From b70c0e4ab384a7bd1104a6ca3426dea22aa78bf0 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 21:01:23 +0200 Subject: [PATCH] Add some piggy bank events. --- app/Factory/PiggyBankFactory.php | 82 +++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php index 068cd0841a..b1cdbaaabe 100644 --- a/app/Factory/PiggyBankFactory.php +++ b/app/Factory/PiggyBankFactory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Factory; +use FireflyIII\Events\Model\PiggyBank\ChangedAmount; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\TransactionCurrency; @@ -67,7 +68,7 @@ class PiggyBankFactory public function store(array $data): PiggyBank { - $piggyBankData = $data; + $piggyBankData = $data; // unset some fields unset($piggyBankData['object_group_title'], $piggyBankData['transaction_currency_code'], $piggyBankData['transaction_currency_id'], $piggyBankData['accounts'], $piggyBankData['object_group_id'], $piggyBankData['notes']); @@ -91,11 +92,11 @@ class PiggyBankFactory throw new FireflyException('400005: Could not store new piggy bank.', 0, $e); } - $piggyBank = $this->setOrder($piggyBank, $data); + $piggyBank = $this->setOrder($piggyBank, $data); $this->linkToAccountIds($piggyBank, $data['accounts']); $this->piggyBankRepository->updateNote($piggyBank, $data['notes']); - $objectGroupTitle = $data['object_group_title'] ?? ''; + $objectGroupTitle = $data['object_group_title'] ?? ''; if ('' !== $objectGroupTitle) { $objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle); if (null !== $objectGroup) { @@ -103,7 +104,7 @@ class PiggyBankFactory } } // try also with ID - $objectGroupId = (int) ($data['object_group_id'] ?? 0); + $objectGroupId = (int) ($data['object_group_id'] ?? 0); if (0 !== $objectGroupId) { $objectGroup = $this->findObjectGroupById($objectGroupId); if (null !== $objectGroup) { @@ -111,7 +112,7 @@ class PiggyBankFactory } } Log::debug('Touch piggy bank'); - $piggyBank->encrypted = false; + $piggyBank->encrypted = false; $piggyBank->save(); $piggyBank->touch(); @@ -144,11 +145,10 @@ class PiggyBankFactory // first find by ID: if ($piggyBankId > 0) { $piggyBank = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.id', $piggyBankId) - ->first(['piggy_banks.*']) - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.id', $piggyBankId) + ->first(['piggy_banks.*']); if (null !== $piggyBank) { return $piggyBank; } @@ -169,17 +169,16 @@ class PiggyBankFactory public function findByName(string $name): ?PiggyBank { return PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.name', $name) - ->first(['piggy_banks.*']) - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.name', $name) + ->first(['piggy_banks.*']); } private function setOrder(PiggyBank $piggyBank, array $data): PiggyBank { $this->resetOrder(); - $order = $this->getMaxOrder() + 1; + $order = $this->getMaxOrder() + 1; if (array_key_exists('order', $data)) { $order = $data['order']; } @@ -194,15 +193,14 @@ class PiggyBankFactory { // TODO duplicate code $set = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->with( - [ - 'objectGroups', - ] - ) - ->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']) - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->with( + [ + 'objectGroups', + ] + ) + ->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']); $current = 1; foreach ($set as $piggyBank) { if ($piggyBank->order !== $current) { @@ -237,20 +235,45 @@ class PiggyBankFactory } } - /** @var array $info */ foreach ($accounts as $info) { $account = $this->accountRepository->find((int) ($info['account_id'] ?? 0)); if (null === $account) { + Log::debug(sprintf('Account #%d not found, skipping.', (int) ($info['account_id'] ?? 0))); continue; } if (array_key_exists('current_amount', $info) && null !== $info['current_amount']) { + // an amount is set, first check out if there is a difference with the previous amount. + $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; + $diff = bcsub($info['current_amount'], $previous); + + // create event for difference. + if (0 !== bccomp($diff, '0')) { + Log::debug(sprintf('[a] Will save event for difference %s (previous value was %s)', $diff, $previous)); + event(new ChangedAmount($piggyBank, $diff, null, null)); + } + $toBeLinked[$account->id] = ['current_amount' => $info['current_amount']]; Log::debug(sprintf('[a] Will link account #%d with amount %s', $account->id, $info['current_amount'])); } if (array_key_exists('current_amount', $info) && null === $info['current_amount']) { + // an amount is set, first check out if there is a difference with the previous amount. + $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; + $diff = bcsub('0', $previous); + + // create event for difference. + if (0 !== bccomp($diff, '0')) { + Log::debug(sprintf('[b] Will save event for difference %s (previous value was %s)', $diff, $previous)); + event(new ChangedAmount($piggyBank, $diff, null, null)); + } + + // no amount set, use previous amount or go to ZERO. $toBeLinked[$account->id] = ['current_amount' => $toBeLinked[$account->id]['current_amount'] ?? '0']; Log::debug(sprintf('[b] Will link account #%d with amount %s', $account->id, $toBeLinked[$account->id]['current_amount'] ?? '0')); + + // create event: + Log::debug('linkToAccountIds: Trigger change for positive amount [b].'); + event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'], null, null)); } if (!array_key_exists('current_amount', $info)) { $toBeLinked[$account->id] ??= []; @@ -258,6 +281,11 @@ class PiggyBankFactory } } Log::debug(sprintf('Link information: %s', json_encode($toBeLinked))); - $piggyBank->accounts()->sync($toBeLinked); + if (0 !== count($toBeLinked)) { + $piggyBank->accounts()->sync($toBeLinked); + } + if (0 === count($toBeLinked)) { + Log::warning('No accounts to link to piggy bank, will not change whatever is there now.'); + } } }