diff --git a/app/controllers/ReportController.php b/app/controllers/ReportController.php index 86885e978a..35a5588929 100644 --- a/app/controllers/ReportController.php +++ b/app/controllers/ReportController.php @@ -1,6 +1,5 @@ _accounts = $accounts; $this->_journals = $journals; $this->_repository = $repository; + /** @var \FireflyIII\Database\Budget\Budget _budgets */ + $this->_budgets = App::make('FireflyIII\Database\Budget\Budget'); + View::share('title', 'Reports'); View::share('mainTitleIcon', 'fa-line-chart'); } + /** + * @param string $year + * @param string $month + * + * @return \Illuminate\View\View + */ + public function budget($year = '2014', $month = '1') + { + try { + new Carbon($year . '-' . $month . '-01'); + } catch (Exception $e) { + View::make('error')->with('message', 'Invalid date'); + } + $date = new Carbon($year . '-' . $month . '-01'); + $dayEarly = clone $date; + $dayEarly = $dayEarly->subDay(); + $accounts = $this->_repository->getAccountListBudgetOverview($date); + $budgets = $this->_repository->getBudgetsForMonth($date); + + return View::make('reports.budget', compact('accounts', 'budgets', 'dayEarly')); + + } + /** * */ @@ -62,7 +83,7 @@ class ReportController extends BaseController } catch (Exception $e) { View::make('error')->with('message', 'Invalid date'); } - $date = new Carbon($year . '-' . $month . '-01'); + $date = new Carbon($year . '-' . $month . '-01'); $subTitle = 'Report for ' . $date->format('F Y'); $subTitleIcon = 'fa-calendar'; $displaySum = true; // to show sums in report. @@ -79,61 +100,6 @@ class ReportController extends BaseController ); } - /** - * @param $year - * @param $month - * - * @return \Illuminate\View\View - */ - public function unbalanced($year, $month) - { - try { - new Carbon($year . '-' . $month . '-01'); - } catch (Exception $e) { - App::abort(500); - } - $start = new Carbon($year . '-' . $month . '-01'); - $end = clone $start; - $title = 'Reports'; - $subTitle = 'Unbalanced transactions in ' . $start->format('F Y'); - $mainTitleIcon = 'fa-line-chart'; - $subTitleIcon = 'fa-bar-chart'; - $end->endOfMonth(); - - /** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $journalRepository */ - $journalRepository = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal'); - $journals = $journalRepository->getInDateRange($start, $end); - - $withdrawals = $journals->filter( - function (TransactionJournal $journal) { - $relations = $journal->transactiongroups()->where('relation', 'balance')->count(); - $budgets = $journal->budgets()->count(); - $type = $journal->transactionType->type; - if ($type == 'Withdrawal' && $budgets == 0 && $relations == 0) { - return $journal; - } - - return null; - } - ); - $deposits = $journals->filter( - function (TransactionJournal $journal) { - $relations = $journal->transactiongroups()->where('relation', 'balance')->count(); - $budgets = $journal->budgets()->count(); - $type = $journal->transactionType->type; - if ($type == 'Deposit' && $budgets == 0 && $relations == 0) { - return $journal; - } - - return null; - } - ); - - $journals = $withdrawals->merge($deposits); - - return View::make('reports.unbalanced', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'journals')); - } - /** * @param $year * diff --git a/app/lib/FireflyIII/Report/Report.php b/app/lib/FireflyIII/Report/Report.php index 4dc0986102..f7ef12dfea 100644 --- a/app/lib/FireflyIII/Report/Report.php +++ b/app/lib/FireflyIII/Report/Report.php @@ -9,7 +9,6 @@ use FireflyIII\Database\TransactionJournal\TransactionJournal as JournalReposito use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; -use stdClass; // todo add methods to interface @@ -47,8 +46,6 @@ class Report implements ReportInterface } /** - * TODO Used in yearly report, so not ready for cleanup. - * * @param Carbon $start * @param Carbon $end * @param int $limit @@ -57,37 +54,49 @@ class Report implements ReportInterface */ public function expensesGroupedByAccount(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', 'Withdrawal') - ->where('acm_from.data', '!=', '"sharedExpense"') - ->before($end)->after($start) - ->where('transaction_journals.user_id', \Auth::user()->id) - ->groupBy('account_id')->orderBy('sum', 'DESC')->limit($limit) - ->get(['t_to.account_id as account_id', 'ac_to.name as name', \DB::Raw('SUM(t_to.amount) as `sum`')]); + $result = $this->_queries->journalsByExpenseAccount($start, $end); + $array = $this->_helper->makeArray($result); + $limited = $this->_helper->limitArray($array, $limit); + return $limited; + + } + + /** + * Gets all the users shared and non-shared accounts combined with various meta-data + * to display the amount of money spent that month compared to what's been spend within + * budgets. + * + * @param Carbon $date + * + * @return Collection + */ + public function getAccountListBudgetOverview(Carbon $date) + { + $start = clone $date; + $start->startOfMonth(); + $end = clone $date; + $end->endOfMonth(); + $start->subDay(); + $accounts = $this->_queries->getAllAccounts($start, $end); + + $accounts->each( + function (\Account $account) use ($start, $end) { + $budgets = $this->_queries->getBudgetSummary($account, $start, $end); + $balancedAmount = $this->_queries->balancedTransactionsSum($account, $start, $end); + $array = []; + foreach ($budgets as $budget) { + $id = intval($budget->id); + $data = $budget->toArray(); + $array[$id] = $data; + } + $account->budgetInformation = $array; + $account->balancedAmount = $balancedAmount; + + } + ); + + return $accounts; } @@ -191,78 +200,27 @@ class Report implements ReportInterface $start->startOfMonth(); $end = clone $date; $end->endOfMonth(); - $userId = $this->_accounts->getUser()->id; - $set = \TransactionJournal:: - leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->leftJoin( - 'transactions', function (JoinClause $join) { - $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where( - 'transactions.amount', '>', 0 - ); - } - ) - ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') - ->leftJoin( - 'transactions AS otherTransactions', function (JoinClause $join) { - $join->on('transaction_journals.id', '=', 'otherTransactions.transaction_journal_id')->where( - 'otherTransactions.amount', '<', 0 - ); - } - ) - ->leftJoin('accounts as otherAccounts', 'otherAccounts.id', '=', 'otherTransactions.account_id') - ->leftJoin( - 'account_meta', function (JoinClause $join) { - $join->on('otherAccounts.id', '=', 'account_meta.account_id')->where('account_meta.name', '=', 'accountRole'); - } - ) - ->where('date', '>=', $start->format('Y-m-d')) - ->where('date', '<=', $end->format('Y-m-d')) - ->where('account_meta.data', '!=', '"sharedExpense"') - ->where('transaction_types.type', 'Withdrawal') - ->whereNull('transaction_journals.deleted_at') - ->where('transaction_journals.user_id', $userId) - ->groupBy('account_id') - ->orderBy('sum', 'ASC') - ->get( - [ - 'transactions.account_id', - 'accounts.name', - \DB::Raw('SUM(`transactions`.`amount`) * -1 AS `sum`') - ] - ); - $transfers = $this->getTransfersToSharedGroupedByAccounts($date); - // merge $transfers into $set + $set = $this->_queries->journalsByExpenseAccount($start, $end); + $expenses = $this->_helper->makeArray($set); + + $alt = $this->_queries->sharedExpenses($start, $end); + $transfers = $this->_helper->makeArray($alt); + + $expenses[-1] = [ + 'amount' => 0, + 'name' => 'Transfers to shared', + 'spent' => 0 + ]; + foreach ($transfers as $transfer) { - if (!is_null($transfer->account_id)) { - $set->push($transfer); - } - } - // sort the list. - $set = $set->sortBy( - function ($entry) { - return floatval($entry->sum); - } - ); - $return = new Collection; - $bottom = new stdClass(); - $bottom->name = 'Others'; - $bottom->account_id = 0; - $bottom->sum = 0; - - $count = 0; - foreach ($set as $entry) { - if ($count < $limit) { - $return->push($entry); - } else { - $bottom->sum += floatval($entry->sum); - } - $count++; + $expenses[-1]['amount'] += $transfer['amount']; } - $return->push($bottom); + $expenses = $this->_helper->sortArray($expenses); + $limited = $this->_helper->limitArray($expenses, $limit); - return $return; + return $limited; } @@ -280,8 +238,8 @@ class Report implements ReportInterface $end->endOfMonth(); $userId = $this->_accounts->getUser()->id; - $list = \TransactionJournal::withRelevantData() - ->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + + $list = \TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') ->leftJoin( 'account_meta', function (JoinClause $join) { @@ -291,6 +249,7 @@ class Report implements ReportInterface ->transactionTypes(['Deposit']) ->where('transaction_journals.user_id', $userId) ->where('transactions.amount', '>', 0) + ->where('transaction_journals.user_id', \Auth::user()->id) ->where('account_meta.data', '!=', '"sharedExpense"') ->orderBy('date', 'ASC') ->before($end)->after($start)->get(['transaction_journals.*']); @@ -354,49 +313,6 @@ class Report implements ReportInterface } - /** - * @param Carbon $date - * - * @return Collection - */ - public function getTransfersToSharedGroupedByAccounts(Carbon $date) - { - $start = clone $date; - $start->startOfMonth(); - $end = clone $date; - $end->endOfMonth(); - - return \TransactionJournal:: - leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->leftJoin( - 'transactions', function (JoinClause $join) { - $join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where( - 'transactions.amount', '>', 0 - ); - } - ) - ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') - ->leftJoin( - 'account_meta', function (JoinClause $join) { - $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); - } - ) - ->where('account_meta.data', '"sharedExpense"') - ->where('date', '>=', $start->format('Y-m-d')) - ->where('date', '<=', $end->format('Y-m-d')) - ->where('transaction_types.type', 'Transfer') - ->where('transaction_journals.user_id', \Auth::user()->id) - ->groupBy('accounts.name') - ->get( - [ - 'transactions.account_id', - 'accounts.name', - \DB::Raw('SUM(`transactions`.`amount`) * -1 AS `sum`') - ] - ); - } - - /** * @param Carbon $start * diff --git a/app/lib/FireflyIII/Report/ReportHelper.php b/app/lib/FireflyIII/Report/ReportHelper.php index d6dd6e619f..6d82ae261a 100644 --- a/app/lib/FireflyIII/Report/ReportHelper.php +++ b/app/lib/FireflyIII/Report/ReportHelper.php @@ -116,4 +116,25 @@ class ReportHelper implements ReportHelperInterface return $array; } + + /** + * Sort an array where all 'amount' keys are positive floats. + * + * @param array $array + * + * @return array + */ + public function sortArray(array $array) { + uasort( + $array, function ($left, $right) { + if ($left['amount'] == $right['amount']) { + return 0; + } + + return ($left['amount'] < $right['amount']) ? 1 : -1; + } + ); + return $array; + + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Report/ReportHelperInterface.php b/app/lib/FireflyIII/Report/ReportHelperInterface.php index 1be77864c7..762af0bee6 100644 --- a/app/lib/FireflyIII/Report/ReportHelperInterface.php +++ b/app/lib/FireflyIII/Report/ReportHelperInterface.php @@ -52,4 +52,13 @@ interface ReportHelperInterface */ public function sortNegativeArray(array $array); + /** + * Sort an array where all 'amount' keys are positive floats. + * + * @param array $array + * + * @return array + */ + public function sortArray(array $array); + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Report/ReportInterface.php b/app/lib/FireflyIII/Report/ReportInterface.php index e72cb2948b..73658f652f 100644 --- a/app/lib/FireflyIII/Report/ReportInterface.php +++ b/app/lib/FireflyIII/Report/ReportInterface.php @@ -22,33 +22,15 @@ interface ReportInterface public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15); /** + * Gets all the users shared and non-shared accounts combined with various meta-data + * to display the amount of money spent that month compared to what's been spend within + * budgets. + * * @param Carbon $date * * @return Collection */ - public function getBudgetsForMonth(Carbon $date); - - /** - * @param Carbon $date - * - * @return Collection - */ - public function getTransfersToSharedGroupedByAccounts(Carbon $date); - - /** - * @param Carbon $date - * - * @return Collection - */ - public function getPiggyBanksForMonth(Carbon $date); - - /** - * @param Carbon $date - * @param int $limit - * - * @return array - */ - public function getCategoriesForMonth(Carbon $date, $limit = 15); + public function getAccountListBudgetOverview(Carbon $date); /** * @param Carbon $date @@ -57,14 +39,28 @@ interface ReportInterface */ public function getAccountsForMonth(Carbon $date); + /** + * @param Carbon $date + * + * @return Collection + */ + public function getBudgetsForMonth(Carbon $date); + + /** + * @param Carbon $date + * @param int $limit + * + * @return array + */ + public function getCategoriesForMonth(Carbon $date, $limit = 15); + /** * @param Carbon $date * @param int $limit * * @return Collection */ - public function getExpenseGroupedForMonth(Carbon $date, $limit = 15); - + public function getExpenseGroupedForMonth(Carbon $date, $limit = 15); /** * @param Carbon $date @@ -74,6 +70,13 @@ interface ReportInterface */ public function getIncomeForMonth(Carbon $date, $shared = false); + /** + * @param Carbon $date + * + * @return Collection + */ + public function getPiggyBanksForMonth(Carbon $date); + /** * @param Carbon $start * diff --git a/app/lib/FireflyIII/Report/ReportQuery.php b/app/lib/FireflyIII/Report/ReportQuery.php index 6cb7049c41..199827e7bb 100644 --- a/app/lib/FireflyIII/Report/ReportQuery.php +++ b/app/lib/FireflyIII/Report/ReportQuery.php @@ -3,6 +3,7 @@ namespace FireflyIII\Report; use Carbon\Carbon; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; @@ -30,7 +31,7 @@ class ReportQuery implements ReportQueryInterface ->whereIn('account_types.type', ['Default account', 'Cash account', 'Asset account']) ->where('active', 1) ->where( - function ($query) { + function (Builder $query) { $query->where('account_meta.data', '!=', '"sharedExpense"'); $query->orWhereNull('account_meta.data'); } @@ -38,6 +39,114 @@ class ReportQuery implements ReportQueryInterface ->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. + * + * @param \Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function balancedTransactionsList(\Account $account, Carbon $start, Carbon $end) + { + + $set = \TransactionJournal:: + leftJoin('transaction_group_transaction_journal', 'transaction_group_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->leftJoin( + 'transaction_group_transaction_journal as otherFromGroup', function (JoinClause $join) { + $join->on('otherFromGroup.transaction_group_id', '=', 'transaction_group_transaction_journal.transaction_group_id') + ->on('otherFromGroup.transaction_journal_id', '!=', 'transaction_journals.id'); + } + ) + ->leftJoin('transaction_journals as otherJournals', 'otherJournals.id', '=', 'otherFromGroup.transaction_journal_id') + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'otherJournals.transaction_type_id') + ->leftJoin( + 'transactions', function (JoinClause $join) { + $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('amount', '>', 0); + } + ) + ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'otherJournals.id') + ->before($end) + ->after($start) + ->where('transaction_types.type', 'Withdrawal') + ->where('transaction_journals.user_id', \Auth::user()->id) + ->whereNull('budget_transaction_journal.budget_id') + ->whereNull('transaction_journals.deleted_at') + ->whereNull('otherJournals.deleted_at') + ->where('transactions.account_id', $account->id) + ->whereNotNull('transaction_group_transaction_journal.transaction_group_id') + ->groupBy('transaction_journals.id') + ->get( + [ + 'transaction_journals.id as transferId', + 'transaction_journals.description as transferDescription', + 'transaction_group_transaction_journal.transaction_group_id as groupId', + 'otherFromGroup.transaction_journal_id as expenseId', + 'otherJournals.description as expenseDescription', + 'transactions.amount' + ] + ); + + return $set; + } + + /** + * This method will sum up all expenses in a certain time period that have no budget + * and are balanced by a transfer to make up for it. + * + * @param \Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return float + */ + public function balancedTransactionsSum(\Account $account, Carbon $start, Carbon $end) + { + $list = $this->balancedTransactionsList($account, $start, $end); + $sum = 0; + foreach ($list as $entry) { + $sum += floatval($entry->amount); + } + + return $sum; + } + + /** + * Get a users accounts combined with various meta-data related to the start and end date. + * + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getAllAccounts(Carbon $start, Carbon $end) + { + $set = \Auth::user()->accounts() + ->accountTypeIn(['Default account', 'Asset account', 'Cash account']) + ->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', '!=', '"sharedExpense"'); + $query->orWhereNull('account_meta.data'); + } + ) + ->get(['accounts.*']); + $set->each( + function (\Account $account) use ($start, $end) { + $account->startBalance = \Steam::balance($account, $start); + $account->endBalance = \Steam::balance($account, $end); + } + ); + + return $set; + } + /** * Gets a list of all budgets and if present, the amount of the current BudgetLimit * as well @@ -57,6 +166,41 @@ class ReportQuery implements ReportQueryInterface ->get(['budgets.*', 'budget_limits.amount as amount']); } + /** + * Grabs a summary of all expenses grouped by budget, related to the account. + * + * @param \Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return mixed + */ + public function getBudgetSummary(\Account $account, Carbon $start, Carbon $end) + { + $set = \TransactionJournal:: + leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->leftJoin('budgets', 'budgets.id', '=', 'budget_transaction_journal.budget_id') + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->leftJoin( + 'transactions', function (JoinClause $join) { + $join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0); + } + ) + ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') + ->before($end) + ->after($start) + ->where('accounts.id', $account->id) + ->where('transaction_journals.user_id', \Auth::user()->id) + ->where('transaction_types.type', 'Withdrawal') + ->groupBy('budgets.id') + ->orderBy('budgets.id') + ->get(['budgets.id', 'budgets.name', \DB::Raw('SUM(`transactions`.`amount`) as `amount`')]); + + return $set; + + + } + /** * Gets a list of expenses grouped by the budget they were filed under. * @@ -140,6 +284,38 @@ class ReportQuery implements ReportQueryInterface */ public function journalsByExpenseAccount(Carbon $start, Carbon $end) { + 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', 'Withdrawal') + ->where('acm_from.data', '!=', '"sharedExpense"') + ->before($end) + ->after($start) + ->where('transaction_journals.user_id', \Auth::user()->id) + ->groupBy('t_to.account_id') + ->orderBy('amount', 'DESC') + ->get(['t_to.account_id as id', 'ac_to.name as name', \DB::Raw('SUM(t_to.amount) as `amount`')]); } /** diff --git a/app/lib/FireflyIII/Report/ReportQueryInterface.php b/app/lib/FireflyIII/Report/ReportQueryInterface.php index fffdb133b4..a33d6ee8ad 100644 --- a/app/lib/FireflyIII/Report/ReportQueryInterface.php +++ b/app/lib/FireflyIII/Report/ReportQueryInterface.php @@ -22,14 +22,49 @@ interface ReportQueryInterface public function accountList(); /** - * Gets a list of expenses grouped by the budget they were filed under. + * Get a users accounts combined with various meta-data related to the start and end date. * * @param Carbon $start * @param Carbon $end * * @return Collection */ - public function journalsByBudget(Carbon $start, Carbon $end); + public function getAllAccounts(Carbon $start, Carbon $end); + + /** + * Grabs a summary of all expenses grouped by budget, related to the account. + * + * @param \Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return mixed + */ + public function getBudgetSummary(\Account $account, Carbon $start, Carbon $end); + + /** + * This method will sum up all expenses in a certain time period that have no budget + * and are balanced by a transfer to make up for it. + * + * @param \Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return float + */ + public function balancedTransactionsSum(\Account $account, Carbon $start, Carbon $end); + + /** + * 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. + * + * @param \Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function balancedTransactionsList(\Account $account, Carbon $start, Carbon $end); /** * Gets a list of all budgets and if present, the amount of the current BudgetLimit @@ -41,6 +76,16 @@ interface ReportQueryInterface */ public function getAllBudgets(Carbon $date); + /** + * Gets a list of expenses grouped by the budget they were filed under. + * + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function journalsByBudget(Carbon $start, Carbon $end); + /** * Gets a list of categories and the expenses therein, grouped by the relevant category. * This result excludes transfers to shared accounts which are expenses, technically. @@ -63,6 +108,16 @@ interface ReportQueryInterface */ public function journalsByExpenseAccount(Carbon $start, Carbon $end); + /** + * With an equally misleading name, this query returns are transfers to shared accounts. These are considered + * expenses. + * + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function sharedExpenses(Carbon $start, Carbon $end); /** * With a slightly misleading name, this query returns all transfers to shared accounts @@ -75,15 +130,4 @@ interface ReportQueryInterface */ public function sharedExpensesByCategory(Carbon $start, Carbon $end); - /** - * With an equally misleading name, this query returns are transfers to shared accounts. These are considered - * expenses. - * - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - public function sharedExpenses(Carbon $start, Carbon $end); - } \ No newline at end of file diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index 2703bb4fe1..ee9cd336c7 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -111,7 +111,7 @@ class TransactionJournal extends Eloquent */ public function scopeAfter($query, Carbon $date) { - return $query->where('date', '>=', $date->format('Y-m-d')); + return $query->where('transaction_journals.date', '>=', $date->format('Y-m-d 00:00:00')); } /** @@ -122,7 +122,7 @@ class TransactionJournal extends Eloquent */ public function scopeBefore($query, Carbon $date) { - return $query->where('date', '<=', $date->format('Y-m-d')); + return $query->where('transaction_journals.date', '<=', $date->format('Y-m-d 00:00:00')); } /** diff --git a/app/routes.php b/app/routes.php index b12d653354..17368d6878 100644 --- a/app/routes.php +++ b/app/routes.php @@ -248,6 +248,7 @@ 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']); #Route::get('/reports/unbalanced/{year}/{month}', ['uses' => 'ReportController@unbalanced', 'as' => 'reports.unbalanced']); // reminder controller diff --git a/app/views/reports/budget.blade.php b/app/views/reports/budget.blade.php new file mode 100644 index 0000000000..3d37060fd6 --- /dev/null +++ b/app/views/reports/budget.blade.php @@ -0,0 +1,129 @@ +@extends('layouts.default') +@section('content') +{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName()) }} +
+
+ + + + + + + + @foreach($accounts as $account) + + + + + + + @endforeach +
AccountStart of monthCurrent balanceSpent
{{{$account->name}}}{{mf($account->startBalance)}}{{mf($account->endBalance)}}{{mf($account->startBalance - $account->endBalance,false)}}
+
+
+
+
+ + + + + + @foreach($accounts as $account) + + id] = 0; + ?> + @endforeach + + + @foreach($budgets as $id => $budget) + + + + + @foreach($accounts as $account) + @if(isset($account->budgetInformation[$id])) + + budgetInformation[$id]['amount']); + $accountSums[$account->id] += floatval($account->budgetInformation[$id]['amount']); + ?> + @else + + @endif + @endforeach + + + + @endforeach + + + @foreach($accounts as $account) + @if(isset($account->budgetInformation[0])) + + @else + + @endif + @endforeach + + + + + @foreach($accounts as $account) + + @endforeach + + + + + + @foreach($accounts as $account) + id] += $account->balancedAmount; + ?> + @if(isset($account->budgetInformation[0])) + + @else + + @endif + @endforeach + + + + + @foreach($accounts as $account) + + @endforeach + + + + + @foreach($accounts as $account) + + @endforeach + + + +
Budgets{{{$account->name}}} + Left in budget +
{{{$budget['name']}}}{{mf($budget['amount'])}}{{mf($account->budgetInformation[$id]['amount'])}}{{mf(0)}}{{mf($budget['amount'] + $budget['spent'])}}{{mf($budget['amount'] + $spent)}}
Without budget{{mf($account->budgetInformation[0]['amount'])}}{{mf(0)}} 
Balanced by transfers{{mf($account->balancedAmount)}} 
Left unbalanced{{mf($account->budgetInformation[0]['amount'] + $account->balancedAmount)}}{{mf(0)}} 
Sum{{mf($accountSums[$account->id])}} 
Expected balance{{mf($account->startBalance + $accountSums[$account->id])}} 
+
+
+@stop \ No newline at end of file diff --git a/app/views/reports/index.blade.php b/app/views/reports/index.blade.php index 8a0e83fe81..80e6180f36 100644 --- a/app/views/reports/index.blade.php +++ b/app/views/reports/index.blade.php @@ -31,5 +31,20 @@ + +
+
+
+ Budget reports +
+
+ +
+
+
@stop \ No newline at end of file diff --git a/app/views/reports/month.blade.php b/app/views/reports/month.blade.php index 693e39ac7c..2075b3f6a3 100644 --- a/app/views/reports/month.blade.php +++ b/app/views/reports/month.blade.php @@ -13,15 +13,15 @@
Expenses (top 10)
- @foreach($expenses as $expense) - sum);?> + @foreach($expenses as $id => $expense) + - @if($expense->account_id != 0) - + @if($id > 0) + @else - + @endif - + @endforeach @@ -51,7 +51,7 @@ - +
{{{$expense->name}}}{{{$expense['name']}}}{{{$expense->name}}}{{{$expense['name']}}}{{mf($expense->sum)}}{{mf($expense['amount'])}}
Difference{{mf($sum + $in)}}{{mf($in - $sum)}}
diff --git a/app/views/reports/unbalanced.blade.php b/app/views/reports/unbalanced.blade.php deleted file mode 100644 index 74aa64fe41..0000000000 --- a/app/views/reports/unbalanced.blade.php +++ /dev/null @@ -1,56 +0,0 @@ -@extends('layouts.default') -@section('content') -{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $start) }} -@if(count($journals) == 0) -
-
-

