From 46bba9d7990a7c2820a77d4223ae8fe70eb0fcf7 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 30 Apr 2023 06:45:25 +0200 Subject: [PATCH] Various optimizations in budget limit handling. --- .../Events/Model/BudgetLimitHandler.php | 64 ++++++++++++------- .../Budget/OperationsRepository.php | 6 +- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/app/Handlers/Events/Model/BudgetLimitHandler.php b/app/Handlers/Events/Model/BudgetLimitHandler.php index c097fcf7b5..7b050fd2f9 100644 --- a/app/Handlers/Events/Model/BudgetLimitHandler.php +++ b/app/Handlers/Events/Model/BudgetLimitHandler.php @@ -30,6 +30,8 @@ use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; use Illuminate\Support\Facades\Log; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; use Spatie\Period\Boundaries; use Spatie\Period\Period; use Spatie\Period\Precision; @@ -45,7 +47,7 @@ class BudgetLimitHandler */ public function created(Created $event): void { - Log::debug(sprintf('BudgetLimitHandler::created(%s)', $event->budgetLimit->id)); + Log::debug(sprintf('BudgetLimitHandler::created(#%s)', $event->budgetLimit->id)); $this->updateAvailableBudget($event->budgetLimit); } @@ -55,7 +57,7 @@ class BudgetLimitHandler */ public function updated(Updated $event): void { - Log::debug(sprintf('BudgetLimitHandler::updated(%s)', $event->budgetLimit->id)); + Log::debug(sprintf('BudgetLimitHandler::updated(#%s)', $event->budgetLimit->id)); $this->updateAvailableBudget($event->budgetLimit); } @@ -65,7 +67,9 @@ class BudgetLimitHandler */ public function deleted(Deleted $event): void { - Log::debug(sprintf('BudgetLimitHandler::deleted(%s)', $event->budgetLimit->id)); + Log::debug(sprintf('BudgetLimitHandler::deleted(#%s)', $event->budgetLimit->id)); + $budgetLimit = $event->budgetLimit; + $budgetLimit->id = null; $this->updateAvailableBudget($event->budgetLimit); } @@ -124,6 +128,11 @@ class BudgetLimitHandler } } } + if (0 === bccomp('0', $newAmount)) { + Log::debug('New amount is zero, deleting AB.'); + $availableBudget->delete(); + return; + } Log::debug(sprintf('Concluded new amount for this AB must be %s', $newAmount)); $availableBudget->amount = $newAmount; $availableBudget->save(); @@ -135,6 +144,9 @@ class BudgetLimitHandler */ private function getDailyAmount(BudgetLimit $budgetLimit): string { + if(0 === (int)$budgetLimit->id) { + return '0'; + } $limitPeriod = Period::make( $budgetLimit->start_date, $budgetLimit->end_date, @@ -152,9 +164,6 @@ class BudgetLimitHandler /** * @param BudgetLimit $budgetLimit * @return void - * @throws \FireflyIII\Exceptions\FireflyException - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface */ private function updateAvailableBudget(BudgetLimit $budgetLimit): void { @@ -163,11 +172,15 @@ class BudgetLimitHandler // based on the view range of the user (month week quarter etc) the budget limit could // either overlap multiple available budget periods or be contained in a single one. // all have to be created or updated. - $viewRange = app('preferences')->get('viewRange', '1M')->data; - $start = app('navigation')->startOfPeriod($budgetLimit->start_date, $viewRange); - $end = app('navigation')->startOfPeriod($budgetLimit->end_date, $viewRange); - $end = app('navigation')->endOfPeriod($end, $viewRange); - $user = $budgetLimit->budget->user; + try { + $viewRange = app('preferences')->get('viewRange', '1M')->data; + } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { + $viewRange = '1M'; + } + $start = app('navigation')->startOfPeriod($budgetLimit->start_date, $viewRange); + $end = app('navigation')->startOfPeriod($budgetLimit->end_date, $viewRange); + $end = app('navigation')->endOfPeriod($end, $viewRange); + $user = $budgetLimit->budget->user; // limit period in total is: $limitPeriod = Period::make($start, $end, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE()); @@ -195,19 +208,24 @@ class BudgetLimitHandler // no need to calculate if period is equal. if ($currentPeriod->equals($limitPeriod)) { - $amount = $budgetLimit->amount; + $amount = 0 === (int)$budgetLimit->id ? '0' : $budgetLimit->amount; + } + if(0 === bccomp($amount,'0')) { + Log::debug('Amount is zero, will not create AB.'); + } + if(0 !== bccomp($amount,'0')) { + Log::debug(sprintf('Will create AB for period %s to %s', $current->format('Y-m-d'), $currentEnd->format('Y-m-d'))); + $availableBudget = new AvailableBudget( + [ + 'user_id' => $budgetLimit->budget->user->id, + 'transaction_currency_id' => $budgetLimit->transaction_currency_id, + 'start_date' => $current, + 'end_date' => $currentEnd, + 'amount' => $amount, + ] + ); + $availableBudget->save(); } - Log::debug(sprintf('Will create AB for period %s to %s', $current->format('Y-m-d'), $currentEnd->format('Y-m-d'))); - $availableBudget = new AvailableBudget( - [ - 'user_id' => $budgetLimit->budget->user->id, - 'transaction_currency_id' => $budgetLimit->transaction_currency_id, - 'start_date' => $current, - 'end_date' => $currentEnd, - 'amount' => $amount, - ] - ); - $availableBudget->save(); } // prep for next loop diff --git a/app/Repositories/Budget/OperationsRepository.php b/app/Repositories/Budget/OperationsRepository.php index 07a10a4e95..4bca48f1d1 100644 --- a/app/Repositories/Budget/OperationsRepository.php +++ b/app/Repositories/Budget/OperationsRepository.php @@ -298,7 +298,7 @@ class OperationsRepository implements OperationsRepositoryInterface ?Collection $budgets = null, ?TransactionCurrency $currency = null ): array { - Log::debug(sprintf('Now in %s', __METHOD__)); + //Log::debug(sprintf('Now in %s', __METHOD__)); $start->startOfDay(); $end->endOfDay(); @@ -340,7 +340,7 @@ class OperationsRepository implements OperationsRepositoryInterface // same but for foreign currencies: if (null !== $currency) { - Log::debug(sprintf('Currency is "%s".', $currency->name)); + //Log::debug(sprintf('Currency is "%s".', $currency->name)); /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]) @@ -350,7 +350,7 @@ class OperationsRepository implements OperationsRepositoryInterface $collector->setAccounts($accounts); } $result = $collector->getExtractedJournals(); - Log::debug(sprintf('Found %d journals with currency %s.', count($result), $currency->code)); + //Log::debug(sprintf('Found %d journals with currency %s.', count($result), $currency->code)); // do not use array_merge because you want keys to overwrite (otherwise you get double results): $journals = $result + $journals; }