Allow webhooks to be send for budget limit update.

This commit is contained in:
James Cole
2025-09-14 09:21:32 +02:00
parent 768bd892c8
commit 9075fa8ac8
5 changed files with 88 additions and 71 deletions

View File

@@ -77,6 +77,7 @@ class UpdateController extends Controller
throw new FireflyException('20028: The budget limit does not belong to the budget.'); throw new FireflyException('20028: The budget limit does not belong to the budget.');
} }
$data = $request->getAll(); $data = $request->getAll();
$data['fire_webhooks'] = $data['fire_webhooks'] ?? true;
$data['budget_id'] = $budget->id; $data['budget_id'] = $budget->id;
$budgetLimit = $this->blRepository->update($budgetLimit, $data); $budgetLimit = $this->blRepository->update($budgetLimit, $data);
$manager = $this->getManager(); $manager = $this->getManager();

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit; namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use FireflyIII\Rules\IsBoolean;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
@@ -52,6 +53,9 @@ class UpdateRequest extends FormRequest
'currency_id' => ['currency_id', 'convertInteger'], 'currency_id' => ['currency_id', 'convertInteger'],
'currency_code' => ['currency_code', 'convertString'], 'currency_code' => ['currency_code', 'convertString'],
'notes' => ['notes', 'stringWithNewlines'], 'notes' => ['notes', 'stringWithNewlines'],
// webhooks
'fire_webhooks' => ['fire_webhooks','boolean']
]; ];
if (false === $this->has('notes')) { if (false === $this->has('notes')) {
// ignore notes, not submitted. // ignore notes, not submitted.
@@ -73,6 +77,9 @@ class UpdateRequest extends FormRequest
'currency_id' => 'numeric|exists:transaction_currencies,id', 'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code', 'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'notes' => 'nullable|min:0|max:32768', 'notes' => 'nullable|min:0|max:32768',
// webhooks
'fire_webhooks' => [new IsBoolean()],
]; ];
} }

View File

@@ -75,7 +75,7 @@ class BudgetLimitObserver
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($budgetLimit->budget->user->userGroup); $userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($budgetLimit->budget->user->userGroup);
$budgetLimit->native_amount = null; $budgetLimit->native_amount = null;
if ($budgetLimit->transactionCurrency->id !== $userCurrency->id) { if ($budgetLimit->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter(); $converter = new ExchangeRateConverter();
$converter->setUserGroup($budgetLimit->budget->user->userGroup); $converter->setUserGroup($budgetLimit->budget->user->userGroup);
$converter->setIgnoreSettings(true); $converter->setIgnoreSettings(true);
$budgetLimit->native_amount = $converter->convert($budgetLimit->transactionCurrency, $userCurrency, today(), $budgetLimit->amount); $budgetLimit->native_amount = $converter->convert($budgetLimit->transactionCurrency, $userCurrency, today(), $budgetLimit->amount);
@@ -90,16 +90,21 @@ class BudgetLimitObserver
$this->updatePrimaryCurrencyAmount($budgetLimit); $this->updatePrimaryCurrencyAmount($budgetLimit);
$this->updateAvailableBudget($budgetLimit); $this->updateAvailableBudget($budgetLimit);
$user = $budgetLimit->budget->user; // this is a lame trick to communicate with the observer.
$singleton = PreferencesSingleton::getInstance();
/** @var MessageGeneratorInterface $engine */ if (true === $singleton->getPreference('fire_webhooks_bl_update')) {
$engine = app(MessageGeneratorInterface::class); $user = $budgetLimit->budget->user;
$engine->setUser($user);
$engine->setObjects(new Collection()->push($budgetLimit));
$engine->setTrigger(WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT);
$engine->generateMessages();
Log::debug(sprintf('send event RequestedSendWebhookMessages from %s', __METHOD__)); /** @var MessageGeneratorInterface $engine */
event(new RequestedSendWebhookMessages()); $engine = app(MessageGeneratorInterface::class);
$engine->setUser($user);
$engine->setObjects(new Collection()->push($budgetLimit));
$engine->setTrigger(WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT);
$engine->generateMessages();
Log::debug(sprintf('send event RequestedSendWebhookMessages from %s', __METHOD__));
event(new RequestedSendWebhookMessages());
}
} }
} }

View File

