From c2d3f5da16c56763b06a755191080dfa859f3394 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 14 Sep 2025 08:55:29 +0200 Subject: [PATCH] Allow budget store to have optional webhook using "fire_webhooks". --- .../Models/Budget/StoreController.php | 14 ++++---- .../Requests/Models/Budget/StoreRequest.php | 6 ++++ .../Models/Transaction/StoreRequest.php | 1 + app/Handlers/Observer/BudgetObserver.php | 34 +++++++++++-------- app/Repositories/Budget/BudgetRepository.php | 5 +++ app/Support/Request/ConvertsDataTypes.php | 6 ++++ 6 files changed, 46 insertions(+), 20 deletions(-) diff --git a/app/Api/V1/Controllers/Models/Budget/StoreController.php b/app/Api/V1/Controllers/Models/Budget/StoreController.php index b6d9e85e6c..3e4954f474 100644 --- a/app/Api/V1/Controllers/Models/Budget/StoreController.php +++ b/app/Api/V1/Controllers/Models/Budget/StoreController.php @@ -67,22 +67,24 @@ class StoreController extends Controller */ public function store(StoreRequest $request): JsonResponse { - $budget = $this->repository->store($request->getAll()); + $data = $request->getAll(); + $data['fire_webhooks'] = $data['fire_webhooks'] ?? true; + $budget = $this->repository->store($data); $budget->refresh(); - $manager = $this->getManager(); + $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/StoreRequest.php b/app/Api/V1/Requests/Models/Budget/StoreRequest.php index 9a0118406d..fc17d164dd 100644 --- a/app/Api/V1/Requests/Models/Budget/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Budget/StoreRequest.php @@ -59,6 +59,9 @@ class StoreRequest 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'] ]; return $this->getAllData($fields); @@ -79,6 +82,9 @@ class StoreRequest extends FormRequest 'auto_budget_type' => 'in:reset,rollover,adjusted,none', 'auto_budget_amount' => ['required_if:auto_budget_type,reset', 'required_if:auto_budget_type,rollover', 'required_if:auto_budget_type,adjusted', new IsValidPositiveAmount()], 'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted', + + // webhooks + 'fire_webhooks' => [new IsBoolean()], ]; } diff --git a/app/Api/V1/Requests/Models/Transaction/StoreRequest.php b/app/Api/V1/Requests/Models/Transaction/StoreRequest.php index a1a20fe4d1..6e85264031 100644 --- a/app/Api/V1/Requests/Models/Transaction/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Transaction/StoreRequest.php @@ -183,6 +183,7 @@ class StoreRequest extends FormRequest // basic fields for group: 'group_title' => 'min:1|max:1000|nullable', 'error_if_duplicate_hash' => [new IsBoolean()], + 'fire_webhooks' => [new IsBoolean()], 'apply_rules' => [new IsBoolean()], // location rules diff --git a/app/Handlers/Observer/BudgetObserver.php b/app/Handlers/Observer/BudgetObserver.php index d7366d3a4b..156946e917 100644 --- a/app/Handlers/Observer/BudgetObserver.php +++ b/app/Handlers/Observer/BudgetObserver.php @@ -31,6 +31,7 @@ use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use FireflyIII\Support\Observers\RecalculatesAvailableBudgetsTrait; +use FireflyIII\Support\Singleton\PreferencesSingleton; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; @@ -45,23 +46,28 @@ class BudgetObserver { Log::debug(sprintf('Observe "created" of budget #%d ("%s").', $budget->id, $budget->name)); - // fire event. - $user = $budget->user; + // this is a lame trick to communicate with the observer. + $singleton = PreferencesSingleton::getInstance(); - /** @var MessageGeneratorInterface $engine */ - $engine = app(MessageGeneratorInterface::class); - $engine->setUser($user); - $engine->setObjects(new Collection()->push($budget)); - $engine->setTrigger(WebhookTrigger::STORE_BUDGET); - $engine->generateMessages(); - Log::debug(sprintf('send event RequestedSendWebhookMessages from %s', __METHOD__)); - event(new RequestedSendWebhookMessages()); + if (true === $singleton->getPreference('fire_webhooks_budget_create')) { + // fire event. + $user = $budget->user; + + /** @var MessageGeneratorInterface $engine */ + $engine = app(MessageGeneratorInterface::class); + $engine->setUser($user); + $engine->setObjects(new Collection()->push($budget)); + $engine->setTrigger(WebhookTrigger::STORE_BUDGET); + $engine->generateMessages(); + Log::debug(sprintf('send event RequestedSendWebhookMessages from %s', __METHOD__)); + event(new RequestedSendWebhookMessages()); + } } public function updated(Budget $budget): void { Log::debug(sprintf('Observe "updated" of budget #%d ("%s").', $budget->id, $budget->name)); - $user = $budget->user; + $user = $budget->user; /** @var MessageGeneratorInterface $engine */ $engine = app(MessageGeneratorInterface::class); @@ -77,10 +83,10 @@ class BudgetObserver { Log::debug('Observe "deleting" of a budget.'); - $user = $budget->user; + $user = $budget->user; /** @var MessageGeneratorInterface $engine */ - $engine = app(MessageGeneratorInterface::class); + $engine = app(MessageGeneratorInterface::class); $engine->setUser($user); $engine->setObjects(new Collection()->push($budget)); $engine->setTrigger(WebhookTrigger::DESTROY_BUDGET); @@ -88,7 +94,7 @@ class BudgetObserver Log::debug(sprintf('send event RequestedSendWebhookMessages from %s', __METHOD__)); event(new RequestedSendWebhookMessages()); - $repository = app(AttachmentRepositoryInterface::class); + $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($budget->user); /** @var Attachment $attachment */ diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 3aa57328de..8c39398b69 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -44,6 +44,7 @@ use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface; use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; +use FireflyIII\Support\Singleton\PreferencesSingleton; use Illuminate\Database\QueryException; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; @@ -724,6 +725,10 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface { $order = $this->getMaxOrder(); + // this is a lame trick to communicate with the observer. + $singleton = PreferencesSingleton::getInstance(); + $singleton->setPreference('fire_webhooks_budget_create', $data['fire_webhooks'] ?? true); + try { $newBudget = Budget::create( [ diff --git a/app/Support/Request/ConvertsDataTypes.php b/app/Support/Request/ConvertsDataTypes.php index c90541b081..bc8da96efb 100644 --- a/app/Support/Request/ConvertsDataTypes.php +++ b/app/Support/Request/ConvertsDataTypes.php @@ -258,6 +258,12 @@ trait ConvertsDataTypes if ('yes' === $value) { return true; } + if ('on' === $value) { + return true; + } + if ('y' === $value) { + return true; + } if ('1' === $value) { return true; }