diff --git a/app/Api/V1/Controllers/Models/Budget/UpdateController.php b/app/Api/V1/Controllers/Models/Budget/UpdateController.php index b6524ba738..8ec009b7e1 100644 --- a/app/Api/V1/Controllers/Models/Budget/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Budget/UpdateController.php @@ -57,30 +57,25 @@ class UpdateController extends Controller ); } - /** - * This endpoint is documented at: - * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudget - * - * Update a budget. - */ public function update(UpdateRequest $request, Budget $budget): JsonResponse { - $data = $request->getAll(); - $budget = $this->repository->update($budget, $data); - $manager = $this->getManager(); + $data = $request->getAll(); + $data['fire_webhooks'] = $data['fire_webhooks'] ?? true; + $budget = $this->repository->update($budget, $data); + $manager = $this->getManager(); // enrich /** @var User $admin */ - $admin = auth()->user(); - $enrichment = new BudgetEnrichment(); + $admin = auth()->user(); + $enrichment = new BudgetEnrichment(); $enrichment->setUser($admin); - $budget = $enrichment->enrichSingle($budget); + $budget = $enrichment->enrichSingle($budget); /** @var BudgetTransformer $transformer */ $transformer = app(BudgetTransformer::class); $transformer->setParameters($this->parameters); - $resource = new Item($budget, $transformer, 'budgets'); + $resource = new Item($budget, $transformer, 'budgets'); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } diff --git a/app/Api/V1/Requests/Models/Budget/UpdateRequest.php b/app/Api/V1/Requests/Models/Budget/UpdateRequest.php index 6eb0dc7acc..3a89dbaa15 100644 --- a/app/Api/V1/Requests/Models/Budget/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Budget/UpdateRequest.php @@ -59,6 +59,9 @@ class UpdateRequest extends FormRequest 'auto_budget_type' => ['auto_budget_type', 'convertString'], 'auto_budget_amount' => ['auto_budget_amount', 'convertString'], 'auto_budget_period' => ['auto_budget_period', 'convertString'], + + // webhooks + 'fire_webhooks' => ['fire_webhooks','boolean'] ]; $allData = $this->getAllData($fields); if (array_key_exists('auto_budget_type', $allData)) { @@ -91,6 +94,9 @@ class UpdateRequest extends FormRequest 'auto_budget_currency_code' => 'exists:transaction_currencies,code', 'auto_budget_amount' => ['nullable', new IsValidPositiveAmount()], 'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly', + + // webhooks + 'fire_webhooks' => [new IsBoolean()], ]; } diff --git a/app/Handlers/Observer/BudgetObserver.php b/app/Handlers/Observer/BudgetObserver.php index 156946e917..9030c4f955 100644 --- a/app/Handlers/Observer/BudgetObserver.php +++ b/app/Handlers/Observer/BudgetObserver.php @@ -67,16 +67,22 @@ class BudgetObserver public function updated(Budget $budget): void { Log::debug(sprintf('Observe "updated" of budget #%d ("%s").', $budget->id, $budget->name)); - $user = $budget->user; - /** @var MessageGeneratorInterface $engine */ - $engine = app(MessageGeneratorInterface::class); - $engine->setUser($user); - $engine->setObjects(new Collection()->push($budget)); - $engine->setTrigger(WebhookTrigger::UPDATE_BUDGET); - $engine->generateMessages(); - Log::debug(sprintf('send event RequestedSendWebhookMessages from %s', __METHOD__)); - event(new RequestedSendWebhookMessages()); + // this is a lame trick to communicate with the observer. + $singleton = PreferencesSingleton::getInstance(); + + if (true === $singleton->getPreference('fire_webhooks_budget_update')) { + $user = $budget->user; + + /** @var MessageGeneratorInterface $engine */ + $engine = app(MessageGeneratorInterface::class); + $engine->setUser($user); + $engine->setObjects(new Collection()->push($budget)); + $engine->setTrigger(WebhookTrigger::UPDATE_BUDGET); + $engine->generateMessages(); + Log::debug(sprintf('send event RequestedSendWebhookMessages from %s', __METHOD__)); + event(new RequestedSendWebhookMessages()); + } } public function deleting(Budget $budget): void diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 8c39398b69..b893334320 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -86,7 +86,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface public function budgetedInPeriod(Carbon $start, Carbon $end): array { - app('log')->debug(sprintf('Now in budgetedInPeriod("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d'))); + Log::debug(sprintf('Now in budgetedInPeriod("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d'))); $return = []; /** @var BudgetLimitRepository $limitRepository */ @@ -98,12 +98,12 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface /** @var Budget $budget */ foreach ($budgets as $budget) { - app('log')->debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name)); + Log::debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name)); $limits = $limitRepository->getBudgetLimits($budget, $start, $end); /** @var BudgetLimit $limit */ foreach ($limits as $limit) { - app('log')->debug(sprintf('Budget limit #%d', $limit->id)); + Log::debug(sprintf('Budget limit #%d', $limit->id)); $currency = $limit->transactionCurrency; $rate = $converter->getCurrencyRate($currency, $primaryCurrency, $end); $currencyCode = $currency->code; @@ -125,7 +125,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)) { $return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], (string) $limit->amount); $return[$currencyCode]['pc_sum'] = bcmul($rate, $return[$currencyCode]['sum']); - app('log')->debug(sprintf('Add full amount [1]: %s', $limit->amount)); + Log::debug(sprintf('Add full amount [1]: %s', $limit->amount)); continue; } @@ -133,7 +133,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface if ($start->lte($limit->start_date) && $end->gte($limit->end_date)) { $return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], (string) $limit->amount); $return[$currencyCode]['pc_sum'] = bcmul($rate, $return[$currencyCode]['sum']); - app('log')->debug(sprintf('Add full amount [2]: %s', $limit->amount)); + Log::debug(sprintf('Add full amount [2]: %s', $limit->amount)); continue; } @@ -142,7 +142,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface $amount = bcmul(bcdiv((string) $limit->amount, (string) $total), (string) $days); $return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], $amount); $return[$currencyCode]['pc_sum'] = bcmul($rate, $return[$currencyCode]['sum']); - app('log')->debug( + Log::debug( sprintf( 'Amount per day: %s (%s over %d days). Total amount for %d days: %s', bcdiv((string) $limit->amount, (string) $total), @@ -203,19 +203,19 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface public function budgetedInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array { - app('log')->debug(sprintf('Now in budgetedInPeriod(#%d, "%s", "%s")', $budget->id, $start->format('Y-m-d'), $end->format('Y-m-d'))); + Log::debug(sprintf('Now in budgetedInPeriod(#%d, "%s", "%s")', $budget->id, $start->format('Y-m-d'), $end->format('Y-m-d'))); $return = []; /** @var BudgetLimitRepository $limitRepository */ $limitRepository = app(BudgetLimitRepository::class); $limitRepository->setUser($this->user); - app('log')->debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name)); + Log::debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name)); $limits = $limitRepository->getBudgetLimits($budget, $start, $end); /** @var BudgetLimit $limit */ foreach ($limits as $limit) { - app('log')->debug(sprintf('Budget limit #%d', $limit->id)); + Log::debug(sprintf('Budget limit #%d', $limit->id)); $currency = $limit->transactionCurrency; $return[$currency->id] ??= [ 'id' => (string) $currency->id, @@ -228,14 +228,14 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface // same period if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)) { $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], (string) $limit->amount); - app('log')->debug(sprintf('Add full amount [1]: %s', $limit->amount)); + Log::debug(sprintf('Add full amount [1]: %s', $limit->amount)); continue; } // limit is inside of date range if ($start->lte($limit->start_date) && $end->gte($limit->end_date)) { $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], (string) $limit->amount); - app('log')->debug(sprintf('Add full amount [2]: %s', $limit->amount)); + Log::debug(sprintf('Add full amount [2]: %s', $limit->amount)); continue; } @@ -243,7 +243,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface $days = $this->daysInOverlap($limit, $start, $end); $amount = bcmul(bcdiv((string) $limit->amount, (string) $total), (string) $days); $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $amount); - app('log')->debug( + Log::debug( sprintf( 'Amount per day: %s (%s over %d days). Total amount for %d days: %s', bcdiv((string) $limit->amount, (string) $total), @@ -283,7 +283,11 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface */ public function update(Budget $budget, array $data): Budget { - app('log')->debug('Now in update()'); + Log::debug('Now in update()'); + + // this is a lame trick to communicate with the observer. + $singleton = PreferencesSingleton::getInstance(); + $singleton->setPreference('fire_webhooks_budget_update', $data['fire_webhooks'] ?? true); $oldName = $budget->name; if (array_key_exists('name', $data)) { @@ -331,13 +335,13 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface ->where('rule_actions.action_value', $oldName) ->get(['rule_actions.*']) ; - app('log')->debug(sprintf('Found %d actions to update.', $actions->count())); + Log::debug(sprintf('Found %d actions to update.', $actions->count())); /** @var RuleAction $action */ foreach ($actions as $action) { $action->action_value = $newName; $action->save(); - app('log')->debug(sprintf('Updated action %d: %s', $action->id, $action->action_value)); + Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value)); } } @@ -350,13 +354,13 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface ->where('rule_triggers.trigger_value', $oldName) ->get(['rule_triggers.*']) ; - app('log')->debug(sprintf('Found %d triggers to update.', $triggers->count())); + Log::debug(sprintf('Found %d triggers to update.', $triggers->count())); /** @var RuleTrigger $trigger */ foreach ($triggers as $trigger) { $trigger->trigger_value = $newName; $trigger->save(); - app('log')->debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value)); + Log::debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value)); } } @@ -487,17 +491,17 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface public function findBudget(?int $budgetId, ?string $budgetName): ?Budget { - app('log')->debug('Now in findBudget()'); - app('log')->debug(sprintf('Searching for budget with ID #%d...', $budgetId)); + Log::debug('Now in findBudget()'); + Log::debug(sprintf('Searching for budget with ID #%d...', $budgetId)); $result = $this->find((int) $budgetId); if (!$result instanceof Budget && null !== $budgetName && '' !== $budgetName) { - app('log')->debug(sprintf('Searching for budget with name %s...', $budgetName)); + Log::debug(sprintf('Searching for budget with name %s...', $budgetName)); $result = $this->findByName($budgetName); } if ($result instanceof Budget) { - app('log')->debug(sprintf('Found budget #%d: %s', $result->id, $result->name)); + Log::debug(sprintf('Found budget #%d: %s', $result->id, $result->name)); } - app('log')->debug(sprintf('Found result is null? %s', var_export(!$result instanceof Budget, true))); + Log::debug(sprintf('Found result is null? %s', var_export(!$result instanceof Budget, true))); return $result; } @@ -594,7 +598,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface public function spentInPeriod(Carbon $start, Carbon $end): array { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $start->startOfDay(); $end->endOfDay(); @@ -656,7 +660,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface public function spentInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $start->startOfDay(); $end->endOfDay(); @@ -740,8 +744,8 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface ] ); } catch (QueryException $e) { - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException('400002: Could not store budget.', 0, $e); }