From 0acd07405bc9bb172e6e7f58cc376a701d3cf508 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 19 Dec 2025 16:30:39 +0100 Subject: [PATCH] Fix #11388 --- .../Commands/Correction/CorrectsAmounts.php | 4 ++ .../Correction/CorrectsUnevenAmount.php | 28 ++------ .../Upgrade/RemovesDatabaseDecryption.php | 7 +- .../Upgrade/RepairsAccountBalances.php | 2 +- .../Upgrade/UpgradesLiabilitiesEight.php | 65 +++++++++---------- .../Account/AccountRepository.php | 5 -- .../Account/AccountRepositoryInterface.php | 1 - app/Support/Balance.php | 1 + .../Models/AccountBalanceCalculator.php | 2 +- 9 files changed, 45 insertions(+), 70 deletions(-) diff --git a/app/Console/Commands/Correction/CorrectsAmounts.php b/app/Console/Commands/Correction/CorrectsAmounts.php index c46880bf8d..b140344b17 100644 --- a/app/Console/Commands/Correction/CorrectsAmounts.php +++ b/app/Console/Commands/Correction/CorrectsAmounts.php @@ -100,6 +100,10 @@ class CorrectsAmounts extends Command if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) { continue; } + if(null === $source->foreign_amount || null === $destination->foreign_amount) { + continue; + } + $sourceAccount = $source->account; $destAccount = $destination->account; if (null === $sourceAccount || null === $destAccount) { diff --git a/app/Console/Commands/Correction/CorrectsUnevenAmount.php b/app/Console/Commands/Correction/CorrectsUnevenAmount.php index 31f81ca19b..d96f2b6599 100644 --- a/app/Console/Commands/Correction/CorrectsUnevenAmount.php +++ b/app/Console/Commands/Correction/CorrectsUnevenAmount.php @@ -132,11 +132,7 @@ class CorrectsUnevenAmount extends Command private function fixUnevenAmounts(): void { Log::debug('fixUnevenAmounts()'); - $journals = DB::table('transactions') - ->groupBy('transaction_journal_id') - ->whereNull('deleted_at') - ->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]) - ; + $journals = DB::table('transactions')->groupBy('transaction_journal_id')->whereNull('deleted_at')->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]); /** @var stdClass $entry */ foreach ($journals as $entry) { @@ -146,11 +142,7 @@ class CorrectsUnevenAmount extends Command || '' === $sum // @phpstan-ignore-line || str_contains($sum, 'e') || str_contains($sum, ',')) { - $message = sprintf( - 'Journal #%d has an invalid sum ("%s"). No sure what to do.', - $entry->transaction_journal_id, - $entry->the_sum - ); + $message = sprintf('Journal #%d has an invalid sum ("%s"). No sure what to do.', $entry->transaction_journal_id, $entry->the_sum); $this->friendlyWarning($message); Log::warning($message); ++$this->count; @@ -184,13 +176,7 @@ class CorrectsUnevenAmount extends Command $source = $journal->transactions()->where('amount', '<', 0)->first(); if (null === $source) { - $this->friendlyError( - sprintf( - 'Journal #%d ("%s") has no source transaction. It will be deleted to maintain database consistency.', - $journal->id ?? 0, - $journal->description ?? '' - ) - ); + $this->friendlyError(sprintf('Journal #%d ("%s") has no source transaction. It will be deleted to maintain database consistency.', $journal->id ?? 0, $journal->description ?? '')); Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete(); TransactionJournal::where('id', $journal->id ?? 0)->forceDelete(); ++$this->count; @@ -205,13 +191,7 @@ class CorrectsUnevenAmount extends Command $destination = $journal->transactions()->where('amount', '>', 0)->first(); if (null === $destination) { - $this->friendlyError( - sprintf( - 'Journal #%d ("%s") has no destination transaction. It will be deleted to maintain database consistency.', - $journal->id ?? 0, - $journal->description ?? '' - ) - ); + $this->friendlyError(sprintf('Journal #%d ("%s") has no destination transaction. It will be deleted to maintain database consistency.', $journal->id ?? 0, $journal->description ?? '')); Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete(); TransactionJournal::where('id', $journal->id ?? 0)->forceDelete(); diff --git a/app/Console/Commands/Upgrade/RemovesDatabaseDecryption.php b/app/Console/Commands/Upgrade/RemovesDatabaseDecryption.php index 03070692ef..6ef235f0be 100644 --- a/app/Console/Commands/Upgrade/RemovesDatabaseDecryption.php +++ b/app/Console/Commands/Upgrade/RemovesDatabaseDecryption.php @@ -34,7 +34,6 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use JsonException; use stdClass; - use function Safe\json_decode; class RemovesDatabaseDecryption extends Command @@ -120,8 +119,8 @@ class RemovesDatabaseDecryption extends Command if (null === $original) { return; } - $id = (int) $row->id; - $value = ''; + $id = (int)$row->id; + $value = ''; try { $value = $this->tryDecrypt($original); @@ -133,7 +132,7 @@ class RemovesDatabaseDecryption extends Command } // A separate routine for preferences table: - if ('preferences' === $table) { + if ('preferences' === $table && is_string($value)) { $this->decryptPreferencesRow($id, $value); return; diff --git a/app/Console/Commands/Upgrade/RepairsAccountBalances.php b/app/Console/Commands/Upgrade/RepairsAccountBalances.php index 1e35520f09..3282b2f00f 100644 --- a/app/Console/Commands/Upgrade/RepairsAccountBalances.php +++ b/app/Console/Commands/Upgrade/RepairsAccountBalances.php @@ -1,7 +1,7 @@ accounts() - ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') - ->whereIn('account_types.type', config('firefly.valid_liabilities')) - ->get(['accounts.*']) - ; + ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') + ->whereIn('account_types.type', config('firefly.valid_liabilities')) + ->get(['accounts.*']); /** @var Account $account */ foreach ($accounts as $account) { @@ -102,7 +101,7 @@ class UpgradesLiabilitiesEight extends Command $repository = app(AccountRepositoryInterface::class); $repository->setUser($account->user); - $direction = $repository->getMetaValue($account, 'liability_direction'); + $direction = $repository->getMetaValue($account, 'liability_direction'); if ('credit' === $direction && $this->hasBadOpening($account)) { $this->deleteCreditTransaction($account); $this->reverseOpeningBalance($account); @@ -121,34 +120,31 @@ class UpgradesLiabilitiesEight extends Command $openingBalanceType = TransactionType::whereType(TransactionTypeEnum::OPENING_BALANCE->value)->first(); $liabilityType = TransactionType::whereType(TransactionTypeEnum::LIABILITY_CREDIT->value)->first(); $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) - ->first(['transaction_journals.*']) - ; + ->where('transactions.account_id', $account->id) + ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) + ->first(['transaction_journals.*']); if (null === $openingJournal) { return false; } - $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.transaction_type_id', $liabilityType->id) - ->first(['transaction_journals.*']) - ; + $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id) + ->where('transaction_journals.transaction_type_id', $liabilityType->id) + ->first(['transaction_journals.*']); if (null === $liabilityJournal) { return false; } - return (bool) $openingJournal->date->isSameDay($liabilityJournal->date); + return (bool)$openingJournal->date->isSameDay($liabilityJournal->date); } private function deleteCreditTransaction(Account $account): void { $liabilityType = TransactionType::whereType(TransactionTypeEnum::LIABILITY_CREDIT->value)->first(); $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.transaction_type_id', $liabilityType->id) - ->first(['transaction_journals.*']) - ; - if (null !== $liabilityJournal) { + ->where('transactions.account_id', $account->id) + ->where('transaction_journals.transaction_type_id', $liabilityType->id) + ->first(['transaction_journals.*']); + if (null !== $liabilityJournal && null !== $liabilityJournal->transactionGroup) { $group = $liabilityJournal->transactionGroup; $service = new TransactionGroupDestroyService(); $service->destroy($group); @@ -161,17 +157,16 @@ class UpgradesLiabilitiesEight extends Command $openingBalanceType = TransactionType::whereType(TransactionTypeEnum::OPENING_BALANCE->value)->first(); /** @var TransactionJournal $openingJournal */ - $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) - ->first(['transaction_journals.*']) - ; + $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id) + ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) + ->first(['transaction_journals.*']); /** @var null|Transaction $source */ - $source = $openingJournal->transactions()->where('amount', '<', 0)->first(); + $source = $openingJournal->transactions()->where('amount', '<', 0)->first(); /** @var null|Transaction $dest */ - $dest = $openingJournal->transactions()->where('amount', '>', 0)->first(); + $dest = $openingJournal->transactions()->where('amount', '>', 0)->first(); if (null !== $source && null !== $dest) { $sourceId = $source->account_id; $destId = $dest->account_id; @@ -189,14 +184,16 @@ class UpgradesLiabilitiesEight extends Command { $count = 0; $journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transactions.account_id', $account->id)->get(['transaction_journals.*']) - ; + ->where('transactions.account_id', $account->id)->get(['transaction_journals.*']); + + $service = app(TransactionGroupDestroyService::class); /** @var TransactionJournal $journal */ foreach ($journals as $journal) { - $service = app(TransactionGroupDestroyService::class); - $service->destroy($journal->transactionGroup); - ++$count; + if (null !== $journal->transactionGroup) { + $service->destroy($journal->transactionGroup); + ++$count; + } } return $count; diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index 546953a8c8..14d61f3791 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -167,11 +167,6 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac return $account; } - #[Override] - public function getAccountBalances(Account $account): Collection - { - return $account->accountBalances; - } /** * Return account type or null if not found. diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php index 3a16896695..97a0e69c03 100644 --- a/app/Repositories/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Account/AccountRepositoryInterface.php @@ -71,7 +71,6 @@ interface AccountRepositoryInterface public function findByName(string $name, array $types): ?Account; - public function getAccountBalances(Account $account): Collection; public function getAccountCurrency(Account $account): ?TransactionCurrency; diff --git a/app/Support/Balance.php b/app/Support/Balance.php index 0a9a97d0ee..2c400e7c81 100644 --- a/app/Support/Balance.php +++ b/app/Support/Balance.php @@ -34,6 +34,7 @@ class Balance { /** * Returns the accounts balances as an array, on the account ID. + * @deprecated */ public function getAccountBalances(Collection $accounts, Carbon $date): array { diff --git a/app/Support/Models/AccountBalanceCalculator.php b/app/Support/Models/AccountBalanceCalculator.php index 5675f92adc..a828eead5b 100644 --- a/app/Support/Models/AccountBalanceCalculator.php +++ b/app/Support/Models/AccountBalanceCalculator.php @@ -161,7 +161,7 @@ class AccountBalanceCalculator // then update all transactions. // save all collected balances in their respective account objects. - $this->storeAccountBalances($balances); + // $this->storeAccountBalances($balances); } private function storeAccountBalances(array $balances): void