Cleaned up reports and associated views.

This commit is contained in:
James Cole
2015-05-15 20:07:51 +02:00
parent b20f369aef
commit d5a154d2e6
15 changed files with 239 additions and 627 deletions

View File

@@ -22,11 +22,11 @@ class ReportHelper implements ReportHelperInterface
* This method gets some kind of list for a monthly overview.
*
* @param Carbon $date
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function getBudgetsForMonth(Carbon $date, $showSharedReports = false)
public function getBudgetsForMonth(Carbon $date, $includeShared = false)
{
/** @var \FireflyIII\Helpers\Report\ReportQueryInterface $query */
$query = App::make('FireflyIII\Helpers\Report\ReportQueryInterface');
@@ -44,7 +44,7 @@ class ReportHelper implements ReportHelperInterface
->get(['budgets.*', 'budget_limits.amount as queryAmount']);
$budgets = Steam::makeArray($set);
$amountSet = $query->journalsByBudget($start, $end, $showSharedReports);
$amountSet = $query->journalsByBudget($start, $end, $includeShared);
$amounts = Steam::makeArray($amountSet);
$budgets = Steam::mergeArrays($budgets, $amounts);
$budgets[0]['spent'] = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0;
@@ -53,7 +53,7 @@ class ReportHelper implements ReportHelperInterface
// find transactions to shared asset accounts, which are without a budget by default:
// which is only relevant when shared asset accounts are hidden.
if ($showSharedReports === false) {
if ($includeShared === false) {
$transfers = $query->sharedExpenses($start, $end)->sum('queryAmount');
$budgets[0]['spent'] += floatval($transfers) * -1;
}
@@ -87,37 +87,16 @@ class ReportHelper implements ReportHelperInterface
/**
* @param Carbon $date
* @param bool $includeShared
*
* @return array
*/
public function listOfYears(Carbon $date)
{
$start = clone $date;
$end = Carbon::now();
$years = [];
while ($start <= $end) {
$years[] = $start->year;
$start->addYear();
}
$years[] = Carbon::now()->year;
// force the current year.
$years = array_unique($years);
return $years;
}
/**
* @param Carbon $date
* @param bool $showSharedReports
*
* @return array
*/
public function yearBalanceReport(Carbon $date, $showSharedReports = false)
public function yearBalanceReport(Carbon $date, $includeShared = false)
{
$start = clone $date;
$end = clone $date;
$sharedAccounts = [];
if ($showSharedReports === false) {
if ($includeShared === false) {
$sharedCollection = Auth::user()->accounts()
->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id')
->where('account_meta.name', '=', 'accountRole')

View File

@@ -17,10 +17,11 @@ interface ReportHelperInterface
* This method gets some kind of list for a monthly overview.
*
* @param Carbon $date
* @param bool $includeShared
*
* @return Collection
*/
public function getBudgetsForMonth(Carbon $date);
public function getBudgetsForMonth(Carbon $date, $includeShared = false);
/**
* @param Carbon $date
@@ -31,16 +32,9 @@ interface ReportHelperInterface
/**
* @param Carbon $date
* @param bool $includeShared
*
* @return array
*/
public function listOfYears(Carbon $date);
/**
* @param Carbon $date
* @param bool $showSharedReports
*
* @return array
*/
public function yearBalanceReport(Carbon $date, $showSharedReports = false);
public function yearBalanceReport(Carbon $date, $includeShared = false);
}

View File

@@ -22,38 +22,6 @@ use Steam;
class ReportQuery implements ReportQueryInterface
{
/**
* This query retrieves a list of accounts that are active and not shared.
*
* @param bool $showSharedReports
*
* @return Collection
*/
public function accountList($showSharedReports = false)
{
$query = Auth::user()->accounts();
if ($showSharedReports === false) {
$query->leftJoin(
'account_meta', function (JoinClause $join) {
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', "accountRole");
}
)->where(
function (Builder $query) {
$query->where('account_meta.data', '!=', '"sharedAsset"');
$query->orWhereNull('account_meta.data');
}
);
}
$query->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', ['Default account', 'Cash account', 'Asset account'])
->where('active', 1)
->orderBy('accounts.name', 'ASC');
return $query->get(['accounts.*']);
}
/**
* This method will get a list of all expenses in a certain time period that have no budget
* and are balanced by a transfer to make up for it.
@@ -123,15 +91,15 @@ class ReportQuery implements ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function getAllAccounts(Carbon $start, Carbon $end, $showSharedReports = false)
public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false)
{
$query = Auth::user()->accounts()->orderBy('accounts.name', 'ASC')
->accountTypeIn(['Default account', 'Asset account', 'Cash account']);
if ($showSharedReports === false) {
if ($includeShared === false) {
$query->leftJoin(
'account_meta', function (JoinClause $join) {
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
@@ -208,14 +176,14 @@ class ReportQuery implements ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function incomeByPeriod(Carbon $start, Carbon $end, $showSharedReports = false)
public function incomeInPeriod(Carbon $start, Carbon $end, $includeShared = false)
{
$query = $this->queryJournalsWithTransactions($start, $end);
if ($showSharedReports === false) {
if ($includeShared === false) {
// only get deposits not to a shared account
// and transfers to a shared account.
$query->where(
@@ -268,11 +236,11 @@ class ReportQuery implements ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function journalsByBudget(Carbon $start, Carbon $end, $showSharedReports = false)
public function journalsByBudget(Carbon $start, Carbon $end, $includeShared = false)
{
$query = Auth::user()->transactionjournals()
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
@@ -283,7 +251,7 @@ class ReportQuery implements ReportQueryInterface
}
)
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id');
if ($showSharedReports === false) {
if ($includeShared === false) {
$query->leftJoin(
'account_meta', function (JoinClause $join) {
@@ -307,11 +275,11 @@ class ReportQuery implements ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function journalsByCategory(Carbon $start, Carbon $end, $showSharedReports = false)
public function journalsByCategory(Carbon $start, Carbon $end, $includeShared = false)
{
$query = Auth::user()->transactionjournals()
->leftJoin(
@@ -324,7 +292,7 @@ class ReportQuery implements ReportQueryInterface
}
)
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id');
if ($showSharedReports === false) {
if ($includeShared === false) {
$query->leftJoin(
'account_meta', function (JoinClause $join) {
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
@@ -358,14 +326,14 @@ class ReportQuery implements ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function journalsByExpenseAccount(Carbon $start, Carbon $end, $showSharedReports = false)
public function journalsByExpenseAccount(Carbon $start, Carbon $end, $includeShared = false)
{
$query = $this->queryJournalsWithTransactions($start, $end);
if ($showSharedReports === false) {
if ($includeShared === false) {
// get all withdrawals not from a shared accounts
// and all transfers to a shared account
$query->where(
@@ -410,14 +378,14 @@ class ReportQuery implements ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function journalsByRevenueAccount(Carbon $start, Carbon $end, $showSharedReports = false)
public function journalsByRevenueAccount(Carbon $start, Carbon $end, $includeShared = false)
{
$query = $this->queryJournalsWithTransactions($start, $end);
if ($showSharedReports === false) {
if ($includeShared === false) {
// show queries where transfer type is deposit, and its not to a shared account
// or where its a transfer and its from a shared account (both count as incomes)

View File

@@ -14,15 +14,6 @@ use Illuminate\Support\Collection;
interface ReportQueryInterface
{
/**
* This query retrieves a list of accounts that are active and not shared.
*
* @param bool $showSharedReports
*
* @return Collection
*/
public function accountList($showSharedReports = false);
/**
* This method will get a list of all expenses in a certain time period that have no budget
* and are balanced by a transfer to make up for it.
@@ -52,11 +43,11 @@ interface ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function getAllAccounts(Carbon $start, Carbon $end, $showSharedReports = false);
public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false);
/**
* Grabs a summary of all expenses grouped by budget, related to the account.
@@ -88,22 +79,23 @@ interface ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*
*/
public function incomeByPeriod(Carbon $start, Carbon $end, $showSharedReports = false);
public function incomeInPeriod(Carbon $start, Carbon $end, $includeShared = false);
/**
* Gets a list of expenses grouped by the budget they were filed under.
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function journalsByBudget(Carbon $start, Carbon $end, $showSharedReports = false);
public function journalsByBudget(Carbon $start, Carbon $end, $includeShared = false);
/**
* Gets a list of categories and the expenses therein, grouped by the relevant category.
@@ -111,11 +103,11 @@ interface ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function journalsByCategory(Carbon $start, Carbon $end, $showSharedReports = false);
public function journalsByCategory(Carbon $start, Carbon $end, $includeShared = false);
/**
* Gets a list of expense accounts and the expenses therein, grouped by that expense account.
@@ -125,22 +117,23 @@ interface ReportQueryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*
*/
public function journalsByExpenseAccount(Carbon $start, Carbon $end, $showSharedReports = false);
public function journalsByExpenseAccount(Carbon $start, Carbon $end, $includeShared = false);
/**
* This method returns all deposits into asset accounts, grouped by the revenue account,
*
* @param Carbon $start
* @param Carbon $end
* @param bool $showSharedReports
* @param bool $includeShared
*
* @return Collection
*/
public function journalsByRevenueAccount(Carbon $start, Carbon $end, $showSharedReports = false);
public function journalsByRevenueAccount(Carbon $start, Carbon $end, $includeShared = false);
/**
* With an equally misleading name, this query returns are transfers to shared accounts. These are considered

View File

@@ -513,8 +513,7 @@ class GoogleChartController extends Controller
$chart->addColumn(trans('firefly.income'), 'number');
$chart->addColumn(trans('firefly.expenses'), 'number');
$pref = Preferences::get('showSharedReports', false);
$showSharedReports = $pref->data;
$includeShared = Preferences::get('includeShared', false)->data;
// get report query interface.
@@ -524,8 +523,8 @@ class GoogleChartController extends Controller
$currentEnd = clone $start;
$currentEnd->endOfMonth();
// total income && total expenses:
$incomeSum = floatval($query->incomeByPeriod($start, $currentEnd, $showSharedReports)->sum('queryAmount'));
$expenseSum = floatval($query->journalsByExpenseAccount($start, $currentEnd, $showSharedReports)->sum('queryAmount'));
$incomeSum = floatval($query->incomeInPeriod($start, $currentEnd, $includeShared)->sum('queryAmount'));
$expenseSum = floatval($query->journalsByExpenseAccount($start, $currentEnd, $includeShared)->sum('queryAmount'));
$chart->addRow(clone $start, $incomeSum, $expenseSum);
$start->addMonth();
@@ -552,8 +551,7 @@ class GoogleChartController extends Controller
$chart->addColumn(trans('firefly.income'), 'number');
$chart->addColumn(trans('firefly.expenses'), 'number');
$pref = Preferences::get('showSharedReports', false);
$showSharedReports = $pref->data;
$includeShared = Preferences::get('includeShared', false)->data;
$income = 0;
$expense = 0;
@@ -565,9 +563,9 @@ class GoogleChartController extends Controller
$currentEnd = clone $start;
$currentEnd->endOfMonth();
// total income:
$incomeSum = floatval($query->incomeByPeriod($start, $currentEnd, $showSharedReports)->sum('queryAmount'));
$incomeSum = floatval($query->incomeInPeriod($start, $currentEnd, $includeShared)->sum('queryAmount'));
// total expenses:
$expenseSum = floatval($query->journalsByExpenseAccount($start, $currentEnd, $showSharedReports)->sum('queryAmount'));
$expenseSum = floatval($query->journalsByExpenseAccount($start, $currentEnd, $includeShared)->sum('queryAmount'));
$income += $incomeSum;
$expense += $expenseSum;

View File

@@ -128,7 +128,7 @@ class JsonController extends Controller
{
$start = Session::get('start', Carbon::now()->startOfMonth());
$end = Session::get('end', Carbon::now()->endOfMonth());
$amount = $reportQuery->incomeByPeriod($start, $end, true)->sum('queryAmount');
$amount = $reportQuery->incomeInPeriod($start, $end, true)->sum('queryAmount');
return Response::json(['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]);
}
@@ -208,9 +208,9 @@ class JsonController extends Controller
public function setSharedReports()
{
/** @var Preference $pref */
$pref = Preferences::get('showSharedReports', false);
$pref = Preferences::get('includeShared', false);
$new = !$pref->data;
Preferences::set('showSharedReports', $new);
Preferences::set('includeShared', $new);
return Response::json(['value' => $new]);
@@ -221,7 +221,7 @@ class JsonController extends Controller
*/
public function showSharedReports()
{
$pref = Preferences::get('showSharedReports', false);
$pref = Preferences::get('includeShared', false);
return Response::json(['value' => $pref->data]);
}

View File

@@ -38,74 +38,6 @@ class ReportController extends Controller
}
/**
* @param string $year
* @param string $month
*
* @return \Illuminate\View\View
*/
public function budget($year = '2014', $month = '1')
{
$date = new Carbon($year . '-' . $month . '-01');
$subTitle = 'Budget report for ' . $date->format('F Y');
$subTitleIcon = 'fa-calendar';
$start = clone $date;
$start->startOfMonth();
$end = clone $date;
$end->endOfMonth();
// should show shared reports?
/** @var Preference $pref */
$pref = Preferences::get('showSharedReports', false);
$showSharedReports = $pref->data;
$accountAmounts = []; // array with sums of spent amounts on each account.
$accounts = $this->query->getAllAccounts($start, $end, $showSharedReports); // all accounts and some data.
foreach ($accounts as $account) {
$budgets = $this->query->getBudgetSummary($account, $start, $end);// get budget summary for this account:
$balancedAmount = $this->query->balancedTransactionsSum($account, $start, $end);
$accountAmounts[$account->id] = $balancedAmount;
// balance out the transactions (see transaction groups & tags) ^^
// array with budget information for each account:
$array = [];
// should always hide account
$hide = true;
// loop all budgets
/** @var \FireflyIII\Models\Budget $budget */
foreach ($budgets as $budget) {
$id = intval($budget->id);
$data = $budget->toArray();
$array[$id] = $data;
// no longer hide account if any budget has money in it.
if (floatval($data['queryAmount']) != 0) {
$hide = false;
}
$accountAmounts[$account->id] += $data['queryAmount'];
}
$account->hide = $hide;
$account->budgetInformation = $array;
$account->balancedAmount = $balancedAmount;
}
/**
* Start getBudgetsForMonth DONE
*/
$budgets = $this->helper->getBudgetsForMonth($date, $showSharedReports);
/**
* End getBudgetsForMonth DONE
*/
return view('reports.budget', compact('subTitle', 'accountAmounts', 'year', 'month', 'subTitleIcon', 'date', 'accounts', 'budgets'));
}
/**
* @return View
* @internal param ReportHelperInterface $helper
@@ -115,11 +47,10 @@ class ReportController extends Controller
{
$start = Session::get('first');
$months = $this->helper->listOfMonths($start);
$years = $this->helper->listOfYears($start);
$title = 'Reports';
$mainTitleIcon = 'fa-line-chart';
return view('reports.index', compact('years', 'months', 'title', 'mainTitleIcon'));
return view('reports.index', compact('months', 'title', 'mainTitleIcon'));
}
/**
@@ -203,44 +134,63 @@ class ReportController extends Controller
$subTitle = 'Report for ' . $date->format('F Y');
$subTitleIcon = 'fa-calendar';
$displaySum = true; // to show sums in report.
/** @var Preference $pref */
$pref = Preferences::get('showSharedReports', false);
$showSharedReports = $pref->data;
/**
*
* get income for month (date)
*
*/
$start = clone $date;
$start->startOfMonth();
$end = clone $date;
$start = clone $date;
$includeShared = Preferences::get('includeShared', false)->data;
// set start and end.
$start->startOfMonth();
$end->endOfMonth();
/**
* Start getIncomeForMonth DONE
*/
$income = $this->query->incomeByPeriod($start, $end, $showSharedReports);
/**
* End getIncomeForMonth DONE
*/
/**
* Start getExpenseGroupedForMonth DONE
*/
$set = $this->query->journalsByExpenseAccount($start, $end, $showSharedReports);
// get all income and expenses. it's OK.
$income = $this->query->incomeInPeriod($start, $end, $includeShared);
$expensesSet = $this->query->journalsByExpenseAccount($start, $end, $includeShared);
$expenses = Steam::makeArray($set);
$expenses = Steam::sortArray($expenses);
$expenses = Steam::limitArray($expenses, 10);
/**
* End getExpenseGroupedForMonth DONE
* INCLUDE ORIGINAL BUDGET REPORT HERE:
*/
// should show shared reports?
/** @var Preference $pref */
$accountAmounts = []; // array with sums of spent amounts on each account.
$accounts = $this->query->getAllAccounts($start, $end, $includeShared); // all accounts and some data.
foreach ($accounts as $account) {
$budgets = $this->query->getBudgetSummary($account, $start, $end);// get budget summary for this account:
$balancedAmount = $this->query->balancedTransactionsSum($account, $start, $end);
$accountAmounts[$account->id] = $balancedAmount;
// balance out the transactions (see transaction groups & tags) ^^
// array with budget information for each account:
$array = [];
// should always hide account
$hide = true;
// loop all budgets
/** @var \FireflyIII\Models\Budget $budget */
foreach ($budgets as $budget) {
$id = intval($budget->id);
$data = $budget->toArray();
$array[$id] = $data;
// no longer hide account if any budget has money in it.
if (floatval($data['queryAmount']) != 0) {
$hide = false;
}
$accountAmounts[$account->id] += $data['queryAmount'];
}
$account->hide = $hide;
$account->budgetInformation = $array;
$account->balancedAmount = $balancedAmount;
}
/**
* END ORIGINAL BUDGET REPORT
*/
/**
* Start getBudgetsForMonth DONE
*/
$budgets = $this->helper->getBudgetsForMonth($date, $showSharedReports);
$budgets = $this->helper->getBudgetsForMonth($date, $includeShared);
/**
* End getBudgetsForMonth DONE
@@ -254,7 +204,7 @@ class ReportController extends Controller
// all transfers
if ($showSharedReports === false) {
if ($includeShared === false) {
$result = $this->query->sharedExpensesByCategory($start, $end);
$transfers = Steam::makeArray($result);
$merged = Steam::mergeArrays($categories, $transfers);
@@ -268,31 +218,16 @@ class ReportController extends Controller
// limit to $limit:
$categories = Steam::limitArray($sorted, 10);
/**
* End getCategoriesForMonth DONE
*/
/**
* Start getAccountsForMonth
*/
$list = $this->query->accountList($showSharedReports);
$accounts = [];
/** @var Account $account */
foreach ($list as $account) {
$id = intval($account->id);
/** @noinspection PhpParamsInspection */
$accounts[$id] = [
'name' => $account->name,
'startBalance' => Steam::balance($account, $start),
'endBalance' => Steam::balance($account, $end)
];
$accounts[$id]['difference'] = $accounts[$id]['endBalance'] - $accounts[$id]['startBalance'];
}
/**
* End getAccountsForMonth
*/
// clean up and sort expenses:
$expenses = Steam::makeArray($expensesSet);
$expenses = Steam::sortArray($expenses);
$expenses = Steam::limitArray($expenses, 10);
return view(
'reports.month',
@@ -311,8 +246,7 @@ class ReportController extends Controller
public function year($year)
{
/** @var Preference $pref */
$pref = Preferences::get('showSharedReports', false);
$showSharedReports = $pref->data;
$includeShared = Preferences::get('includeShared', false)->data;
$date = new Carbon('01-01-' . $year);
$end = clone $date;
$end->endOfYear();
@@ -320,9 +254,9 @@ class ReportController extends Controller
$subTitle = $year;
$subTitleIcon = 'fa-bar-chart';
$mainTitleIcon = 'fa-line-chart';
$balances = $this->helper->yearBalanceReport($date, $showSharedReports);
$groupedIncomes = $this->query->journalsByRevenueAccount($date, $end, $showSharedReports);
$groupedExpenses = $this->query->journalsByExpenseAccount($date, $end, $showSharedReports);
$balances = $this->helper->yearBalanceReport($date, $includeShared);
$groupedIncomes = $this->query->journalsByRevenueAccount($date, $end, $includeShared);
$groupedExpenses = $this->query->journalsByExpenseAccount($date, $end, $includeShared);
return view(
'reports.year', compact('date', 'groupedIncomes', 'groupedExpenses', 'year', 'balances', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon')

View File

@@ -357,7 +357,6 @@ Route::group(
Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']);
Route::get('/reports/{year}', ['uses' => 'ReportController@year', 'as' => 'reports.year']);
Route::get('/reports/{year}/{month}', ['uses' => 'ReportController@month', 'as' => 'reports.month']);
Route::get('/reports/budget/{year}/{month}', ['uses' => 'ReportController@budget', 'as' => 'reports.budget']);
// pop ups for budget report:
Route::get('/reports/modal/{account}/{year}/{month}/no-budget', ['uses' => 'ReportController@modalNoBudget', 'as' => 'reports.no-budget']);

2
pu.sh
View File

@@ -11,7 +11,7 @@ fi
if [ ! -z "$1" ]
then
phpunit --verbose tests/repositories/$1.php
phpunit --verbose tests/helpers/$1.php
fi
# restore .env file

View File

@@ -1,159 +0,0 @@
{% extends "./layout/default.twig" %}
{% block content %}
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, date) }}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<p>
<a href="#" class="btn btn-default" id="includeShared" style="display:none;">
<i class="state-icon glyphicon glyphicon-unchecked"></i>
Include shared asset accounts</a>
</p>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-fw fa-credit-card"></i>
Accounts
</div>
<table class="table table-bordered table-striped">
<tr>
<th>Account</th>
<th>Start of month</th>
<th>Current balance</th>
<th>Spent</th>
<th>Earned</th>
</tr>
{% for account in accounts %}
<tr>
<td><a href="{{route('accounts.show',account.id)}}">{{ account.name }}</a></td>
<td>{{ account.startBalance|formatAmount }}</td>
<td>{{ account.endBalance|formatAmount }}</td>
<td>
{% if account.startBalance - account.endBalance > 0 %}
<span class="text-danger">{{ (account.startBalance - account.endBalance)|formatAmountPlain }}</span>
{% endif %}
</td>
<td>
{% if account.startBalance - account.endBalance < 0 %}
<span class="text-success">{{ ((account.startBalance - account.endBalance)*-1)|formatAmountPlain }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-tasks fa-fw"></i>
Budgets
</div>
<table class="table table-bordered table-striped">
<tr>
<th colspan="2">Budgets</th>
{% for account in accounts %}
{% if not account.hide %}
<th><a href="{{route('accounts.show',account.id)}}">{{ account.name }}</a></th>
{% endif %}
{% endfor %}
<th colspan="2">
Left in budget
</th>
</tr>
{% for id,budget in budgets %}
<tr>
<td>{{ budget.name }}</td>
<td>{{ budget.queryAmount|formatAmount }}</td>
{% set spent = 0 %}
{% for account in accounts %}
{% if not account.hide %}
{% if account.budgetInformation[id] %}
<td>
{% if id == 0 %}
<a href="{{route('reports.no-budget',[account, year, month])}}" class="openModal">
{{ account.budgetInformation[id].queryAmount|formatAmount }}
</a>
{% else %}
{{ account.budgetInformation[id].queryAmount|formatAmount }}
{% endif %}
</td>
{% set spent = spent + account.budgetInformation[id].queryAmount %}
{% else %}
<td>{{ 0|formatAmount }}</td>
{% endif %}
{% endif %}
{% endfor %}
<td>{{ (budget.queryAmount + budget.spent)|formatAmount }}</td>
<td>{{ (budget.queryAmount + spent)|formatAmount }}</td>
</tr>
{% endfor %}
<tr>
<td colspan="2">Balanced by transfers</td>
{% for account in accounts %}
{% if not account.hide %}
<td>
<a href="{{route('reports.balanced-transfers',[account, year, month])}}" class="openModal">{{ account.balancedAmount|formatAmount }}</a>
</td>
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2">Left unbalanced</td>
{% for account in accounts %}
{% if not account.hide %}
{% if account.budgetInformation[0] %}
<td>
{% if account.budgetInformation[0].queryAmount + account.balancedAmount != 0.0 %}
<a href="{{route('reports.left-unbalanced',[account, year, month])}}" class="openModal">{{ (account.budgetInformation[0].queryAmount + account.balancedAmount)|formatAmount }}</a>
{% else %}
{{ (account.budgetInformation[0].queryAmount + account.balancedAmount)|formatAmount }}
{% endif %}
</td>
{% else %}
<td>{{ 0|formatAmount }}</td>
{% endif %}
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2"><em>Sum</em></td>
{% for account in accounts %}
{% if not account.hide %}
<td>{{ accountAmounts[account.id]|formatAmount }}</td>
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2">Expected balance</td>
{% for account in accounts %}
{% if not account.hide %}
<td>{{ (account.startBalance + accountAmounts[account.id])|formatAmount }}</td>
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
</table>
</div>
</div>
</div>
<!-- modal to show various budget information -->
<div class="modal fade" id="budgetModal">
</div>
{% endblock %}
{% block scripts %}
<script type="text/javascript" src="js/reports.js"></script>
{% endblock %}

View File

@@ -11,58 +11,22 @@
</div>
</div>
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-calendar fa-fw"></i>
Yearly reports
</div>
<div class="panel-body">
<ul>
{% for year in years %}
<li><a href="{{route('reports.year',year)}}">{{ year }}</a></li>
{% endfor %}
</ul>
</div>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-calendar fa-fw"></i>
Monthly reports
Reports
</div>
<div class="panel-body">
{% for year, entries in months %}
<h5>{{ year }}</h5>
<ul>
<h4><a href="{{route('reports.year',year)}}">{{ year }}</a></h4>
<ul class="list-inline">
{% for month in entries %}
<li><a href="{{route('reports.month',[month.year, month.month])}}">{{ month.formatted}}</a></li>
{% endfor %}
</ul>
{% endfor %}
</div>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-calendar fa-fw"></i>
Budget reports
</div>
<div class="panel-body">
{% for year, entries in months %}
<h5>{{ year }}</h5>
<ul>
{% for month in entries %}
<li><a href="{{route('reports.budget',[month.year,month.month])}}">{{ month.formatted}}</a></li>
{% endfor %}
</ul>
{% endfor %}
</div>
</div>
</div>

View File

@@ -189,31 +189,35 @@
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-credit-card fa-fw"></i>
<i class="fa fa-fw fa-credit-card"></i>
Accounts
</div>
<table class="table table-bordered">
{% set sumStart = 0 %}
{% set sumEnd = 0 %}
{% set sumDiff = 0 %}
{% for id,account in accounts %}
{% set sumStart = sumStart + account.startBalance %}
{% set sumEnd = sumEnd + account.endBalance %}
{% set sumDiff = sumDiff + account.difference %}
<table class="table table-bordered table-striped">
<tr>
<td><a href="{{route('accounts.show',id)}}">{{ account.name }}</a></td>
<th>Account</th>
<th>Start of month</th>
<th>Current balance</th>
<th>Spent</th>
<th>Earned</th>
</tr>
{% for account in accounts %}
<tr>
<td><a href="{{route('accounts.show',account.id)}}">{{ account.name }}</a></td>
<td>{{ account.startBalance|formatAmount }}</td>
<td>{{ account.endBalance|formatAmount }}</td>
<td>{{ account.difference|formatAmount }}</td>
<td>
{% if account.startBalance - account.endBalance > 0 %}
<span class="text-danger">{{ (account.startBalance - account.endBalance)|formatAmountPlain }}</span>
{% endif %}
</td>
<td>
{% if account.startBalance - account.endBalance < 0 %}
<span class="text-success">{{ ((account.startBalance - account.endBalance)*-1)|formatAmountPlain }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
<tr>
<td><em>Sum</em></td>
<td>{{ sumStart|formatAmount }}</td>
<td>{{ sumEnd|formatAmount }}</td>
<td>{{ sumDiff|formatAmount }}</td>
</tr>
</table>
</div>
</div>
@@ -223,9 +227,98 @@
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-sort-amount-asc fa-fw"></i>
Piggy banks
Budgets
</div>
<div class="panel-body">Body</div>
<table class="table table-bordered table-striped">
<tr>
<th colspan="2">Budgets</th>
{% for account in accounts %}
{% if not account.hide %}
<th><a href="{{route('accounts.show',account.id)}}">{{ account.name }}</a></th>
{% endif %}
{% endfor %}
<th colspan="2">
Left in budget
</th>
</tr>
{% for id,budget in budgets %}
<tr>
<td>{{ budget.name }}</td>
<td>{{ budget.queryAmount|formatAmount }}</td>
{% set spent = 0 %}
{% for account in accounts %}
{% if not account.hide %}
{% if account.budgetInformation[id] %}
<td>
{% if id == 0 %}
<a href="{{route('reports.no-budget',[account, year, month])}}" class="openModal">
{{ account.budgetInformation[id].queryAmount|formatAmount }}
</a>
{% else %}
{{ account.budgetInformation[id].queryAmount|formatAmount }}
{% endif %}
</td>
{% set spent = spent + account.budgetInformation[id].queryAmount %}
{% else %}
<td>{{ 0|formatAmount }}</td>
{% endif %}
{% endif %}
{% endfor %}
<td>{{ (budget.queryAmount + budget.spent)|formatAmount }}</td>
<td>{{ (budget.queryAmount + spent)|formatAmount }}</td>
</tr>
{% endfor %}
<tr>
<td colspan="2">Balanced by transfers</td>
{% for account in accounts %}
{% if not account.hide %}
<td>
<a href="{{route('reports.balanced-transfers',[account, year, month])}}" class="openModal">{{ account.balancedAmount|formatAmount }}</a>
</td>
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2">Left unbalanced</td>
{% for account in accounts %}
{% if not account.hide %}
{% if account.budgetInformation[0] %}
<td>
{% if account.budgetInformation[0].queryAmount + account.balancedAmount != 0.0 %}
<a href="{{route('reports.left-unbalanced',[account, year, month])}}" class="openModal">{{ (account.budgetInformation[0].queryAmount + account.balancedAmount)|formatAmount }}</a>
{% else %}
{{ (account.budgetInformation[0].queryAmount + account.balancedAmount)|formatAmount }}
{% endif %}
</td>
{% else %}
<td>{{ 0|formatAmount }}</td>
{% endif %}
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2"><em>Sum</em></td>
{% for account in accounts %}
{% if not account.hide %}
<td>{{ accountAmounts[account.id]|formatAmount }}</td>
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2">Expected balance</td>
{% for account in accounts %}
{% if not account.hide %}
<td>{{ (account.startBalance + accountAmounts[account.id])|formatAmount }}</td>
{% endif %}
{% endfor %}
<td colspan="2">&nbsp;</td>
</tr>
</table>
</div>
</div>
</div>

View File

@@ -36,47 +36,6 @@ class ReportControllerTest extends TestCase
parent::tearDown();
}
public function testBudget()
{
$user = FactoryMuffin::create('FireflyIII\User');
$showSharedReports = FactoryMuffin::create('FireflyIII\Models\Preference');
$currency = FactoryMuffin::create('FireflyIII\Models\TransactionCurrency');
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$budget->queryAmount = 100;
$accounts = new Collection([$account]);
$budgets = new Collection([$budget]);
$showSharedReports->data = false;
$this->be($user);
$showSharedReports->save();
// mock stuff
$query = $this->mock('FireflyIII\Helpers\Report\ReportQueryInterface');
$helper = $this->mock('FireflyIII\Helpers\Report\ReportHelperInterface');
// fake it!
Preferences::shouldReceive('get')->withArgs(['showSharedReports', false])->andReturn($showSharedReports);
Amount::shouldReceive('getDefaultCurrency')->once()->andReturn($currency);
Amount::shouldReceive('getAllCurrencies')->once()->andReturn([$currency]);
Amount::shouldReceive('getCurrencyCode')->andReturn('X');
Amount::shouldReceive('format')->andReturn('X');
$query->shouldReceive('getAllAccounts')->withAnyArgs()->andReturn($accounts);
$query->shouldReceive('getBudgetSummary')->withAnyArgs()->andReturn($budgets);
$query->shouldReceive('balancedTransactionsSum')->withAnyArgs()->andReturn(100);
$helper->shouldReceive('getBudgetsForMonth')->withAnyArgs()->andReturn($budgets);
// language preference:
$language = FactoryMuffin::create('FireflyIII\Models\Preference');
$language->data = 'en';
$language->save();
Preferences::shouldReceive('get')->withAnyArgs()->andReturn($language);
$this->call('GET', '/reports/budget/2015/1');
$this->assertResponseOk();
}
public function testIndex()
{
$user = FactoryMuffin::create('FireflyIII\User');
@@ -143,82 +102,6 @@ class ReportControllerTest extends TestCase
}
public function testMonth()
{
$user = FactoryMuffin::create('FireflyIII\User');
$currency = FactoryMuffin::create('FireflyIII\Models\TransactionCurrency');
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$journals = new Collection([$journal]);
$budgets = new Collection([$budget]);
$accounts = new Collection([$account]);
$this->be($user);
$helper = $this->mock('FireflyIII\Helpers\Report\ReportHelperInterface');
$query = $this->mock('FireflyIII\Helpers\Report\ReportQueryInterface');
$query->shouldReceive('incomeByPeriod')->withAnyArgs()->andReturn([]);
$query->shouldReceive('journalsByExpenseAccount')->withAnyArgs()->andReturn($journals);
$helper->shouldReceive('getBudgetsForMonth')->withAnyArgs()->andReturn($budgets);
$query->shouldReceive('journalsByCategory')->withAnyArgs()->andReturn($journals);
$query->shouldReceive('sharedExpensesByCategory')->withAnyArgs()->andReturn($journals);
$query->shouldReceive('accountList')->withAnyArgs()->andReturn($accounts);
// mock stuff!
Amount::shouldReceive('getDefaultCurrency')->once()->andReturn($currency);
Amount::shouldReceive('getAllCurrencies')->once()->andReturn([$currency]);
Amount::shouldReceive('getCurrencyCode')->andReturn('X');
Amount::shouldReceive('getCurrencySymbol')->andReturn('X');
Amount::shouldReceive('format')->andReturn('X');
$this->call('GET', '/reports/2015/1');
$this->assertResponseOk();
}
public function testMonthWithShared()
{
$user = FactoryMuffin::create('FireflyIII\User');
$currency = FactoryMuffin::create('FireflyIII\Models\TransactionCurrency');
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$showSharedReports = FactoryMuffin::create('FireflyIII\Models\Preference');
$showSharedReports->data = true;
$journals = new Collection([$journal]);
$budgets = new Collection([$budget]);
$accounts = new Collection([$account]);
$this->be($user);
$helper = $this->mock('FireflyIII\Helpers\Report\ReportHelperInterface');
$query = $this->mock('FireflyIII\Helpers\Report\ReportQueryInterface');
$query->shouldReceive('incomeByPeriod')->withAnyArgs()->andReturn([]);
$query->shouldReceive('journalsByExpenseAccount')->withAnyArgs()->andReturn($journals);
$helper->shouldReceive('getBudgetsForMonth')->withAnyArgs()->andReturn($budgets);
$query->shouldReceive('journalsByCategory')->withAnyArgs()->andReturn($journals);
$query->shouldReceive('sharedExpensesByCategory')->withAnyArgs()->andReturn($journals);
$query->shouldReceive('accountList')->withAnyArgs()->andReturn($accounts);
// mock stuff!
Preferences::shouldReceive('get')->withArgs(['showSharedReports', false])->andReturn($showSharedReports);
Amount::shouldReceive('getDefaultCurrency')->once()->andReturn($currency);
Amount::shouldReceive('getAllCurrencies')->once()->andReturn([$currency]);
Amount::shouldReceive('getCurrencyCode')->andReturn('X');
Amount::shouldReceive('getCurrencySymbol')->andReturn('X');
Amount::shouldReceive('format')->andReturn('X');
// language preference:
$language = FactoryMuffin::create('FireflyIII\Models\Preference');
$language->data = 'en';
$language->save();
Preferences::shouldReceive('get')->withAnyArgs()->andReturn($language);
$this->call('GET', '/reports/2015/1');
$this->assertResponseOk();
}
public function testYear()
{
$user = FactoryMuffin::create('FireflyIII\User');

View File

@@ -118,15 +118,6 @@ class ReportHelperTest extends TestCase
}
public function testListOfYears()
{
$date = new Carbon('2015-01-01');
$now = new Carbon;
$diff = $now->diffInYears($date) + 1; // the year itself.
$result = $this->object->listOfYears($date);
$this->assertCount($diff, $result);
}
public function testYearBalanceReport()
{

View File

@@ -36,31 +36,6 @@ class ReportQueryTest extends TestCase
parent::tearDown();
}
public function testAccountList()
{
$user = FactoryMuffin::create('FireflyIII\User');
$this->be($user);
// account types:
FactoryMuffin::create('FireflyIII\Models\AccountType');
FactoryMuffin::create('FireflyIII\Models\AccountType');
$type = FactoryMuffin::create('FireflyIII\Models\AccountType');
// create four accounts:
for ($i = 0; $i < 4; $i++) {
$account = FactoryMuffin::create('FireflyIII\Models\Account');
$account->user_id = $user->id;
$account->active = 1;
$account->account_type_id = $type->id;
$account->save();
}
$set = $this->object->accountList();
$this->assertCount(4, $set);
}
public function testBalancedTransactionsList()
{
$this->markTestIncomplete();