@@ -375,11 +375,15 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface, UserGroup
} }
// catch unexpected null: // catch unexpected null:
if (null === $currency) { if (null === $currency) {
$currency = $budgetLimit->transactionCurrency ?? app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup); $currency = $budgetLimit->transactionCurrency ?? Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
} }
$currency->enabled = true; $currency->enabled = true;
$currency->save(); $currency->save();
// this is a lame trick to communicate with the observer.
$singleton = PreferencesSingleton::getInstance();
$singleton->setPreference('fire_webhooks_bl_update', $data['fire_webhooks'] ?? true);
$budgetLimit->transaction_currency_id = $currency->id; $budgetLimit->transaction_currency_id = $currency->id;
$budgetLimit->save(); $budgetLimit->save();
@@ -391,63 +395,63 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface, UserGroup
return $budgetLimit; return $budgetLimit;
} }
public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit // public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit
{ // {
// count the limits: // // count the limits:
$limits = $budget->budgetlimits() // $limits = $budget->budgetlimits()
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) // ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) // ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
->count('budget_limits.*') // ->count('budget_limits.*')
; // ;
Log::debug(sprintf('Found %d budget limits.', $limits)); // Log::debug(sprintf('Found %d budget limits.', $limits));
//
// there might be a budget limit for these dates: // // there might be a budget limit for these dates:
/** @var null|BudgetLimit $limit */ // /** @var null|BudgetLimit $limit */
$limit = $budget->budgetlimits() // $limit = $budget->budgetlimits()
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) // ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) // ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
->first(['budget_limits.*']) // ->first(['budget_limits.*'])
; // ;
//
// if more than 1 limit found, delete the others: // // if more than 1 limit found, delete the others:
if ($limits > 1 && null !== $limit) { // if ($limits > 1 && null !== $limit) {
Log::debug(sprintf('Found more than 1, delete all except #%d', $limit->id)); // Log::debug(sprintf('Found more than 1, delete all except #%d', $limit->id));
$budget->budgetlimits() // $budget->budgetlimits()
->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) // ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) // ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
->where('budget_limits.id', '!=', $limit->id)->delete() // ->where('budget_limits.id', '!=', $limit->id)->delete()
; // ;
} // }
//
// delete if amount is zero. // // delete if amount is zero.
// Returns 0 if the two operands are equal, // // Returns 0 if the two operands are equal,
// 1 if the left_operand is larger than the right_operand, -1 otherwise. // // 1 if the left_operand is larger than the right_operand, -1 otherwise.
if (null !== $limit && bccomp($amount, '0') <= 0) { // if (null !== $limit && bccomp($amount, '0') <= 0) {
Log::debug(sprintf('%s is zero, delete budget limit #%d', $amount, $limit->id)); // Log::debug(sprintf('%s is zero, delete budget limit #%d', $amount, $limit->id));
$limit->delete(); // $limit->delete();
//
return null; // return null;
} // }
// update if exists: // // update if exists:
if (null !== $limit) { // if (null !== $limit) {
Log::debug(sprintf('Existing budget limit is #%d, update this to amount %s', $limit->id, $amount)); // Log::debug(sprintf('Existing budget limit is #%d, update this to amount %s', $limit->id, $amount));
$limit->amount = $amount; // $limit->amount = $amount;
$limit->save(); // $limit->save();
//
return $limit; // return $limit;
} // }
Log::debug('No existing budget limit, create a new one'); // Log::debug('No existing budget limit, create a new one');
// or create one and return it. // // or create one and return it.
$limit = new BudgetLimit(); // $limit = new BudgetLimit();
$limit->budget()->associate($budget); // $limit->budget()->associate($budget);
$limit->start_date = $start->startOfDay(); // $limit->start_date = $start->startOfDay();
$limit->start_date_tz = $start->format('e'); // $limit->start_date_tz = $start->format('e');
$limit->end_date = $end->startOfDay(); // $limit->end_date = $end->startOfDay();
$limit->end_date_tz = $end->format('e'); // $limit->end_date_tz = $end->format('e');
$limit->amount = $amount; // $limit->amount = $amount;
$limit->save(); // $limit->save();
Log::debug(sprintf('Created new budget limit with ID #%d and amount %s', $limit->id, $amount)); // Log::debug(sprintf('Created new budget limit with ID #%d and amount %s', $limit->id, $amount));
//
return $limit; // return $limit;
} // }
} }

View File

@@ -81,5 +81,5 @@ interface BudgetLimitRepositoryInterface
public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit; public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit;
public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit; //public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit;
} }