From 9c83c18137a711e2ed5a8c54bb3bc9f8bd89c459 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 9 Dec 2014 18:24:53 +0100 Subject: [PATCH] Fixed some query-heavy things in the report controller. --- app/controllers/ReportController.php | 63 +-------- app/lib/FireflyIII/Report/Report.php | 128 ++++++++++++++---- app/lib/FireflyIII/Report/ReportInterface.php | 19 ++- 3 files changed, 120 insertions(+), 90 deletions(-) diff --git a/app/controllers/ReportController.php b/app/controllers/ReportController.php index 1bb335e453..81ff131fdd 100644 --- a/app/controllers/ReportController.php +++ b/app/controllers/ReportController.php @@ -245,74 +245,21 @@ class ReportController extends BaseController } catch (Exception $e) { App::abort(500); } - $date = new Carbon('01-01-' . $year); + $date = new Carbon('01-01-' . $year); + $end = clone $date; + $end->endOfYear(); $title = 'Reports'; $subTitle = $year; $subTitleIcon = 'fa-bar-chart'; $mainTitleIcon = 'fa-line-chart'; $balances = $this->_reports->yearBalanceReport($date); - $groupedIncomes = $this->_reports->groupByRevenue($date, 'income'); - $groupedExpenses = $this->_reports->groupByRevenue($date, 'expense'); - + $groupedIncomes = $this->_reports->revenueGroupedByAccount($date, $end, 15); + $groupedExpenses = $this->_reports->expensesGroupedByAccount($date, $end, 15); return View::make( 'reports.year', compact('date', 'groupedIncomes', 'groupedExpenses', 'year', 'balances', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon') ); - - - /* - * For this year, get: - * - the sum of all expenses. - * - the sum of all incomes - * - per month, the sum of all expenses - * - per month, the sum of all incomes - * - 2x for shared and not-shared alike. - * - * - balance difference for all accounts. - */ - - $accounts = $accountRepository->getAssetAccounts(); - - // get some sums going - $summary = []; - - $end = clone $date; - $end->endOfYear(); - while ($date < $end) { - $month = $date->format('F'); - - $income = 0; - $incomeShared = 0; - $expense = 0; - $expenseShared = 0; - - foreach ($accounts as $account) { - if ($account->accountRole == 'sharedExpense') { - $incomeShared += $reportRepository->getIncomeByMonth($account, $date); - $expenseShared += $reportRepository->getExpenseByMonth($account, $date); - } else { - $income += $reportRepository->getIncomeByMonth($account, $date); - $expense += $reportRepository->getExpenseByMonth($account, $date); - } - } - - $summary[] = [ - 'month' => $month, - 'income' => $income, - 'expense' => $expense, - 'incomeShared' => $incomeShared, - 'expenseShared' => $expenseShared, - ]; - $date->addMonth(); - } - - - // draw some charts etc. - return View::make('reports.year', compact('summary', 'date'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart')->with('subTitle', $year) - ->with( - 'subTitleIcon', 'fa-bar-chart' - )->with('year', $year); } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Report/Report.php b/app/lib/FireflyIII/Report/Report.php index ebbf8ce990..d1e6c2a6e4 100644 --- a/app/lib/FireflyIII/Report/Report.php +++ b/app/lib/FireflyIII/Report/Report.php @@ -4,6 +4,7 @@ namespace FireflyIII\Report; use Carbon\Carbon; use FireflyIII\Database\Account as AccountRepository; +use Illuminate\Support\Collection; /** * Class Report @@ -25,35 +26,45 @@ class Report implements ReportInterface } /** - * @param Carbon $date - * @param string $direction + * @param Carbon $start + * @param Carbon $end + * @param int $limit * - * @return mixed + * @return Collection */ - public function groupByRevenue(Carbon $date, $direction = 'income') + public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15) { - $operator = $direction == 'income' ? '<' : '>'; - $type = $direction == 'income' ? 'Deposit' : 'Withdrawal'; - $order = $direction == 'income' ? 'ASC' : 'DESC'; - $start = clone $date; - $end = clone $date; - $start->startOfYear(); - $end->endOfYear(); - - // TODO remove shared accounts return \TransactionJournal:: - leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') - ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') - ->where('transaction_types.type', '=', $type) - ->where('transactions.amount', $operator, 0) - ->before($end) - ->after($start) - ->groupBy('accounts.id') + leftJoin( + 'transactions as t_from', function ($join) { + $join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0); + } + ) + ->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id') + ->leftJoin( + 'account_meta as acm_from', function ($join) { + $join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole'); + } + ) + ->leftJoin( + 'transactions as t_to', function ($join) { + $join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0); + } + ) + ->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id') + ->leftJoin( + 'account_meta as acm_to', function ($join) { + $join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole'); + } + ) + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->where('transaction_types.type', 'Withdrawal') + ->where('acm_from.data', '!=', '"sharedExpense"') + ->before($end)->after($start) ->where('transaction_journals.user_id', \Auth::user()->id) - ->orderBy('sum', $order) - ->take(10) - ->get(['accounts.name', 'transactions.account_id', \DB::Raw('SUM(`transactions`.`amount`) as `sum`')]); + ->groupBy('account_id')->orderBy('sum', 'DESC')->limit(15) + ->get(['t_to.account_id as account_id', 'ac_to.name as name', \DB::Raw('SUM(t_to.amount) as `sum`')]); + } @@ -95,6 +106,49 @@ class Report implements ReportInterface return $years; } + /** + * @param Carbon $start + * @param Carbon $end + * @param int $limit + * + * @return Collection + */ + public function revenueGroupedByAccount(Carbon $start, Carbon $end, $limit = 15) + { + return \TransactionJournal:: + leftJoin( + 'transactions as t_from', function ($join) { + $join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0); + } + ) + ->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id') + ->leftJoin( + 'account_meta as acm_from', function ($join) { + $join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole'); + } + ) + ->leftJoin( + 'transactions as t_to', function ($join) { + $join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0); + } + ) + ->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id') + ->leftJoin( + 'account_meta as acm_to', function ($join) { + $join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole'); + } + ) + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->where('transaction_types.type', 'Deposit') + ->where('acm_to.data', '!=', '"sharedExpense"') + ->before($end)->after($start) + ->where('transaction_journals.user_id', \Auth::user()->id) + ->groupBy('account_id')->orderBy('sum')->limit(15) + ->get(['t_from.account_id as account_id', 'ac_from.name as name', \DB::Raw('SUM(t_from.amount) as `sum`')]); + + + } + /** * @param Carbon $date * @@ -102,10 +156,28 @@ class Report implements ReportInterface */ public function yearBalanceReport(Carbon $date) { - $start = clone $date; - $end = clone $date; - // TODO filter accounts, no shared accounts. - $accounts = $this->_accounts->getAssetAccounts(); + $start = clone $date; + $end = clone $date; + $sharedAccounts = []; + $sharedCollection = \Auth::user()->accounts() + ->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id') + ->where('account_meta.name', '=', 'accountRole') + ->where('account_meta.data', '=', json_encode('sharedExpense')) + ->get(['accounts.id']); + + foreach ($sharedCollection as $account) { + $sharedAccounts[] = $account->id; + } + + $accounts = $this->_accounts->getAssetAccounts()->filter( + function (\Account $account) use ($sharedAccounts) { + if (!in_array($account->id, $sharedAccounts)) { + return $account; + } + + return null; + } + ); $report = []; $start->startOfYear(); $end->endOfYear(); diff --git a/app/lib/FireflyIII/Report/ReportInterface.php b/app/lib/FireflyIII/Report/ReportInterface.php index 20f201b579..4605beb75d 100644 --- a/app/lib/FireflyIII/Report/ReportInterface.php +++ b/app/lib/FireflyIII/Report/ReportInterface.php @@ -3,6 +3,7 @@ namespace FireflyIII\Report; use Carbon\Carbon; +use Illuminate\Support\Collection; /** * Interface ReportInterface @@ -12,12 +13,22 @@ use Carbon\Carbon; interface ReportInterface { /** - * @param Carbon $date - * @param string $direction + * @param Carbon $start + * @param Carbon $end + * @param int $limit * - * @return mixed + * @return Collection */ - public function groupByRevenue(Carbon $date, $direction = 'income'); + public function revenueGroupedByAccount(Carbon $start, Carbon $end, $limit = 15); + + /** + * @param Carbon $start + * @param Carbon $end + * @param int $limit + * + * @return Collection + */ + public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15); /** * @param Carbon $start