From 83de3482ce3d000e30e805a79d1750512b9e6822 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 28 Dec 2015 17:57:03 +0100 Subject: [PATCH] Optimised budget year chart. --- .../Controllers/Chart/BudgetController.php | 33 ++++++------ app/Repositories/Budget/BudgetRepository.php | 53 +++++++++++++++++++ .../Budget/BudgetRepositoryInterface.php | 11 ++++ 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index 8d854c474b..b276cdf313 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -283,9 +283,6 @@ class BudgetController extends Controller */ public function year(BudgetRepositoryInterface $repository, $report_type, Carbon $start, Carbon $end, Collection $accounts) { - $allBudgets = $repository->getBudgets(); - $budgets = new Collection; - // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); @@ -298,26 +295,30 @@ class BudgetController extends Controller return Response::json($cache->get()); // @codeCoverageIgnore } - // filter empty budgets: - foreach ($allBudgets as $budget) { - $spent = $repository->balanceInPeriod($budget, $start, $end, $accounts); - if ($spent != 0) { - $budgets->push($budget); - } - } + $budgetInformation = $repository->getBudgetsAndExpenses($start, $end); + $budgets = new Collection; + $entries = new Collection; - $entries = new Collection; + /** @var array $row */ + foreach ($budgetInformation as $row) { + $budgets->push($row['budget']); + } while ($start < $end) { // month is the current end of the period: $month = clone $start; $month->endOfMonth(); - $row = [clone $start]; + $row = [clone $start]; + $dateFormatted = $start->format('Y-m'); - // each budget, fill the row: - foreach ($budgets as $budget) { - $spent = $repository->balanceInPeriod($budget, $start, $month, $accounts); - $row[] = $spent * -1; + // each budget, check if there is an entry for this month: + /** @var array $row */ + foreach ($budgetInformation as $budgetRow) { + $spent = 0; // nothing spent. + if (isset($budgetRow['entries'][$dateFormatted])) { + $spent = $budgetRow['entries'][$dateFormatted] * -1; // to fit array + } + $row[] = $spent; } $entries->push($row); $start->endOfMonth()->addDay(); diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index a38cd42261..56113c1d76 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -210,6 +210,59 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn return Carbon::now()->startOfYear(); } + /** + * Returns an array with every budget in it and the expenses for each budget + * per month. + * + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function getBudgetsAndExpenses(Carbon $start, Carbon $end) + { + /** @var Collection $set */ + $set = Auth::user()->budgets() + ->leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id') + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id') + ->leftJoin( + 'transactions', function (JoinClause $join) { + $join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0); + } + ) + ->groupBy('budgets.id') + ->groupBy('dateFormatted') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) + ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) + ->get( + [ + 'budgets.*', + DB::Raw('DATE_FORMAT(`transaction_journals`.`date`, "%Y-%m") AS `dateFormatted`'), + DB::Raw('SUM(`transactions`.`amount`) AS `sumAmount`') + ] + ); + + $set = $set->sortBy( + function (Budget $budget) { + return strtolower($budget->name); + } + ); + + $return = []; + foreach ($set as $budget) { + $id = $budget->id; + if (!isset($return[$id])) { + $return[$id] = [ + 'budget' => $budget, + 'entries' => [], + ]; + } + // store each entry: + $return[$id]['entries'][$budget->dateFormatted] = $budget->sumAmount; + } + return $return; + } + /** * @return Collection */ diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index 9ac42a85be..4e75e37bc6 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -27,6 +27,17 @@ interface BudgetRepositoryInterface */ public function destroy(Budget $budget); + /** + * Returns an array with every budget in it and the expenses for each budget + * per month. + * + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function getBudgetsAndExpenses(Carbon $start, Carbon $end); + /** * Takes tags into account. *