From b94781aef14d40406c093eb5660431a9f8c1c707 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 16 May 2015 08:05:04 +0200 Subject: [PATCH] Some optimisations. --- app/Helpers/Report/ReportQuery.php | 63 +++++++++++++++++++++ app/Helpers/Report/ReportQueryInterface.php | 14 +++++ app/Http/Controllers/ReportController.php | 35 ++++++++++-- resources/twig/reports/year.twig | 13 +++-- 4 files changed, 116 insertions(+), 9 deletions(-) diff --git a/app/Helpers/Report/ReportQuery.php b/app/Helpers/Report/ReportQuery.php index 57ae219053..b1c2d8c2a5 100644 --- a/app/Helpers/Report/ReportQuery.php +++ b/app/Helpers/Report/ReportQuery.php @@ -232,6 +232,69 @@ class ReportQuery implements ReportQueryInterface return $data; } + /** + * This method returns all "expense" journals in a certain period, which are both transfers to a shared account + * and "ordinary" withdrawals. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does + * not group and returns different fields. + * + * @param Carbon $start + * @param Carbon $end + * @param bool $includeShared + * + * @return Collection + * + */ + public function expenseInPeriod(Carbon $start, Carbon $end, $includeShared = false) { + $query = $this->queryJournalsWithTransactions($start, $end); + if ($includeShared === false) { + // only get withdrawals not from a shared account + // and transfers from a shared account. + $query->where( + function (Builder $query) { + $query->where( + function (Builder $q) { + $q->where('transaction_types.type', 'Withdrawal'); + $q->where('acm_from.data', '!=', '"sharedAsset"'); + } + ); + $query->orWhere( + function (Builder $q) { + $q->where('transaction_types.type', 'Transfer'); + $q->where('acm_to.data', '=', '"sharedAsset"'); + } + ); + } + ); + } else { + // any withdrawal is fine. + $query->where('transaction_types.type', 'Withdrawal'); + } + $query->groupBy('transaction_journals.id')->orderBy('transaction_journals.date'); + + // get everything, decrypt and return + $data = $query->get( + ['transaction_journals.id', + 'transaction_journals.description', + 'transaction_journals.encrypted', + 'transaction_types.type', + DB::Raw('SUM(`t_from`.`amount`) as `queryAmount`'), + 'transaction_journals.date', + 't_to.account_id as account_id', + 'ac_to.name as name', + 'ac_to.encrypted as account_encrypted' + ] + ); + + $data->each( + function (Model $object) { + $object->name = intval($object->account_encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name; + } + ); + $data->sortByDesc('queryAmount'); + + return $data; + } + /** * Gets a list of expenses grouped by the budget they were filed under. * diff --git a/app/Helpers/Report/ReportQueryInterface.php b/app/Helpers/Report/ReportQueryInterface.php index a2b4d51c61..c4931af7ed 100644 --- a/app/Helpers/Report/ReportQueryInterface.php +++ b/app/Helpers/Report/ReportQueryInterface.php @@ -86,6 +86,20 @@ interface ReportQueryInterface */ public function incomeInPeriod(Carbon $start, Carbon $end, $includeShared = false); + /** + * This method returns all "expense" journals in a certain period, which are both transfers to a shared account + * and "ordinary" withdrawals. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does + * not group and returns different fields. + * + * @param Carbon $start + * @param Carbon $end + * @param bool $includeShared + * + * @return Collection + * + */ + public function expenseInPeriod(Carbon $start, Carbon $end, $includeShared = false); + /** * Gets a list of expenses grouped by the budget they were filed under. * diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index b3b8cbb409..cecf279abc 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -266,8 +266,8 @@ class ReportController extends Controller $subTitleIcon = 'fa-bar-chart'; $totalExpense = 0; $totalIncome = 0; - $incomeTopLength = 5; - $expenseTopLength = 10; + $incomeTopLength = 8; + $expenseTopLength = 8; if ($shared == 'shared') { $shared = true; @@ -327,10 +327,35 @@ class ReportController extends Controller * GET ALL EXPENSES * Summarized. */ - $expenses = $this->query->journalsByExpenseAccount($date, $end, $shared); - foreach ($expenses as $expense) { - $totalExpense += floatval($expense->queryAmount); + $set = $this->query->expenseInPeriod($date, $end, $shared); + // group, sort and sum: + $expenses = []; + foreach ($set as $entry) { + $id = $entry->account_id; + $totalExpense += floatval($entry->queryAmount); + if (isset($expenses[$id])) { + $expenses[$id]['amount'] += floatval($entry->queryAmount); + $expenses[$id]['count']++; + } else { + $expenses[$id] = [ + 'amount' => floatval($entry->queryAmount), + 'name' => $entry->name, + 'count' => 1, + 'id' => $id, + ]; + } } + // sort with callback: + uasort( + $expenses, function ($a, $b) { + if ($a['amount'] == $b['amount']) { + return 0; + } + + return ($a['amount'] < $b['amount']) ? -1 : 1; + } + ); + unset($set, $id); return view( 'reports.year', diff --git a/resources/twig/reports/year.twig b/resources/twig/reports/year.twig index 26599d7a69..0b71be787c 100644 --- a/resources/twig/reports/year.twig +++ b/resources/twig/reports/year.twig @@ -125,16 +125,21 @@ {% set sum =0 %} - {% for expense in expenses %} + {% for row in expenses %} {% if loop.index > expenseTopLength %} {% else %} {% endif %} - - + + - {% set sum = sum + (expense.queryAmount * -1) %} + {% set sum = sum + row.amount %} {% endfor %} {% if expenses|length > expenseTopLength %}
{{ expense.name }}{{ expense.queryAmount|formatAmountPlain }} + {{ row.name }} + {% if row.count > 1 %} +
{{ row.count }} {{ 'transactions'|_|lower }} + {% endif %} +
{{ (row.amount*-1)|formatAmountPlain }}