Various optimizations in budget limit handling.

This commit is contained in:
James Cole
2023-04-30 06:45:25 +02:00
parent 0ef1d1834f
commit 46bba9d799
2 changed files with 44 additions and 26 deletions

View File

@@ -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