Everything accounted for.

-
-
-@endif -@if(count($journals) > 0) -
-
-

Withdrawals

-
-
- -
- @foreach($journals as $journal) -
-
-
- @if($journal->transactiontype->type == 'Withdrawal') - - @endif - @if($journal->transactiontype->type == 'Deposit') - - @endif - @if($journal->transactiontype->type == 'Transfer') - - @endif - @if($journal->transactiontype->type == 'Opening balance') - - @endif - {{{$journal->description}}} -
-
-

Spent {{mf($journal->getAmount())}}

-

No counter transaction!

-

- Add counter transaction -

-
-
-
- @endforeach -
-@endif -@stop -@section('scripts') - -{{HTML::script('assets/javascript/firefly/reports.js')}} -{{HTML::script('assets/javascript/firefly/related-manager.js')}} -@stop \ No newline at end of file diff --git a/app/views/reports/year.blade.php b/app/views/reports/year.blade.php index 827f988a37..db918e2718 100644 --- a/app/views/reports/year.blade.php +++ b/app/views/reports/year.blade.php @@ -84,10 +84,10 @@ Expenses - @foreach($groupedExpenses as $expense) + @foreach($groupedExpenses as $id => $expense) - - + + @endforeach
{{{$expense->name}}}{{mf(floatval($expense->sum)*-1)}}{{{$expense['name']}}}{{mf(floatval($expense['amount'])*-1)}}