diff --git a/app/Generator/Chart/Budget/BudgetChartGeneratorInterface.php b/app/Generator/Chart/Budget/BudgetChartGeneratorInterface.php index acddc5b6da..1abaa89746 100644 --- a/app/Generator/Chart/Budget/BudgetChartGeneratorInterface.php +++ b/app/Generator/Chart/Budget/BudgetChartGeneratorInterface.php @@ -44,4 +44,11 @@ interface BudgetChartGeneratorInterface * @return array */ public function period(array $entries): array; + + /** + * @param array $entries + * + * @return array + */ + public function periodNoBudget(array $entries): array; } diff --git a/app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php b/app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php index 131fae600c..bec7872b28 100644 --- a/app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php +++ b/app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php @@ -104,7 +104,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface * * @return array */ - public function period(array $entries) : array + public function period(array $entries): array { $data = [ @@ -133,4 +133,32 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface return $data; } + + /** + * @param array $entries + * + * @return array + */ + public function periodNoBudget(array $entries): array + { + $data = [ + 'labels' => array_keys($entries), + 'datasets' => [ + 0 => [ + 'label' => trans('firefly.spent'), + 'data' => [], + ], + ], + 'count' => 1, + ]; + + foreach ($entries as $label => $entry) { + // data set 0 is budgeted + // data set 1 is spent: + $data['datasets'][0]['data'][] = round(($entry['spent'] * -1), 2); + + } + + return $data; + } } diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php index 5b0952ab55..7caff56bb4 100644 --- a/app/Generator/Report/Audit/MonthReportGenerator.php +++ b/app/Generator/Report/Audit/MonthReportGenerator.php @@ -78,6 +78,7 @@ class MonthReportGenerator implements ReportGeneratorInterface $auditData[$id]['dayBeforeBalance'] = $dayBeforeBalance; } + $defaultShow = ['icon', 'description', 'balance_before', 'amount', 'balance_after', 'date', 'to']; $reportType = 'audit'; $accountIds = join(',', $this->accounts->pluck('id')->toArray()); $hideable = ['buttons', 'icon', 'description', 'balance_before', 'amount', 'balance_after', 'date', @@ -87,10 +88,9 @@ class MonthReportGenerator implements ReportGeneratorInterface 'from', 'to', 'budget', 'category', 'bill', // more new optional fields 'internal_reference', 'notes', - 'create_date', 'update_date', ]; - $defaultShow = ['icon', 'description', 'balance_before', 'amount', 'balance_after', 'date', 'to']; + return view('reports.audit.report', compact('reportType', 'accountIds', 'auditData', 'hideable', 'defaultShow')) ->with('start', $this->start)->with('end', $this->end)->with('accounts', $this->accounts) diff --git a/app/Helpers/Report/BudgetReportHelper.php b/app/Helpers/Report/BudgetReportHelper.php index eac93e796c..d79b9617b3 100644 --- a/app/Helpers/Report/BudgetReportHelper.php +++ b/app/Helpers/Report/BudgetReportHelper.php @@ -42,22 +42,6 @@ class BudgetReportHelper implements BudgetReportHelperInterface $this->repository = $repository; } - /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * - * @return array - */ - public function getBudgetPeriodReport(Carbon $start, Carbon $end, Collection $accounts): array - { - $budgets = $this->repository->getBudgets(); - $report = $this->repository->getBudgetPeriodReport($budgets, $accounts, $start, $end, true); - $data = $this->filterBudgetPeriodReport($report); - - return $data; - } - /** * @param Carbon $start * @param Carbon $end @@ -162,31 +146,4 @@ class BudgetReportHelper implements BudgetReportHelperInterface return $array; } - - /** - * Filters empty results from getBudgetPeriodReport - * - * @param array $data - * - * @return array - */ - private function filterBudgetPeriodReport(array $data): array - { - /** - * @var int $budgetId - * @var array $set - */ - foreach ($data as $budgetId => $set) { - $sum = '0'; - foreach ($set['entries'] as $amount) { - $sum = bcadd($amount, $sum); - } - $data[$budgetId]['sum'] = $sum; - if (bccomp('0', $sum) === 0) { - unset($data[$budgetId]); - } - } - - return $data; - } } diff --git a/app/Helpers/Report/BudgetReportHelperInterface.php b/app/Helpers/Report/BudgetReportHelperInterface.php index ad8540a22a..07234f9694 100644 --- a/app/Helpers/Report/BudgetReportHelperInterface.php +++ b/app/Helpers/Report/BudgetReportHelperInterface.php @@ -26,15 +26,6 @@ use Illuminate\Support\Collection; interface BudgetReportHelperInterface { - /** - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * - * @return array - */ - public function getBudgetPeriodReport(Carbon $start, Carbon $end, Collection $accounts): array; - /** * @param Carbon $start * @param Carbon $end diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index ab2198be3b..1ef712a9a3 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -252,6 +252,48 @@ class BudgetController extends Controller return Response::json($data); } + /** + * @param BudgetRepositoryInterface $repository + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * + * @return \Illuminate\Http\JsonResponse + */ + public function periodNoBudget(BudgetRepositoryInterface $repository, Carbon $start, Carbon $end, Collection $accounts) + { + // chart properties for cache: + $cache = new CacheProperties(); + $cache->addProperty($start); + $cache->addProperty($end); + $cache->addProperty($accounts); + $cache->addProperty('no-budget'); + $cache->addProperty('period'); + if ($cache->has()) { + return Response::json($cache->get()); + } + + // the expenses: + $periods = Navigation::listOfPeriods($start, $end); + $entries = $repository->getNoBudgetPeriodReport($accounts, $start, $end); + + // join them: + $result = []; + foreach (array_keys($periods) as $period) { + $nice = $periods[$period]; + $result[$nice] = [ + 'spent' => isset($entries['entries'][$period]) ? $entries['entries'][$period] : '0', + ]; + } + + $data = $this->generator->periodNoBudget($result); + + $cache->store($data); + + return Response::json($data); + } + /** * @param Collection $repetitions * @param Budget $budget diff --git a/app/Http/Controllers/Report/BudgetController.php b/app/Http/Controllers/Report/BudgetController.php index 8e76f2c5d5..89b5136b60 100644 --- a/app/Http/Controllers/Report/BudgetController.php +++ b/app/Http/Controllers/Report/BudgetController.php @@ -17,6 +17,7 @@ namespace FireflyIII\Http\Controllers\Report; use Carbon\Carbon; use FireflyIII\Helpers\Report\BudgetReportHelperInterface; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\CacheProperties; use Illuminate\Support\Collection; use Navigation; @@ -31,14 +32,13 @@ class BudgetController extends Controller /** * - * @param BudgetReportHelperInterface $helper - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts * * @return string */ - public function budgetPeriodReport(BudgetReportHelperInterface $helper, Carbon $start, Carbon $end, Collection $accounts) + public function budgetPeriodReport(Carbon $start, Carbon $end, Collection $accounts) { $cache = new CacheProperties; $cache->addProperty($start); @@ -46,12 +46,19 @@ class BudgetController extends Controller $cache->addProperty('budget-period-report'); $cache->addProperty($accounts->pluck('id')->toArray()); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } - $periods = Navigation::listOfPeriods($start, $end); - $budgets = $helper->getBudgetPeriodReport($start, $end, $accounts); - $result = view('reports.partials.budget-period', compact('budgets', 'periods'))->render(); + // generate budget report right here. + /** @var BudgetRepositoryInterface $repository */ + $repository = app(BudgetRepositoryInterface::class); + $budgets = $repository->getBudgets(); + $data = $repository->getBudgetPeriodReport($budgets, $accounts, $start, $end); + $data[0] = $repository->getNoBudgetPeriodReport($accounts, $start, $end); // append report data for "no budget" + $report = $this->filterBudgetPeriodReport($data); + $periods = Navigation::listOfPeriods($start, $end); + + $result = view('reports.partials.budget-period', compact('report', 'periods'))->render(); $cache->store($result); return $result; @@ -86,4 +93,31 @@ class BudgetController extends Controller return $result; } + + /** + * Filters empty results from getBudgetPeriodReport + * + * @param array $data + * + * @return array + */ + private function filterBudgetPeriodReport(array $data): array + { + /** + * @var int $budgetId + * @var array $set + */ + foreach ($data as $budgetId => $set) { + $sum = '0'; + foreach ($set['entries'] as $amount) { + $sum = bcadd($amount, $sum); + } + $data[$budgetId]['sum'] = $sum; + if (bccomp('0', $sum) === 0) { + unset($data[$budgetId]); + } + } + + return $data; + } } \ No newline at end of file diff --git a/app/Http/Controllers/Report/CategoryController.php b/app/Http/Controllers/Report/CategoryController.php index b683171ae8..7284638f27 100644 --- a/app/Http/Controllers/Report/CategoryController.php +++ b/app/Http/Controllers/Report/CategoryController.php @@ -31,40 +31,6 @@ use Navigation; */ class CategoryController extends Controller { - /** - * - * @param Carbon $start - * @param Carbon $end - * @param Collection $accounts - * - * @return string - */ - public function categoryPeriodReport(Carbon $start, Carbon $end, Collection $accounts) - { - $cache = new CacheProperties; - $cache->addProperty($start); - $cache->addProperty($end); - $cache->addProperty('category-period-report'); - $cache->addProperty($accounts->pluck('id')->toArray()); - if ($cache->has()) { - Log::debug('Return report from cache'); - - return $cache->get(); - } - /** @var CategoryRepositoryInterface $repository */ - $repository = app(CategoryRepositoryInterface::class); - $categories = $repository->getCategories(); - $report = $repository->getCategoryPeriodReport($categories, $accounts, $start, $end, true); - $report = $this->filterCategoryPeriodReport($report); - $periods = Navigation::listOfPeriods($start, $end); - - $result = view('reports.partials.category-period', compact('categories', 'periods', 'report'))->render(); - - $cache->store($result); - - return $result; - } - /** * @param ReportHelperInterface $helper * @param Carbon $start @@ -93,6 +59,73 @@ class CategoryController extends Controller return $result; } + /** + * + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * + * @return string + */ + public function expenseReport(Carbon $start, Carbon $end, Collection $accounts) + { + $cache = new CacheProperties; + $cache->addProperty($start); + $cache->addProperty($end); + $cache->addProperty('category-period-expenses-report'); + $cache->addProperty($accounts->pluck('id')->toArray()); + if ($cache->has()) { + Log::debug('Return report from cache'); + return $cache->get(); + } + /** @var CategoryRepositoryInterface $repository */ + $repository = app(CategoryRepositoryInterface::class); + $categories = $repository->getCategories(); + $data = $repository->periodExpenses($categories, $accounts, $start, $end); + $data[0] = $repository->periodExpensesNoCategory($accounts, $start, $end); + $report = $this->filterReport($data); + $periods = Navigation::listOfPeriods($start, $end); + $result = view('reports.partials.category-period', compact('report', 'periods'))->render(); + + $cache->store($result); + + return $result; + } + + /** + * + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * + * @return string + */ + public function incomeReport(Carbon $start, Carbon $end, Collection $accounts) + { + $cache = new CacheProperties; + $cache->addProperty($start); + $cache->addProperty($end); + $cache->addProperty('category-period-income-report'); + $cache->addProperty($accounts->pluck('id')->toArray()); + if ($cache->has()) { + Log::debug('Return report from cache'); + return $cache->get(); + } + /** @var CategoryRepositoryInterface $repository */ + $repository = app(CategoryRepositoryInterface::class); + $categories = $repository->getCategories(); + $data = $repository->periodIncome($categories, $accounts, $start, $end); + $data[0] = $repository->periodIncomeNoCategory($accounts, $start, $end); + $report = $this->filterReport($data); + $periods = Navigation::listOfPeriods($start, $end); + $result = view('reports.partials.category-period', compact('report', 'periods'))->render(); + + $cache->store($result); + + return $result; + } + + /** * Filters empty results from category period report * @@ -100,22 +133,16 @@ class CategoryController extends Controller * * @return array */ - private function filterCategoryPeriodReport(array $data): array + private function filterReport(array $data): array { - /** - * @var string $type - * @var array $report - */ - foreach ($data as $type => $report) { - foreach ($report as $categoryId => $set) { - $sum = '0'; - foreach ($set['entries'] as $amount) { - $sum = bcadd($amount, $sum); - } - $data[$type][$categoryId]['sum'] = $sum; - if (bccomp('0', $sum) === 0) { - unset($data[$type][$categoryId]); - } + foreach ($data as $categoryId => $set) { + $sum = '0'; + foreach ($set['entries'] as $amount) { + $sum = bcadd($amount, $sum); + } + $data[$categoryId]['sum'] = $sum; + if (bccomp('0', $sum) === 0) { + unset($data[$categoryId]); } } @@ -123,25 +150,5 @@ class CategoryController extends Controller return $data; } - /** - * @param int $categoryId - * @param Collection $categories - * - * @return string - */ - private function getCategoryName(int $categoryId, Collection $categories): string - { - - $first = $categories->filter( - function (Category $category) use ($categoryId) { - return $categoryId === $category->id; - } - ); - if (!is_null($first->first())) { - return $first->first()->name; - } - - return '(unknown)'; - } } \ No newline at end of file diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index ecdafaf1b8..140b865fd3 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -368,10 +368,10 @@ class AccountRepository implements AccountRepositoryInterface protected function openingBalanceTransaction(Account $account): TransactionJournal { $journal = TransactionJournal::sortCorrectly() - ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->transactionTypes([TransactionType::OPENING_BALANCE]) - ->first(['transaction_journals.*']); + ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id) + ->transactionTypes([TransactionType::OPENING_BALANCE]) + ->first(['transaction_journals.*']); if (is_null($journal)) { Log::debug('Could not find a opening balance journal, return empty one.'); diff --git a/app/Repositories/Account/AccountTasker.php b/app/Repositories/Account/AccountTasker.php index efcff148de..691181b40f 100644 --- a/app/Repositories/Account/AccountTasker.php +++ b/app/Repositories/Account/AccountTasker.php @@ -250,19 +250,19 @@ class AccountTasker implements AccountTaskerInterface $selection = $incoming ? '>' : '<'; $query = Transaction::distinct() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin( - 'transactions as other_side', function (JoinClause $join) use ($joinModifier) { - $join->on('transaction_journals.id', '=', 'other_side.transaction_journal_id')->where('other_side.amount', $joinModifier, 0); - } - ) - ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) - ->where('transaction_journals.user_id', $this->user->id) - ->whereNull('transactions.deleted_at') - ->whereNull('transaction_journals.deleted_at') - ->whereIn('transactions.account_id', $accounts['accounts']) - ->where('transactions.amount', $selection, 0); + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin( + 'transactions as other_side', function (JoinClause $join) use ($joinModifier) { + $join->on('transaction_journals.id', '=', 'other_side.transaction_journal_id')->where('other_side.amount', $joinModifier, 0); + } + ) + ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) + ->where('transaction_journals.user_id', $this->user->id) + ->whereNull('transactions.deleted_at') + ->whereNull('transaction_journals.deleted_at') + ->whereIn('transactions.account_id', $accounts['accounts']) + ->where('transactions.amount', $selection, 0); if (count($accounts['exclude']) > 0) { $query->whereNotIn('other_side.account_id', $accounts['exclude']); } @@ -302,25 +302,27 @@ class AccountTasker implements AccountTaskerInterface $joinModifier = $incoming ? '<' : '>'; $selection = $incoming ? '>' : '<'; $query = Transaction::distinct() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') - ->leftJoin( - 'transactions as other_side', function (JoinClause $join) use ($joinModifier) { - $join->on('transaction_journals.id', '=', 'other_side.transaction_journal_id')->where('other_side.amount', $joinModifier, 0); - } - ) - ->leftJoin('accounts as other_account', 'other_account.id', '=', 'other_side.account_id') - ->where('transaction_types.type', '!=', TransactionType::OPENING_BALANCE) - ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) - ->where('transaction_journals.user_id', $this->user->id) - ->whereNull('transactions.deleted_at') - ->whereNull('other_side.deleted_at') - ->whereNull('transaction_journals.deleted_at') - ->whereIn('transactions.account_id', $accounts['accounts']) - ->where('other_side.amount', '=', DB::raw('transactions.amount * -1')) - ->where('transactions.amount', $selection, 0) - ->orderBy('transactions.amount'); + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') + ->leftJoin( + 'transactions as other_side', function (JoinClause $join) use ($joinModifier) { + $join->on('transaction_journals.id', '=', 'other_side.transaction_journal_id')->where( + 'other_side.amount', $joinModifier, 0 + ); + } + ) + ->leftJoin('accounts as other_account', 'other_account.id', '=', 'other_side.account_id') + ->where('transaction_types.type', '!=', TransactionType::OPENING_BALANCE) + ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) + ->where('transaction_journals.user_id', $this->user->id) + ->whereNull('transactions.deleted_at') + ->whereNull('other_side.deleted_at') + ->whereNull('transaction_journals.deleted_at') + ->whereIn('transactions.account_id', $accounts['accounts']) + ->where('other_side.amount', '=', DB::raw('transactions.amount * -1')) + ->where('transactions.amount', $selection, 0) + ->orderBy('transactions.amount'); if (count($accounts['exclude']) > 0) { $query->whereNotIn('other_side.account_id', $accounts['exclude']); diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index e41196b81d..179e0aa12b 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -66,7 +66,7 @@ class BillRepository implements BillRepositoryInterface * * @return Bill */ - public function find(int $billId) : Bill + public function find(int $billId): Bill { $bill = $this->user->bills()->find($billId); if (is_null($bill)) { @@ -83,7 +83,7 @@ class BillRepository implements BillRepositoryInterface * * @return Bill */ - public function findByName(string $name) : Bill + public function findByName(string $name): Bill { $bills = $this->user->bills()->get(['bills.*']); diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php index cf71d133bc..c2c6cd223d 100644 --- a/app/Repositories/Bill/BillRepositoryInterface.php +++ b/app/Repositories/Bill/BillRepositoryInterface.php @@ -40,7 +40,7 @@ interface BillRepositoryInterface * * @return Bill */ - public function find(int $billId) : Bill; + public function find(int $billId): Bill; /** * Find a bill by name. @@ -49,7 +49,7 @@ interface BillRepositoryInterface * * @return Bill */ - public function findByName(string $name) : Bill; + public function findByName(string $name): Bill; /** * @return Collection diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 47cf4e7273..ff5e4467b5 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -219,11 +219,10 @@ class BudgetRepository implements BudgetRepositoryInterface * @param Collection $accounts * @param Carbon $start * @param Carbon $end - * @param bool $noBudget * * @return array */ - public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end, bool $noBudget): array + public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array { $carbonFormat = Navigation::preferredCarbonFormat($start, $end); $data = []; @@ -252,11 +251,6 @@ class BudgetRepository implements BudgetRepositoryInterface $data[$budgetId]['entries'][$date] = bcadd($data[$budgetId]['entries'][$date] ?? '0', $transaction->transaction_amount); } - if ($noBudget) { - // and now the same for stuff without a budget: - $data[0] = $this->getNoBudgetPeriodReport($start, $end); - } - return $data; } @@ -295,6 +289,40 @@ class BudgetRepository implements BudgetRepositoryInterface return $set; } + /** + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array + { + $carbonFormat = Navigation::preferredCarbonFormat($start, $end); + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end); + $collector->setTypes([TransactionType::WITHDRAWAL]); + $collector->withoutBudget(); + $transactions = $collector->getJournals(); + $result = [ + 'entries' => [], + 'name' => strval(trans('firefly.no_budget')), + 'sum' => '0', + ]; + + foreach ($transactions as $transaction) { + $date = $transaction->date->format($carbonFormat); + + if (!isset($result['entries'][$date])) { + $result['entries'][$date] = '0'; + } + $result['entries'][$date] = bcadd($result['entries'][$date], $transaction->transaction_amount); + } + + return $result; + } + /** * @param Collection $budgets * @param Collection $accounts @@ -533,58 +561,4 @@ class BudgetRepository implements BudgetRepositoryInterface return $limit; } - - /** - * @param int $budgetId - * @param Collection $budgets - * - * @return string - */ - private function getBudgetName(int $budgetId, Collection $budgets): string - { - - $first = $budgets->filter( - function (Budget $budget) use ($budgetId) { - return $budgetId === $budget->id; - } - ); - if (!is_null($first->first())) { - return $first->first()->name; - } - - return '(unknown)'; - } - - /** - * @param Carbon $start - * @param Carbon $end - * - * @return array - */ - private function getNoBudgetPeriodReport(Carbon $start, Carbon $end): array - { - $carbonFormat = Navigation::preferredCarbonFormat($start, $end); - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAllAssetAccounts()->setRange($start, $end); - $collector->setTypes([TransactionType::WITHDRAWAL]); - $collector->withoutBudget(); - $transactions = $collector->getJournals(); - $result = [ - 'entries' => [], - 'name' => strval(trans('firefly.no_budget')), - 'sum' => '0', - ]; - - foreach ($transactions as $transaction) { - $date = $transaction->date->format($carbonFormat); - - if (!isset($result['entries'][$date])) { - $result['entries'][$date] = '0'; - } - $result['entries'][$date] = bcadd($result['entries'][$date], $transaction->transaction_amount); - } - - return $result; - } } diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index 296b06ed4f..6161545760 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -96,11 +96,10 @@ interface BudgetRepositoryInterface * @param Collection $accounts * @param Carbon $start * @param Carbon $end - * @param bool $noBudget * * @return array */ - public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end, bool $noBudget): array; + public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array; /** * @return Collection @@ -112,6 +111,14 @@ interface BudgetRepositoryInterface */ public function getInactiveBudgets(): Collection; + /** + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array; + /** * @param Collection $budgets * @param Collection $accounts diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php index 403df60c5e..7c002558a2 100644 --- a/app/Repositories/Category/CategoryRepository.php +++ b/app/Repositories/Category/CategoryRepository.php @@ -175,32 +175,6 @@ class CategoryRepository implements CategoryRepositoryInterface return $set; } - /** - * This method is being used to generate the category overview in the year/multi-year report. Its used - * in both the year/multi-year budget overview AND in the accompanying chart. - * - * @param Collection $categories - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * @param @bool $noCategory - * - * @return array - */ - public function getCategoryPeriodReport(Collection $categories, Collection $accounts, Carbon $start, Carbon $end, bool $noCategory): array - { - $data = [ - 'income' => $this->getCategoryReportData($categories, $accounts, $start, $end, $noCategory, [TransactionType::DEPOSIT, TransactionType::TRANSFER]), - 'expense' => $this->getCategoryReportData( - $categories, $accounts, $start, $end, $noCategory, [TransactionType::WITHDRAWAL, TransactionType::TRANSFER] - ), - ]; - - return $data; - - - } - /** * @param Category $category * @param Collection $accounts @@ -250,6 +224,158 @@ class CategoryRepository implements CategoryRepositoryInterface return $last; } + /** + * @param Collection $categories + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array + { + $carbonFormat = Navigation::preferredCarbonFormat($start, $end); + $data = []; + // prep data array: + /** @var Category $category */ + foreach ($categories as $category) { + $data[$category->id] = [ + 'name' => $category->name, + 'sum' => '0', + 'entries' => [], + ]; + } + + // get all transactions: + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end); + $collector->setCategories($categories)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) + ->withOpposingAccount() + ->enableInternalFilter(); + $transactions = $collector->getJournals(); + + // loop transactions: + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + $categoryId = max(intval($transaction->transaction_journal_category_id), intval($transaction->transaction_category_id)); + $date = $transaction->date->format($carbonFormat); + $data[$categoryId]['entries'][$date] = bcadd($data[$categoryId]['entries'][$date] ?? '0', $transaction->transaction_amount); + } + + return $data; + } + + /** + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodExpensesNoCategory(Collection $accounts, Carbon $start, Carbon $end): array + { + $carbonFormat = Navigation::preferredCarbonFormat($start, $end); + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end); + $collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])->enableInternalFilter(); + $collector->withoutCategory(); + $transactions = $collector->getJournals(); + $result = [ + 'entries' => [], + 'name' => strval(trans('firefly.no_category')), + 'sum' => '0', + ]; + + foreach ($transactions as $transaction) { + $date = $transaction->date->format($carbonFormat); + + if (!isset($result['entries'][$date])) { + $result['entries'][$date] = '0'; + } + $result['entries'][$date] = bcadd($result['entries'][$date], $transaction->transaction_amount); + } + + return $result; + } + + /** + * @param Collection $categories + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array + { + $carbonFormat = Navigation::preferredCarbonFormat($start, $end); + $data = []; + // prep data array: + /** @var Category $category */ + foreach ($categories as $category) { + $data[$category->id] = [ + 'name' => $category->name, + 'sum' => '0', + 'entries' => [], + ]; + } + + // get all transactions: + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end); + $collector->setCategories($categories)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) + ->withOpposingAccount() + ->enableInternalFilter(); + $transactions = $collector->getJournals(); + + // loop transactions: + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + $categoryId = max(intval($transaction->transaction_journal_category_id), intval($transaction->transaction_category_id)); + $date = $transaction->date->format($carbonFormat); + $data[$categoryId]['entries'][$date] = bcadd($data[$categoryId]['entries'][$date] ?? '0', $transaction->transaction_amount); + } + + return $data; + } + + /** + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodIncomeNoCategory(Collection $accounts, Carbon $start, Carbon $end): array + { + $carbonFormat = Navigation::preferredCarbonFormat($start, $end); + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end); + $collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])->enableInternalFilter(); + $collector->withoutCategory(); + $transactions = $collector->getJournals(); + $result = [ + 'entries' => [], + 'name' => strval(trans('firefly.no_category')), + 'sum' => '0', + ]; + + foreach ($transactions as $transaction) { + $date = $transaction->date->format($carbonFormat); + + if (!isset($result['entries'][$date])) { + $result['entries'][$date] = '0'; + } + $result['entries'][$date] = bcadd($result['entries'][$date], $transaction->transaction_amount); + } + + return $result; + } + /** * @param Collection $categories * @param Collection $accounts @@ -314,55 +440,6 @@ class CategoryRepository implements CategoryRepositoryInterface return $category; } - /** - * @param Collection $categories - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * @param bool $noCategory - * @param array $types - * - * @return array - */ - private function getCategoryReportData(Collection $categories, Collection $accounts, Carbon $start, Carbon $end, bool $noCategory, array $types): array - { - $carbonFormat = Navigation::preferredCarbonFormat($start, $end); - $data = []; - // prep data array: - /** @var Category $category */ - foreach ($categories as $category) { - $data[$category->id] = [ - 'name' => $category->name, - 'sum' => '0', - 'entries' => [], - ]; - } - - // get all transactions: - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end); - $collector->setCategories($categories)->setTypes($types) - ->withOpposingAccount() - ->enableInternalFilter(); - $transactions = $collector->getJournals(); - - // loop transactions: - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $categoryId = max(intval($transaction->transaction_journal_category_id), intval($transaction->transaction_category_id)); - $date = $transaction->date->format($carbonFormat); - $data[$categoryId]['entries'][$date] = bcadd($data[$categoryId]['entries'][$date] ?? '0', $transaction->transaction_amount); - } - - if ($noCategory) { - // and now the same for stuff without a budget: - //$data[0] = $this->getNoBudgetPeriodReport($start, $end); - } - - return $data; - } - /** * @param Collection $categories * @param Collection $accounts diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php index feb479c52d..bbcd272d1e 100644 --- a/app/Repositories/Category/CategoryRepositoryInterface.php +++ b/app/Repositories/Category/CategoryRepositoryInterface.php @@ -24,7 +24,6 @@ use Illuminate\Support\Collection; */ interface CategoryRepositoryInterface { - /** * @param Category $category * @@ -83,20 +82,6 @@ interface CategoryRepositoryInterface */ public function getCategories(): Collection; - /** - * This method is being used to generate the category overview in the year/multi-year report. Its used - * in both the year/multi-year budget overview AND in the accompanying chart. - * - * @param Collection $categories - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * @param bool $noCategory - * - * @return array - */ - public function getCategoryPeriodReport(Collection $categories, Collection $accounts, Carbon $start, Carbon $end, bool $noCategory): array; - /** * Return most recent transaction(journal) date. * @@ -107,6 +92,44 @@ interface CategoryRepositoryInterface */ public function lastUseDate(Category $category, Collection $accounts): Carbon; + /** + * @param Collection $categories + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array; + + /** + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodExpensesNoCategory(Collection $accounts, Carbon $start, Carbon $end): array; + + /** + * @param Collection $categories + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array; + + /** + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + public function periodIncomeNoCategory(Collection $accounts, Carbon $start, Carbon $end): array; + /** * @param Collection $categories * @param Collection $accounts diff --git a/app/Repositories/Currency/CurrencyRepository.php b/app/Repositories/Currency/CurrencyRepository.php index 3b88e9ede4..1bf6e8728f 100644 --- a/app/Repositories/Currency/CurrencyRepository.php +++ b/app/Repositories/Currency/CurrencyRepository.php @@ -43,7 +43,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function find(int $currencyId) : TransactionCurrency + public function find(int $currencyId): TransactionCurrency { $currency = TransactionCurrency::find($currencyId); if (is_null($currency)) { @@ -61,7 +61,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function findByCode(string $currencyCode) : TransactionCurrency + public function findByCode(string $currencyCode): TransactionCurrency { $currency = TransactionCurrency::whereCode($currencyCode)->first(); if (is_null($currency)) { @@ -78,7 +78,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function findByName(string $currencyName) : TransactionCurrency + public function findByName(string $currencyName): TransactionCurrency { $preferred = TransactionCurrency::whereName($currencyName)->first(); if (is_null($preferred)) { @@ -95,7 +95,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function findBySymbol(string $currencySymbol) : TransactionCurrency + public function findBySymbol(string $currencySymbol): TransactionCurrency { $currency = TransactionCurrency::whereSymbol($currencySymbol)->first(); if (is_null($currency)) { diff --git a/app/Repositories/Currency/CurrencyRepositoryInterface.php b/app/Repositories/Currency/CurrencyRepositoryInterface.php index 4bd01fa256..94ae094cbe 100644 --- a/app/Repositories/Currency/CurrencyRepositoryInterface.php +++ b/app/Repositories/Currency/CurrencyRepositoryInterface.php @@ -39,7 +39,7 @@ interface CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function find(int $currencyId) : TransactionCurrency; + public function find(int $currencyId): TransactionCurrency; /** * Find by currency code @@ -48,7 +48,7 @@ interface CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function findByCode(string $currencyCode) : TransactionCurrency; + public function findByCode(string $currencyCode): TransactionCurrency; /** * Find by currency name @@ -57,7 +57,7 @@ interface CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function findByName(string $currencyName) : TransactionCurrency; + public function findByName(string $currencyName): TransactionCurrency; /** * Find by currency symbol @@ -66,7 +66,7 @@ interface CurrencyRepositoryInterface * * @return TransactionCurrency */ - public function findBySymbol(string $currencySymbol) : TransactionCurrency; + public function findBySymbol(string $currencySymbol): TransactionCurrency; /** * @return Collection diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 1643007904..c655b20f41 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -105,7 +105,7 @@ class JournalRepository implements JournalRepositoryInterface * * @return TransactionJournal */ - public function find(int $journalId) : TransactionJournal + public function find(int $journalId): TransactionJournal { $journal = $this->user->transactionJournals()->where('id', $journalId)->first(); if (is_null($journal)) { diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index 8a25f542b9..fb9779eec3 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -52,7 +52,7 @@ interface JournalRepositoryInterface * * @return TransactionJournal */ - public function find(int $journalId) : TransactionJournal; + public function find(int $journalId): TransactionJournal; /** * Get users very first transaction journal diff --git a/app/Repositories/Journal/JournalTasker.php b/app/Repositories/Journal/JournalTasker.php index 90e3edbd75..16cc5a5f3a 100644 --- a/app/Repositories/Journal/JournalTasker.php +++ b/app/Repositories/Journal/JournalTasker.php @@ -172,36 +172,36 @@ class JournalTasker implements JournalTaskerInterface // go! $sum = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('account_id', $transaction->account_id) - ->whereNull('transactions.deleted_at') - ->whereNull('transaction_journals.deleted_at') - ->where('transactions.id', '!=', $transactionId) - ->where( - function (Builder $q1) use ($date, $order, $journalId, $identifier) { - $q1->where('transaction_journals.date', '<', $date); // date - $q1->orWhere( - function (Builder $q2) use ($date, $order) { // function 1 - $q2->where('transaction_journals.date', $date); - $q2->where('transaction_journals.order', '>', $order); - } - ); - $q1->orWhere( - function (Builder $q3) use ($date, $order, $journalId) { // function 2 - $q3->where('transaction_journals.date', $date); - $q3->where('transaction_journals.order', $order); - $q3->where('transaction_journals.id', '<', $journalId); - } - ); - $q1->orWhere( - function (Builder $q4) use ($date, $order, $journalId, $identifier) { // function 3 - $q4->where('transaction_journals.date', $date); - $q4->where('transaction_journals.order', $order); - $q4->where('transaction_journals.id', $journalId); - $q4->where('transactions.identifier', '>', $identifier); - } - ); - } - )->sum('transactions.amount'); + ->where('account_id', $transaction->account_id) + ->whereNull('transactions.deleted_at') + ->whereNull('transaction_journals.deleted_at') + ->where('transactions.id', '!=', $transactionId) + ->where( + function (Builder $q1) use ($date, $order, $journalId, $identifier) { + $q1->where('transaction_journals.date', '<', $date); // date + $q1->orWhere( + function (Builder $q2) use ($date, $order) { // function 1 + $q2->where('transaction_journals.date', $date); + $q2->where('transaction_journals.order', '>', $order); + } + ); + $q1->orWhere( + function (Builder $q3) use ($date, $order, $journalId) { // function 2 + $q3->where('transaction_journals.date', $date); + $q3->where('transaction_journals.order', $order); + $q3->where('transaction_journals.id', '<', $journalId); + } + ); + $q1->orWhere( + function (Builder $q4) use ($date, $order, $journalId, $identifier) { // function 3 + $q4->where('transaction_journals.date', $date); + $q4->where('transaction_journals.order', $order); + $q4->where('transaction_journals.id', $journalId); + $q4->where('transactions.identifier', '>', $identifier); + } + ); + } + )->sum('transactions.amount'); return strval($sum); } diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index 6eef1e358e..ede86894c7 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -117,7 +117,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface * * @return Collection */ - public function getPiggyBanksWithAmount() : Collection + public function getPiggyBanksWithAmount(): Collection { $set = $this->getPiggyBanks(); foreach ($set as $piggy) { diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php index 22eb0a4e9a..aae01702d7 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php @@ -58,7 +58,7 @@ interface PiggyBankRepositoryInterface * * @return Collection */ - public function getEvents(PiggyBank $piggyBank) : Collection; + public function getEvents(PiggyBank $piggyBank): Collection; /** * Highest order of all piggy banks. @@ -72,14 +72,14 @@ interface PiggyBankRepositoryInterface * * @return Collection */ - public function getPiggyBanks() : Collection; + public function getPiggyBanks(): Collection; /** * Also add amount in name. * * @return Collection */ - public function getPiggyBanksWithAmount() : Collection; + public function getPiggyBanksWithAmount(): Collection; /** * Set all piggy banks to order 0. diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index ecdc5bfe94..3740584f41 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -93,7 +93,7 @@ class TagRepository implements TagRepositoryInterface * * @return Tag */ - public function find(int $tagId) : Tag + public function find(int $tagId): Tag { $tag = $this->user->tags()->find($tagId); if (is_null($tag)) { @@ -108,7 +108,7 @@ class TagRepository implements TagRepositoryInterface * * @return Tag */ - public function findByTag(string $tag) : Tag + public function findByTag(string $tag): Tag { $tags = $this->user->tags()->get(); /** @var Tag $tag */ diff --git a/app/Repositories/Tag/TagRepositoryInterface.php b/app/Repositories/Tag/TagRepositoryInterface.php index dd1966bd51..3da24ab718 100644 --- a/app/Repositories/Tag/TagRepositoryInterface.php +++ b/app/Repositories/Tag/TagRepositoryInterface.php @@ -49,14 +49,14 @@ interface TagRepositoryInterface * * @return Tag */ - public function find(int $tagId) : Tag; + public function find(int $tagId): Tag; /** * @param string $tag * * @return Tag */ - public function findByTag(string $tag) : Tag; + public function findByTag(string $tag): Tag; /** * This method returns all the user's tags. diff --git a/app/Repositories/User/UserRepository.php b/app/Repositories/User/UserRepository.php index e3fa94480a..87ac639290 100644 --- a/app/Repositories/User/UserRepository.php +++ b/app/Repositories/User/UserRepository.php @@ -114,10 +114,10 @@ class UserRepository implements UserRepositoryInterface $return['categories'] = $user->categories()->count(); $return['budgets'] = $user->budgets()->count(); $return['budgets_with_limits'] = BudgetLimit::distinct() - ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') - ->where('amount', '>', 0) - ->whereNull('budgets.deleted_at') - ->where('budgets.user_id', $user->id)->get(['budget_limits.budget_id'])->count(); + ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') + ->where('amount', '>', 0) + ->whereNull('budgets.deleted_at') + ->where('budgets.user_id', $user->id)->get(['budget_limits.budget_id'])->count(); $return['export_jobs'] = $user->exportJobs()->count(); $return['export_jobs_success'] = $user->exportJobs()->where('status', 'export_downloaded')->count(); $return['import_jobs'] = $user->exportJobs()->count(); diff --git a/public/js/ff/reports/default/year.js b/public/js/ff/reports/default/year.js index 237f3bac77..96e2d64167 100644 --- a/public/js/ff/reports/default/year.js +++ b/public/js/ff/reports/default/year.js @@ -5,7 +5,9 @@ $(function () { drawChart(); loadAjaxPartial('budgetPeriodReport', budgetPeriodReportUri); - loadAjaxPartial('categoryPeriodReport', categoryPeriodReportUri); + + loadAjaxPartial('categoryExpense', categoryExpenseUri); + loadAjaxPartial('categoryIncome', categoryIncomeUri); }); function drawChart() { diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index fd25fbd685..33f05b180e 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -85,4 +85,5 @@ return [ 'file' => 'The :attribute must be a file.', 'in_array' => 'The :attribute field does not exist in :other.', 'present' => 'The :attribute field must be present.', + 'amount_zero' => 'The total amount cannot be zero', ]; diff --git a/resources/views/reports/default/year.twig b/resources/views/reports/default/year.twig index 01dcfc304c..5b757717b0 100644 --- a/resources/views/reports/default/year.twig +++ b/resources/views/reports/default/year.twig @@ -113,14 +113,27 @@ - {# same thing but for categories #} + {# same thing but for categories (expenses) #}
-

{{ 'categories'|_ }}

+

{{ 'categories'|_ }} ({{ 'expenses'|_ }})

-
+
+
+
+
+
+ + {# same thing but for categories (income) #} +
+
+
+
+

{{ 'categories'|_ }} ({{ 'income'|_ }})

+
+
@@ -164,7 +177,9 @@ var incExpReportUri = '{{ route('reports.data.incExpReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; var budgetPeriodReportUri = '{{ route('reports.data.budgetPeriodReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; - var categoryPeriodReportUri = '{{ route('reports.data.categoryPeriodReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; + var categoryExpenseUri = '{{ route('reports.data.categoryExpense', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; + var categoryIncomeUri = '{{ route('reports.data.categoryIncome', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}'; + diff --git a/resources/views/reports/partials/budget-period.twig b/resources/views/reports/partials/budget-period.twig index 6660019cbc..c9bb1cbd45 100644 --- a/resources/views/reports/partials/budget-period.twig +++ b/resources/views/reports/partials/budget-period.twig @@ -9,7 +9,7 @@ - {% for id, info in budgets %} + {% for id, info in report %} {{ info.name }} diff --git a/resources/views/reports/partials/category-period.twig b/resources/views/reports/partials/category-period.twig index 59185a3adf..ca20b994ff 100644 --- a/resources/views/reports/partials/category-period.twig +++ b/resources/views/reports/partials/category-period.twig @@ -1,75 +1,44 @@ - + {% for period in periods %} - + {% endfor %} - - - - {% for period in periods %} - - - {% endfor %} - - + - {% for category in categories %} - {% if report.income[category.id] or report.expense[category.id] %} - - + + + {% for key, period in periods %} + {# income first #} + {% if(info.entries[key]) %} + + {% else %} + + {% endif %} + {% endfor %} + + {# if sum of income, display: #} + {% if info.sum %} + - - {% for key, period in periods %} - {# income first #} - {% if(report.income[category.id].entries[key]) %} - - {% else %} - - {% endif %} - - {# expenses #} - {% if(report.expense[category.id].entries[key]) %} - - {% else %} - - {% endif %} - {% endfor %} - - {# if sum of income, display: #} - {% if report.income[category.id].sum %} - - {% else %} - - {% endif %} - {# if sum of expense, display: #} - {% if report.expense[category.id].sum %} - - {% else %} - - {% endif %} - - {% endif %} + {% else %} + + {% endif %} + {% endfor %}
{{ 'category'|_ }}{{ 'category'|_ }}{{ period }}{{ period }}{{ 'sum'|_ }}
InOutInOut{{ 'sum'|_ }}
- {{ category.name }} + {% for id, info in report %} +
+ {{ info.name }} + + {{ info.entries[key]|formatAmount }} + + {{ 0|formatAmount }} + + {{ info.sum|formatAmount }} - {{ report.income[category.id].entries[key]|formatAmount }} - - {{ 0|formatAmount }} - - {{ report.expense[category.id].entries[key]|formatAmount }} - - {{ 0|formatAmount }} - - {{ report.income[category.id].sum|formatAmount }} - - {{ 0|formatAmount }} - - {{ report.expense[category.id].sum|formatAmount }} - - {{ 0|formatAmount }} -
+ {{ 0|formatAmount }} +
\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 2d1d1d4ac4..3b7fe776c0 100755 --- a/routes/web.php +++ b/routes/web.php @@ -210,6 +210,7 @@ Route::group( // budgets: Route::get('/chart/budget/frontpage', ['uses' => 'Chart\BudgetController@frontpage']); + Route::get('/chart/budget/period/0/default/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\BudgetController@periodNoBudget']); Route::get('/chart/budget/period/{budget}/default/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\BudgetController@period']); // this chart is used in reports: @@ -410,11 +411,16 @@ Route::group( ['uses' => 'Report\BudgetController@budgetPeriodReport', 'as' => 'reports.data.budgetPeriodReport'] ); - // category period overview + // category period overview (expense and income) Route::get( - '/reports/data/category-period/{start_date}/{end_date}/{accountList}', - ['uses' => 'Report\CategoryController@categoryPeriodReport', 'as' => 'reports.data.categoryPeriodReport'] + '/reports/data/category-expense/{start_date}/{end_date}/{accountList}', + ['uses' => 'Report\CategoryController@expenseReport', 'as' => 'reports.data.categoryExpense'] ); + Route::get( + '/reports/data/category-income/{start_date}/{end_date}/{accountList}', + ['uses' => 'Report\CategoryController@incomeReport', 'as' => 'reports.data.categoryIncome'] + ); + /** * Rules Controller