diff --git a/app/Helpers/Collector/JournalCollector.php b/app/Helpers/Collector/JournalCollector.php index bc9ca44616..d6790eb096 100644 --- a/app/Helpers/Collector/JournalCollector.php +++ b/app/Helpers/Collector/JournalCollector.php @@ -8,6 +8,7 @@ use Carbon\Carbon; use Crypt; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\AccountType; +use FireflyIII\Models\Budget; use FireflyIII\Models\Category; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionType; @@ -70,6 +71,8 @@ class JournalCollector 'transactions.amount', ]; /** @var bool */ + private $joinedBudget = false; + /** @var bool */ private $joinedCategory = false; /** @var int */ private $limit; @@ -193,7 +196,7 @@ class JournalCollector { /** @var AccountRepositoryInterface $repository */ $repository = app(AccountRepositoryInterface::class, [$this->user]); - $accounts = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]); + $accounts = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT, AccountType::CASH]); if ($accounts->count() > 0) { $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereIn('transactions.account_id', $accountIds); @@ -222,6 +225,30 @@ class JournalCollector } + /** + * @param Budget $budget + * + * @return JournalCollector + */ + public function setBudget(Budget $budget): JournalCollector + { + if (!$this->joinedBudget) { + // join some extra tables: + $this->joinedBudget = true; + $this->query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); + $this->query->leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'transactions.id'); + } + + $this->query->where( + function (EloquentBuilder $q) use ($budget) { + $q->where('budget_transaction.budget_id', $budget->id); + $q->orWhere('budget_transaction_journal.budget_id', $budget->id); + } + ); + + return $this; + } + /** * @param Category $category * diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php index b2ed2af41f..f9b176060a 100644 --- a/app/Http/Controllers/BudgetController.php +++ b/app/Http/Controllers/BudgetController.php @@ -17,6 +17,7 @@ use Amount; use Carbon\Carbon; use Config; use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Http\Requests\BudgetFormRequest; use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget; @@ -305,14 +306,13 @@ class BudgetController extends Controller $start = session('first', Carbon::create()->startOfYear()); $end = new Carbon; $page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); - $pageSize = Preferences::get('transactionPageSize', 50)->data; - $offset = ($page - 1) * $pageSize; - $journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end); // budget - $count = $journals->count(); - $journals = $journals->slice($offset, $pageSize); - $journals = new LengthAwarePaginator($journals, $count, $pageSize); + $pageSize = intval(Preferences::get('transactionPageSize', 50)->data); $accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]); + // collector: + $collector = new JournalCollector(auth()->user()); + $collector->setAllAssetAccounts()->setRange($start, $end)->setBudget($budget)->setLimit($pageSize)->setPage($page); + $journals = $collector->getPaginatedJournals(); $journals->setPath('/budgets/show/' . $budget->id); @@ -347,16 +347,15 @@ class BudgetController extends Controller $start = $repetition->startdate; $end = $repetition->enddate; $page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); - $pageSize = Preferences::get('transactionPageSize', 50)->data; - $offset = ($page - 1) * $pageSize; - $journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end); // budget - $count = $journals->count(); - $journals = $journals->slice($offset, $pageSize); - $journals = new LengthAwarePaginator($journals, $count, $pageSize); + $pageSize = intval(Preferences::get('transactionPageSize', 50)->data); $subTitle = trans('firefly.budget_in_month', ['name' => $budget->name, 'month' => $repetition->startdate->formatLocalized($this->monthFormat)]); $accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]); + // collector: + $collector = new JournalCollector(auth()->user()); + $collector->setAllAssetAccounts()->setRange($start, $end)->setBudget($budget)->setLimit($pageSize)->setPage($page); + $journals = $collector->getPaginatedJournals(); $journals->setPath('/budgets/show/' . $budget->id . '/' . $repetition->id); diff --git a/app/Http/Controllers/Popup/ReportController.php b/app/Http/Controllers/Popup/ReportController.php index b31e514853..89fd605502 100644 --- a/app/Http/Controllers/Popup/ReportController.php +++ b/app/Http/Controllers/Popup/ReportController.php @@ -101,9 +101,13 @@ class ReportController extends Controller switch (true) { case ($role === BalanceLine::ROLE_DEFAULTROLE && !is_null($budget->id)): - $journals = $budgetRepository->journalsInPeriod( - new Collection([$budget]), new Collection([$account]), $attributes['startDate'], $attributes['endDate'] - ); + $collector = new JournalCollector(auth()->user()); + $collector + ->setAccounts(new Collection([$account])) + ->setRange($attributes['startDate'], $attributes['endDate']) + ->setBudget($budget); + $journals = $collector->getJournals(); + break; case ($role === BalanceLine::ROLE_DEFAULTROLE && is_null($budget->id)): $budget->name = strval(trans('firefly.no_budget')); @@ -150,9 +154,17 @@ class ReportController extends Controller $budget = $repository->find(intval($attributes['budgetId'])); if (is_null($budget->id)) { $journals = $repository->journalsInPeriodWithoutBudget($attributes['accounts'], $attributes['startDate'], $attributes['endDate']); - } else { + } + if (!is_null($budget->id)) { // get all expenses in budget in period: - $journals = $repository->journalsInPeriod(new Collection([$budget]), $attributes['accounts'], $attributes['startDate'], $attributes['endDate']); + $collector = new JournalCollector(auth()->user()); + $collector + ->setAccounts($attributes['accounts']) + ->setRange($attributes['startDate'], $attributes['endDate']) + ->setBudget($budget); + $journals = $collector->getJournals(); + + } $view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render(); diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index b814a8eaf8..0e0e281dfd 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -210,76 +210,6 @@ class BudgetRepository implements BudgetRepositoryInterface return $set; } - /** - * @param Collection $budgets - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - public function journalsInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): Collection - { - $return = new Collection; - $accountIds = []; - // expand the number of grabbed fields: - $fields = TransactionJournal::queryFields(); - $fields[] = 'source.account_id'; - if ($accounts->count() > 0) { - $accountIds = $accounts->pluck('id')->toArray(); - } - - // first get all journals for all budget(s): - $journalQuery = $this->user->transactionJournals() - ->expanded() - ->sortCorrectly() - ->before($end) - ->after($start) - ->leftJoin( - 'transactions as source', - function (JoinClause $join) { - $join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', '0'); - } - ) - ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') - ->whereIn('budget_transaction_journal.budget_id', $budgets->pluck('id')->toArray()); - // add account id's, if relevant: - if (count($accountIds) > 0) { - $journalQuery->whereIn('source.account_id', $accountIds); - } - // get them: - $journals = $journalQuery->get(TransactionJournal::queryFields()); - - // then get transactions themselves. - $transactionQuery = $this->user->transactionJournals() - ->expanded() - ->before($end) - ->sortCorrectly() - ->after($start) - ->leftJoin('transactions as related', 'related.transaction_journal_id', '=', 'transaction_journals.id') - ->leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'related.id') - ->leftJoin( - 'transactions as source', - function (JoinClause $join) { - $join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', '0'); - } - ) - ->groupBy(['source.account_id']) - ->whereIn('budget_transaction.budget_id', $budgets->pluck('id')->toArray()); - - if (count($accountIds) > 0) { - $transactionQuery->whereIn('source.account_id', $accountIds); - } - - $transactions = $transactionQuery->get($fields); - - // return complete set: - $return = $return->merge($transactions); - $return = $return->merge($journals); - - return $return; - } - /** * @param Collection $accounts * @param Carbon $start diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index 0f6aba141e..e6c5503c1f 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -89,16 +89,6 @@ interface BudgetRepositoryInterface */ public function getInactiveBudgets(): Collection; - /** - * @param Collection $budgets - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - public function journalsInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): Collection; - /** * @param Collection $accounts * @param Carbon $start diff --git a/resources/views/budgets/show.twig b/resources/views/budgets/show.twig index f88ab7ba9b..65ba0465fa 100644 --- a/resources/views/budgets/show.twig +++ b/resources/views/budgets/show.twig @@ -36,7 +36,7 @@