mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Better management and calculation of available budgets.
This commit is contained in:
parent
1c7988fad2
commit
28efc15820
@ -88,8 +88,8 @@ abstract class Controller extends BaseController
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
if ($page > pow(2,16)) {
|
||||
$page = pow(2,16);
|
||||
if ($page > pow(2, 16)) {
|
||||
$page = pow(2, 16);
|
||||
}
|
||||
$bag->set('page', $page);
|
||||
|
||||
|
46
app/Events/Model/BudgetLimit/Created.php
Normal file
46
app/Events/Model/BudgetLimit/Created.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* Created.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events\Model\BudgetLimit;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class Created
|
||||
*/
|
||||
class Created extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public BudgetLimit $budgetLimit;
|
||||
|
||||
/**
|
||||
* @param BudgetLimit $budgetLimit
|
||||
*/
|
||||
public function __construct(BudgetLimit $budgetLimit)
|
||||
{
|
||||
$this->budgetLimit = $budgetLimit;
|
||||
}
|
||||
}
|
46
app/Events/Model/BudgetLimit/Deleted.php
Normal file
46
app/Events/Model/BudgetLimit/Deleted.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* Created.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events\Model\BudgetLimit;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class Deleted
|
||||
*/
|
||||
class Deleted extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public BudgetLimit $budgetLimit;
|
||||
|
||||
/**
|
||||
* @param BudgetLimit $budgetLimit
|
||||
*/
|
||||
public function __construct(BudgetLimit $budgetLimit)
|
||||
{
|
||||
$this->budgetLimit = $budgetLimit;
|
||||
}
|
||||
}
|
46
app/Events/Model/BudgetLimit/Updated.php
Normal file
46
app/Events/Model/BudgetLimit/Updated.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* Created.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events\Model\BudgetLimit;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class Updated
|
||||
*/
|
||||
class Updated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public BudgetLimit $budgetLimit;
|
||||
|
||||
/**
|
||||
* @param BudgetLimit $budgetLimit
|
||||
*/
|
||||
public function __construct(BudgetLimit $budgetLimit)
|
||||
{
|
||||
$this->budgetLimit = $budgetLimit;
|
||||
}
|
||||
}
|
221
app/Handlers/Events/Model/BudgetLimitHandler.php
Normal file
221
app/Handlers/Events/Model/BudgetLimitHandler.php
Normal file
@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* BudgetLimitHandler.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Handlers\Events\Model;
|
||||
|
||||
use FireflyIII\Events\Model\BudgetLimit\Created;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Deleted;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Updated;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Spatie\Period\Boundaries;
|
||||
use Spatie\Period\Period;
|
||||
use Spatie\Period\Precision;
|
||||
|
||||
/**
|
||||
* Class BudgetLimitHandler
|
||||
*/
|
||||
class BudgetLimitHandler
|
||||
{
|
||||
/**
|
||||
* @param Created $event
|
||||
* @return void
|
||||
*/
|
||||
public function created(Created $event): void
|
||||
{
|
||||
Log::debug(sprintf('BudgetLimitHandler::created(%s)', $event->budgetLimit->id));
|
||||
$this->updateAvailableBudget($event->budgetLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Updated $event
|
||||
* @return void
|
||||
*/
|
||||
public function updated(Updated $event): void
|
||||
{
|
||||
Log::debug(sprintf('BudgetLimitHandler::updated(%s)', $event->budgetLimit->id));
|
||||
$this->updateAvailableBudget($event->budgetLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Deleted $event
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(Deleted $event): void
|
||||
{
|
||||
Log::debug(sprintf('BudgetLimitHandler::deleted(%s)', $event->budgetLimit->id));
|
||||
$this->updateAvailableBudget($event->budgetLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AvailableBudget $availableBudget
|
||||
* @return void
|
||||
*/
|
||||
private function calculateAmount(AvailableBudget $availableBudget): void
|
||||
{
|
||||
$repository = app(BudgetLimitRepositoryInterface::class);
|
||||
$repository->setUser($availableBudget->user);
|
||||
$newAmount = '0';
|
||||
$abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY());
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Now at AB #%d, ("%s" to "%s")',
|
||||
$availableBudget->id,
|
||||
$availableBudget->start_date->format('Y-m-d'),
|
||||
$availableBudget->end_date->format('Y-m-d')
|
||||
)
|
||||
);
|
||||
// have to recalc everything just in case.
|
||||
$set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date);
|
||||
/** @var BudgetLimit $budgetLimit */
|
||||
foreach ($set as $budgetLimit) {
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Found interesting budget limit #%d ("%s" to "%s")',
|
||||
$budgetLimit->id,
|
||||
$budgetLimit->start_date->format('Y-m-d'),
|
||||
$budgetLimit->end_date->format('Y-m-d')
|
||||
)
|
||||
);
|
||||
// overlap in days:
|
||||
$limitPeriod = Period::make(
|
||||
$budgetLimit->start_date,
|
||||
$budgetLimit->end_date,
|
||||
precision: Precision::DAY(),
|
||||
boundaries: Boundaries::EXCLUDE_NONE()
|
||||
);
|
||||
// if both equal eachother, amount from this BL must be added to the AB
|
||||
if ($limitPeriod->equals($abPeriod)) {
|
||||
Log::debug('Limit period is the same as AB period.');
|
||||
$newAmount = bcadd($newAmount, $budgetLimit->amount);
|
||||
}
|
||||
// if budget limit period inside AB period, can be added in full.
|
||||
|
||||
if (!$limitPeriod->equals($abPeriod) && $abPeriod->contains($limitPeriod)) {
|
||||
Log::debug('Limit period falls inside of AB period.');
|
||||
$newAmount = bcadd($newAmount, $budgetLimit->amount);
|
||||
}
|
||||
if (!$limitPeriod->equals($abPeriod) && $abPeriod->overlapsWith($limitPeriod)) {
|
||||
Log::debug('Limit period overlaps AB period.');
|
||||
$overlap = $abPeriod->overlap($limitPeriod);
|
||||
if (null !== $overlap) {
|
||||
$length = $overlap->length();
|
||||
$daily = bcmul($this->getDailyAmount($budgetLimit), (string)$length);
|
||||
Log::debug(sprintf('Length of overlap is %d days, so daily amount is %s', $length, $daily));
|
||||
$newAmount = bcadd($newAmount, $daily);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log::debug(sprintf('Concluded new amount for this AB must be %s', $newAmount));
|
||||
$availableBudget->amount = $newAmount;
|
||||
$availableBudget->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetLimit $budgetLimit
|
||||
* @return string
|
||||
*/
|
||||
private function getDailyAmount(BudgetLimit $budgetLimit): string
|
||||
{
|
||||
$limitPeriod = Period::make(
|
||||
$budgetLimit->start_date,
|
||||
$budgetLimit->end_date,
|
||||
precision: Precision::DAY(),
|
||||
boundaries: Boundaries::EXCLUDE_NONE()
|
||||
);
|
||||
$days = $limitPeriod->length();
|
||||
$amount = bcdiv((string)$budgetLimit->amount, (string)$days, 12);
|
||||
Log::debug(
|
||||
sprintf('Total amount for budget limit #%d is %s. Nr. of days is %d. Amount per day is %s', $budgetLimit->id, $budgetLimit->amount, $days, $amount)
|
||||
);
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetLimit $budgetLimit
|
||||
* @return void
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
private function updateAvailableBudget(BudgetLimit $budgetLimit): void
|
||||
{
|
||||
Log::debug(sprintf('Now in updateAvailableBudget(#%d)', $budgetLimit->id));
|
||||
|
||||
// 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;
|
||||
|
||||
// limit period in total is:
|
||||
$limitPeriod = Period::make($start, $end, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
|
||||
|
||||
// from the start until the end of the budget limit, need to loop!
|
||||
$current = clone $start;
|
||||
while ($current <= $end) {
|
||||
$currentEnd = app('navigation')->endOfPeriod($current, $viewRange);
|
||||
|
||||
// create or find AB for this particular period, and set the amount accordingly.
|
||||
/** @var AvailableBudget $availableBudget */
|
||||
$availableBudget = $user->availableBudgets()->where('start_date', $current->format('Y-m-d'))->where(
|
||||
'end_date',
|
||||
$currentEnd->format('Y-m-d')
|
||||
)->where('transaction_currency_id', $budgetLimit->transaction_currency_id)->first();
|
||||
if (null !== $availableBudget) {
|
||||
Log::debug('Found AB, will update.');
|
||||
$this->calculateAmount($availableBudget);
|
||||
continue;
|
||||
}
|
||||
// if not exists:
|
||||
$currentPeriod = Period::make($current, $currentEnd, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
|
||||
$daily = $this->getDailyAmount($budgetLimit);
|
||||
$amount = bcmul($daily, (string)$currentPeriod->length(), 12);
|
||||
|
||||
// no need to calculate if period is equal.
|
||||
if ($currentPeriod->equals($limitPeriod)) {
|
||||
$amount = $budgetLimit->amount;
|
||||
}
|
||||
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
|
||||
$current = app('navigation')->addPeriod($current, $viewRange, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -89,12 +89,13 @@ class BudgetLimitController extends Controller
|
||||
$collection = $this->currencyRepos->get();
|
||||
$budgetLimits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
||||
|
||||
// remove already budgeted currencies:
|
||||
// remove already budgeted currencies with the same date range
|
||||
$currencies = $collection->filter(
|
||||
static function (TransactionCurrency $currency) use ($budgetLimits) {
|
||||
/** @var AvailableBudget $budget */
|
||||
foreach ($budgetLimits as $budget) {
|
||||
if ($budget->transaction_currency_id === $currency->id) {
|
||||
static function (TransactionCurrency $currency) use ($budgetLimits, $start, $end) {
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($budgetLimits as $limit) {
|
||||
if ($limit->transaction_currency_id === $currency->id && $limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,9 @@ use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
use JsonException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
@ -101,12 +101,23 @@ class IndexController extends Controller
|
||||
*/
|
||||
public function index(Request $request, Carbon $start = null, Carbon $end = null)
|
||||
{
|
||||
Log::debug('Start of IndexController::index()');
|
||||
Log::debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
|
||||
|
||||
// collect some basic vars:
|
||||
$range = app('navigation')->getViewRange(true);
|
||||
$start = $start ?? session('start', today(config('app.timezone'))->startOfMonth());
|
||||
$end = $end ?? app('navigation')->endOfPeriod($start, $range);
|
||||
$range = app('navigation')->getViewRange(true);
|
||||
$isCustomRange = session('is_custom_range', false);
|
||||
if (false === $isCustomRange) {
|
||||
$start = $start ?? session('start', today(config('app.timezone'))->startOfMonth());
|
||||
$end = $end ?? app('navigation')->endOfPeriod($start, $range);
|
||||
}
|
||||
|
||||
// overrule start and end if necessary:
|
||||
if (true === $isCustomRange) {
|
||||
$start = $start ?? session('start', today(config('app.timezone'))->startOfMonth());
|
||||
$end = $end ?? session('end', today(config('app.timezone'))->endOfMonth());
|
||||
}
|
||||
|
||||
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$currencies = $this->currencyRepository->get();
|
||||
$budgeted = '0';
|
||||
|
@ -24,6 +24,9 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use Eloquent;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Created;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Deleted;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Updated;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -81,6 +84,12 @@ class BudgetLimit extends Model
|
||||
/** @var array Fields that can be filled */
|
||||
protected $fillable = ['budget_id', 'start_date', 'end_date', 'amount', 'transaction_currency_id'];
|
||||
|
||||
protected $dispatchesEvents = [
|
||||
'created' => Created::class,
|
||||
'updated' => Updated::class,
|
||||
'deleted' => Deleted::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
*
|
||||
|
@ -29,6 +29,9 @@ use FireflyIII\Events\AdminRequestedTestMessage;
|
||||
use FireflyIII\Events\ChangedPiggyBankAmount;
|
||||
use FireflyIII\Events\DestroyedTransactionGroup;
|
||||
use FireflyIII\Events\DetectedNewIPAddress;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Created;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Deleted;
|
||||
use FireflyIII\Events\Model\BudgetLimit\Updated;
|
||||
use FireflyIII\Events\NewVersionAvailable;
|
||||
use FireflyIII\Events\RegisteredUser;
|
||||
use FireflyIII\Events\RequestedNewPassword;
|
||||
@ -42,6 +45,7 @@ use FireflyIII\Events\UpdatedAccount;
|
||||
use FireflyIII\Events\UpdatedTransactionGroup;
|
||||
use FireflyIII\Events\UserChangedEmail;
|
||||
use FireflyIII\Events\WarnUserAboutBill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
@ -160,6 +164,17 @@ class EventServiceProvider extends ServiceProvider
|
||||
ChangedPiggyBankAmount::class => [
|
||||
'FireflyIII\Handlers\Events\PiggyBankEventHandler@changePiggyAmount',
|
||||
],
|
||||
// budget related events: CRUD budget limit
|
||||
Created::class => [
|
||||
'FireflyIII\Handlers\Events\Model\BudgetLimitHandler@created',
|
||||
],
|
||||
Updated::class => [
|
||||
'FireflyIII\Handlers\Events\Model\BudgetLimitHandler@updated',
|
||||
],
|
||||
Deleted::class => [
|
||||
'FireflyIII\Handlers\Events\Model\BudgetLimitHandler@deleted',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
@ -169,7 +184,6 @@ class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
parent::boot();
|
||||
$this->registerCreateEvents();
|
||||
$this->registerBudgetEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,57 +202,4 @@ class EventServiceProvider extends ServiceProvider
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO needs a dedicated method.
|
||||
*/
|
||||
protected function registerBudgetEvents(): void
|
||||
{
|
||||
$func = static function (BudgetLimit $limit) {
|
||||
Log::debug('Trigger budget limit event.');
|
||||
// find available budget with same period and same currency or create it.
|
||||
// then set it or add money:
|
||||
$user = $limit->budget->user;
|
||||
$availableBudget = $user
|
||||
->availableBudgets()
|
||||
->where('start_date', $limit->start_date->format('Y-m-d'))
|
||||
->where('end_date', $limit->end_date->format('Y-m-d'))
|
||||
->where('transaction_currency_id', $limit->transaction_currency_id)
|
||||
->first();
|
||||
// update!
|
||||
if (null !== $availableBudget) {
|
||||
$repository = app(BudgetLimitRepositoryInterface::class);
|
||||
$repository->setUser($user);
|
||||
$set = $repository->getAllBudgetLimitsByCurrency($limit->transactionCurrency, $limit->start_date, $limit->end_date);
|
||||
$sum = (string)$set->sum('amount');
|
||||
|
||||
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Because budget limit #%d had its amount changed to %s, available budget limit #%d will be updated.',
|
||||
$limit->id,
|
||||
$limit->amount,
|
||||
$availableBudget->id
|
||||
)
|
||||
);
|
||||
$availableBudget->amount = $sum;
|
||||
$availableBudget->save();
|
||||
return;
|
||||
}
|
||||
Log::debug('Does not exist, create it.');
|
||||
// create it.
|
||||
$data = [
|
||||
'amount' => $limit->amount,
|
||||
'start' => $limit->start_date,
|
||||
'end' => $limit->end_date,
|
||||
'currency_id' => $limit->transaction_currency_id,
|
||||
];
|
||||
$repository = app(AvailableBudgetRepositoryInterface::class);
|
||||
$repository->setUser($user);
|
||||
$repository->store($data);
|
||||
};
|
||||
|
||||
BudgetLimit::created($func);
|
||||
BudgetLimit::updated($func);
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,7 @@
|
||||
"ramsey/uuid": "^4.7",
|
||||
"rcrowe/twigbridge": "^0.14",
|
||||
"spatie/laravel-ignition": "^2",
|
||||
"spatie/period": "^2.4",
|
||||
"symfony/http-client": "^6.0",
|
||||
"symfony/mailgun-mailer": "^6.0",
|
||||
"therobfonz/laravel-mandrill-driver": "^5.0"
|
||||
|
56
composer.lock
generated
56
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "7578458e9e378acae56c08bbd053f38b",
|
||||
"content-hash": "3d09d838fdf529c07df3563a3d96de5c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@ -5806,6 +5806,60 @@
|
||||
],
|
||||
"time": "2023-04-12T09:26:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/period",
|
||||
"version": "2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/period.git",
|
||||
"reference": "85fbbea7b24fdff0c924aeed5b109be93c025850"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/period/zipball/85fbbea7b24fdff0c924aeed5b109be93c025850",
|
||||
"reference": "85fbbea7b24fdff0c924aeed5b109be93c025850",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"larapack/dd": "^1.1",
|
||||
"nesbot/carbon": "^2.63",
|
||||
"pestphp/pest": "^1.22",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"spatie/ray": "^1.31"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\Period\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brent Roose",
|
||||
"email": "brent@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Complex period comparisons",
|
||||
"homepage": "https://github.com/spatie/period",
|
||||
"keywords": [
|
||||
"period",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/period/issues",
|
||||
"source": "https://github.com/spatie/period/tree/2.4.0"
|
||||
},
|
||||
"time": "2023-02-20T14:31:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v6.2.8",
|
||||
|
@ -261,6 +261,7 @@
|
||||
{% if not budgetLimit.in_range %}
|
||||
<small class="text-muted">
|
||||
{{ trans('firefly.budget_limit_not_in_range', {start: budgetLimit.start_date, end: budgetLimit.end_date}) }}
|
||||
|
||||
</small><br>
|
||||
{% endif %}
|
||||
<div class="input-group bl_entry" data-budget-limit-id="{{ budgetLimit.id }}">
|
||||
|
Loading…
Reference in New Issue
Block a user