From 1f9e0b48c97e6f9873416100a66d8ea9309ca14e Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 15 Jan 2023 06:58:09 +0100 Subject: [PATCH 1/6] Fix withdrawals away from liabilities, cleanup debug logs --- .../Support/CreditRecalculateService.php | 71 ++++++++++++++----- .../Bulk/ValidatesBulkTransactionQuery.php | 2 +- changelog.md | 2 +- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/app/Services/Internal/Support/CreditRecalculateService.php b/app/Services/Internal/Support/CreditRecalculateService.php index c37dbf181d..365209035d 100644 --- a/app/Services/Internal/Support/CreditRecalculateService.php +++ b/app/Services/Internal/Support/CreditRecalculateService.php @@ -202,6 +202,8 @@ class CreditRecalculateService /** @var AccountMetaFactory $factory */ $factory = app(AccountMetaFactory::class); + + // amount is positive or negative, doesn't matter. $factory->crud($account, 'start_of_debt', $startOfDebt); // get direction of liability: @@ -209,6 +211,8 @@ class CreditRecalculateService // now loop all transactions (except opening balance and credit thing) $transactions = $account->transactions()->get(); + Log::debug(sprintf('Going to process %d transaction(s)', $transactions->count())); + Log::debug(sprintf('Account currency is #%d (%s)', $account->id, $this->repository->getAccountCurrency($account)?->code)); /** @var Transaction $transaction */ foreach ($transactions as $transaction) { $leftOfDebt = $this->processTransaction($account, $direction, $transaction, $leftOfDebt); @@ -226,32 +230,39 @@ class CreditRecalculateService * * @return string */ - private function processTransaction(Account $account, string $direction, Transaction $transaction, string $amount): string + private function processTransaction(Account $account, string $direction, Transaction $transaction, string $leftOfDebt): string { - Log::debug(sprintf('Now in %s(#%d, %s)', __METHOD__, $transaction->id, $amount)); + Log::debug(sprintf('Now in processTransaction(#%d, %s)', $transaction->id, $leftOfDebt)); $journal = $transaction->transactionJournal; $foreignCurrency = $transaction->foreignCurrency; $accountCurrency = $this->repository->getAccountCurrency($account); $groupId = $journal->transaction_group_id; $type = $journal->transactionType->type; - - Log::debug(sprintf('Account currency is #%d (%s)', $accountCurrency->id, $accountCurrency->code)); + /** @var Transaction $destTransaction */ + $destTransaction = $journal->transactions()->where('amount', '>', '0')->first(); + /** @var Transaction $sourceTransaction */ + $sourceTransaction = $journal->transactions()->where('amount', '<', '0')->first(); if ('' === $direction) { Log::debug('Since direction is "", do nothing.'); - return $amount; + return $leftOfDebt; } + if (TransactionType::LIABILITY_CREDIT === $type || TransactionType::OPENING_BALANCE === $type) { + Log::debug(sprintf('Skip group #%d, journal #%d of type "%s"', $journal->id, $groupId, $type)); + return $leftOfDebt; + } + // amount to use depends on the currency: $usedAmount = $transaction->amount; if (null !== $foreignCurrency && $foreignCurrency->id === $accountCurrency->id) { $usedAmount = $transaction->foreign_amount; - Log::debug('Will now use foreign amount!'); + Log::debug('Will use foreign amount to match account currency.'); } - Log::debug(sprintf('Processing group #%d, journal #%d of type "%s"', $journal->id, $groupId, $type)); + // Case 1 // it's a withdrawal into this liability (from asset). // if it's a credit ("I am owed"), this increases the amount due, // because we're lending person X more money @@ -261,13 +272,33 @@ class CreditRecalculateService && 1 === bccomp($usedAmount, '0') && 'credit' === $direction ) { - $amount = bcadd($amount, app('steam')->positive($usedAmount)); - Log::debug( - sprintf('Is withdrawal (%s) into credit liability #%d, will increase amount due to %s.', $transaction->account_id, $usedAmount, $amount) - ); - return $amount; + $newLeftOfDebt = bcadd($leftOfDebt, app('steam')->positive($usedAmount)); + Log::debug(sprintf('[1] Is withdrawal (%s) into liability, left of debt = %s.', $usedAmount, $newLeftOfDebt)); + return $newLeftOfDebt; } + // Case 2 + // it's a withdrawal away from this liability (into expense account). + // if it's a credit ("I am owed"), this decreases the amount due, + // because we're sending money away from the loan (like loan forgiveness) + if ( + $type === TransactionType::WITHDRAWAL + && (int)$account->id === (int)$sourceTransaction->account_id + && -1 === bccomp($usedAmount, '0') + && 'credit' === $direction + ) { + $newLeftOfDebt = bcsub($leftOfDebt, app('steam')->positive($usedAmount)); + Log::debug( + sprintf( + '[2] Is withdrawal (%s) away from liability, left of debt = %s.', + $usedAmount, + $newLeftOfDebt + ) + ); + return $newLeftOfDebt; + } + + // case 3 // it's a deposit out of this liability (to asset). // if it's a credit ("I am owed") this decreases the amount due. // because the person is paying us back. @@ -277,17 +308,21 @@ class CreditRecalculateService && -1 === bccomp($usedAmount, '0') && 'credit' === $direction ) { - $amount = bcsub($amount, app('steam')->positive($usedAmount)); - Log::debug(sprintf('Is deposit (%s) from credit liability #%d, will decrease amount due to %s.', $transaction->account_id, $usedAmount, $amount)); - return $amount; + $newLeftOfDebt = bcsub($leftOfDebt, app('steam')->positive($usedAmount)); + Log::debug(sprintf('[3] Is deposit (%s) away from liability, left of debt = %s.', $usedAmount, $newLeftOfDebt)); + return $newLeftOfDebt; } + // in any other case, remove amount from left of debt. if (in_array($type, [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER], true)) { - $amount = bcadd($amount, bcmul($usedAmount, '-1')); + $newLeftOfDebt = bcadd($leftOfDebt, bcmul($usedAmount, '-1')); + Log::debug(sprintf('[4] transaction is withdrawal/deposit/transfer, remove amount %s from left of debt, = %s.', $usedAmount, $newLeftOfDebt)); + return $newLeftOfDebt; } - Log::debug(sprintf('Amount is now %s', $amount)); - return $amount; + Log::warning(sprintf('[5] Catch-all, should not happen. Left of debt = %s', $leftOfDebt)); + + return $leftOfDebt; } /** diff --git a/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php index 85c823ea1e..f73add54e0 100644 --- a/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php +++ b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php @@ -71,7 +71,7 @@ trait ValidatesBulkTransactionQuery // must have same currency: // some account types (like expenses) do not have currency, so they have to be omitted $sourceCurrency = $repository->getAccountCurrency($source); - $destCurrency = $repository->getAccountCurrency($dest); + $destCurrency = $repository->getAccountCurrency($dest); if ( $sourceCurrency !== null && $destCurrency !== null diff --git a/changelog.md b/changelog.md index 580409fe2f..ad9e2b2a64 100644 --- a/changelog.md +++ b/changelog.md @@ -6,7 +6,7 @@ Alpha 2 - Data import: when you submit a transaction but give the ID of an account of the wrong type, Firefly III will try to create an account of the right type. For example: you submit a deposit but the source account is an expense account: Firefly III will try to create a revenue account instead. -- Security: blocked users can access API, users can unblock themselves using the API. +- Security: blocked users can access API, users can unblock themselves using the API. Recurrent Nymph CVE-2023-0298 - New language: catalan ## 5.8.0-alpha.1 - 2023-01-08 From 7111aec101d904209a76cbb1f2eeeb7b4006ebcb Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 15 Jan 2023 07:20:58 +0100 Subject: [PATCH 2/6] Make sure edit of liability always works. --- app/Http/Requests/AccountFormRequest.php | 3 ++- .../Internal/Update/AccountUpdateService.php | 5 +++++ public/v1/js/ff/accounts/edit.js | 16 ++++++++++++++++ resources/lang/en_US/firefly.php | 4 +++- resources/views/accounts/edit.twig | 6 +++++- 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/app/Http/Requests/AccountFormRequest.php b/app/Http/Requests/AccountFormRequest.php index b9281b9d0a..78b5342eb1 100644 --- a/app/Http/Requests/AccountFormRequest.php +++ b/app/Http/Requests/AccountFormRequest.php @@ -82,7 +82,8 @@ class AccountFormRequest extends FormRequest $data['account_type_name'] = null; $data['account_type_id'] = $this->convertInteger('liability_type_id'); if ('' !== $data['opening_balance']) { - $data['opening_balance'] = app('steam')->negative($data['opening_balance']); + // opening balance is always positive for liabilities + $data['opening_balance'] = app('steam')->positive($data['opening_balance']); } } diff --git a/app/Services/Internal/Update/AccountUpdateService.php b/app/Services/Internal/Update/AccountUpdateService.php index 38800d8d34..e990a7d8c4 100644 --- a/app/Services/Internal/Update/AccountUpdateService.php +++ b/app/Services/Internal/Update/AccountUpdateService.php @@ -298,6 +298,11 @@ class AccountUpdateService $openingBalance = $data['opening_balance']; $openingBalanceDate = $data['opening_balance_date']; + // if liability, make sure the amount is positive for a credit, and negative for a debit. + if($this->isLiability($account)) { + $openingBalance = 'credit' === $data['liability_direction'] ? app('steam')->positive($openingBalance) : app('steam')->negative($openingBalance); + } + $this->updateOBGroupV2($account, $openingBalance, $openingBalanceDate); } diff --git a/public/v1/js/ff/accounts/edit.js b/public/v1/js/ff/accounts/edit.js index 55915cd5b5..192c224145 100644 --- a/public/v1/js/ff/accounts/edit.js +++ b/public/v1/js/ff/accounts/edit.js @@ -30,5 +30,21 @@ $(document).ready(function () { } ); } + // change the 'ffInput_opening_balance' text based on the + // selection of the direction. + $("#ffInput_liability_direction").change(triggerDirection); + triggerDirection(); }); + +function triggerDirection() { + let obj = $("#ffInput_liability_direction"); + let direction = obj.val(); + console.log('Direction is now ' + direction); + if('credit' === direction) { + $('label[for="ffInput_opening_balance"]').text(iAmOwed); + } + if('debit' === direction) { + $('label[for="ffInput_opening_balance"]').text(iOwe); + } +} diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 646a6e5ee4..461147f153 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -1715,6 +1715,8 @@ return [ 'extension_date_is' => 'Extension date is {date}', // accounts: + 'i_am_owed_amount' => 'I am owed amount', + 'i_owe_amount' => 'I owe amount', 'inactive_account_link' => 'You have :count inactive (archived) account, which you can view on this separate page.|You have :count inactive (archived) accounts, which you can view on this separate page.', 'all_accounts_inactive' => 'These are your inactive accounts.', 'active_account_link' => 'This link goes back to your active accounts.', @@ -2468,7 +2470,7 @@ return [ // recurring transactions 'create_right_now' => 'Create right now', - 'no_new_transaction_in_recurrence' => 'No new transaction was created. Perhaps it was already fired for this date?', + 'no_new_transaction_in_recurrence' => 'No new transaction was created. Perhaps it was already fired for this date?', 'recurrences' => 'Recurring transactions', 'repeat_until_in_past' => 'This recurring transaction stopped repeating on :date.', 'recurring_calendar_view' => 'Calendar', diff --git a/resources/views/accounts/edit.twig b/resources/views/accounts/edit.twig index 3e3d523295..edc8df2e58 100644 --- a/resources/views/accounts/edit.twig +++ b/resources/views/accounts/edit.twig @@ -35,7 +35,7 @@ {% if objectType == 'liabilities' %} {{ ExpandedForm.select('liability_type_id', liabilityTypes) }} - {{ ExpandedForm.amountNoCurrency('opening_balance', null, {label:'debt_start_amount'|_, helpText: 'debt_start_amount_help'|_}) }} + {{ ExpandedForm.amountNoCurrency('opening_balance', null, {label:'debt_start_amount'|_}) }} {{ ExpandedForm.select('liability_direction', liabilityDirections) }} {{ ExpandedForm.date('opening_balance_date', null, {label:'debt_start_date'|_}) }} {{ ExpandedForm.percentage('interest') }} @@ -115,6 +115,10 @@ {% endblock %} {% block scripts %} + From 7e6ce7c3e80ebe3a61468319ec7509fc5d86de03 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 15 Jan 2023 07:21:51 +0100 Subject: [PATCH 3/6] Also in create form. --- public/v1/js/ff/accounts/create.js | 17 +++++++++++++++++ resources/views/accounts/create.twig | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/public/v1/js/ff/accounts/create.js b/public/v1/js/ff/accounts/create.js index 7940fe5cc7..2cc44b873f 100644 --- a/public/v1/js/ff/accounts/create.js +++ b/public/v1/js/ff/accounts/create.js @@ -30,4 +30,21 @@ $(document).ready(function () { } ); } + // change the 'ffInput_opening_balance' text based on the + // selection of the direction. + $("#ffInput_liability_direction").change(triggerDirection); + triggerDirection(); }); + + +function triggerDirection() { + let obj = $("#ffInput_liability_direction"); + let direction = obj.val(); + console.log('Direction is now ' + direction); + if('credit' === direction) { + $('label[for="ffInput_opening_balance"]').text(iAmOwed); + } + if('debit' === direction) { + $('label[for="ffInput_opening_balance"]').text(iOwe); + } +} diff --git a/resources/views/accounts/create.twig b/resources/views/accounts/create.twig index 87bef950f5..b83bb08dcc 100644 --- a/resources/views/accounts/create.twig +++ b/resources/views/accounts/create.twig @@ -84,6 +84,10 @@ {% endblock %} {% block scripts %} + From 3c0b23aaedef8ab126c2ec75766e1d5c44488afc Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 15 Jan 2023 07:52:05 +0100 Subject: [PATCH 4/6] Add another case for deposits. --- .../Support/CreditRecalculateService.php | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/app/Services/Internal/Support/CreditRecalculateService.php b/app/Services/Internal/Support/CreditRecalculateService.php index 365209035d..b5b3f00bbe 100644 --- a/app/Services/Internal/Support/CreditRecalculateService.php +++ b/app/Services/Internal/Support/CreditRecalculateService.php @@ -313,14 +313,29 @@ class CreditRecalculateService return $newLeftOfDebt; } - // in any other case, remove amount from left of debt. - if (in_array($type, [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER], true)) { - $newLeftOfDebt = bcadd($leftOfDebt, bcmul($usedAmount, '-1')); - Log::debug(sprintf('[4] transaction is withdrawal/deposit/transfer, remove amount %s from left of debt, = %s.', $usedAmount, $newLeftOfDebt)); + // case 4 + // it's a deposit into this liability (from revenue account). + // if it's a credit ("I am owed") this increases the amount due. + // because the person is having to pay more money. + if ( + $type === TransactionType::DEPOSIT + && (int)$account->id === (int)$destTransaction->account_id + && 1 === bccomp($usedAmount, '0') + && 'credit' === $direction + ) { + $newLeftOfDebt = bcadd($leftOfDebt, app('steam')->positive($usedAmount)); + Log::debug(sprintf('[4] Is deposit (%s) into liability, left of debt = %s.', $usedAmount, $newLeftOfDebt)); return $newLeftOfDebt; } - Log::warning(sprintf('[5] Catch-all, should not happen. Left of debt = %s', $leftOfDebt)); + // in any other case, remove amount from left of debt. + if (in_array($type, [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER], true)) { + $newLeftOfDebt = bcadd($leftOfDebt, bcmul($usedAmount, '-1')); + Log::debug(sprintf('[5] Fallback: transaction is withdrawal/deposit/transfer, remove amount %s from left of debt, = %s.', $usedAmount, $newLeftOfDebt)); + return $newLeftOfDebt; + } + + Log::warning(sprintf('[6] Catch-all, should not happen. Left of debt = %s', $leftOfDebt)); return $leftOfDebt; } From 84c3868c9bfa5a6c8a540f19b4314bfb59f03eb6 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 15 Jan 2023 09:22:34 +0100 Subject: [PATCH 5/6] Add destructive upgrade routine. --- .../Upgrade/UpgradeLiabilitiesEight.php | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php index 88525d8c16..2024db6570 100644 --- a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php +++ b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php @@ -26,6 +26,7 @@ namespace FireflyIII\Console\Commands\Upgrade; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; +use FireflyIII\Models\AccountType; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; @@ -149,9 +150,50 @@ class UpgradeLiabilitiesEight extends Command $this->reverseOpeningBalance($account); $this->line(sprintf('Fixed correct bad opening for liability #%d ("%s")', $account->id, $account->name)); } + if ('credit' === $direction) { + $count = $this->deleteTransactions($account); + if ($count > 0) { + $this->line(sprintf('Removed %d old format transaction(s) for liability #%d ("%s")', $count, $account->id, $account->name)); + } + } Log::debug(sprintf('Done upgrading liability #%d ("%s")', $account->id, $account->name)); } + /** + * @param $account + * @return void + */ + private function deleteTransactions($account): int + { + $count = 0; + $journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transactions.account_id', $account->id)->get([]); + Log::debug(sprintf('Found %d journals to analyse.', $journals->count())); + /** @var TransactionJournal $journal */ + foreach ($journals as $journal) { + $delete = false; + /** @var Transaction $source */ + $source = $journal->transactions()->where('amount', '<', 0)->first(); + /** @var Transaction $dest */ + $dest = $journal->transactions()->where('amount', '>', 0)->first(); + // if source is this liability and destination is expense, remove transaction. + // if source is revenue and destination is liability, remove transaction. + if ((int)$source->account_id === (int)$account->id && $dest->account->accountType->type === AccountType::EXPENSE) { + $delete = true; + } + if ((int)$dest->account_id === (int)$account->id && $source->account->accountType->type === AccountType::REVENUE) { + $delete = true; + } + if ($delete) { + Log::debug(sprintf('Will delete journal #%d ("%s")', $journal->id, $journal->description)); + $service = app(TransactionGroupDestroyService::class); + $service->destroy($journal); + $count++; + } + } + return $count; + } + /** * @param Account $account * @return void @@ -226,13 +268,13 @@ class UpgradeLiabilitiesEight extends Command ->where('transaction_journals.transaction_type_id', $openingBalanceType->id) ->first(['transaction_journals.*']); /** @var Transaction $source */ - $source = $openingJournal->transactions()->where('amount', '<', 0)->first(); + $source = $openingJournal->transactions()->where('amount', '<', 0)->first(); /** @var Transaction $dest */ - $dest = $openingJournal->transactions()->where('amount', '>', 0)->first(); - if($source && $dest) { - $sourceId = $source->account_id; - $destId = $dest->account_id; - $dest->account_id = $sourceId; + $dest = $openingJournal->transactions()->where('amount', '>', 0)->first(); + if ($source && $dest) { + $sourceId = $source->account_id; + $destId = $dest->account_id; + $dest->account_id = $sourceId; $source->account_id = $destId; $source->save(); $dest->save(); From 9b37d5ab8d3f2b7c5d86c6e3875a1293023d14b1 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 15 Jan 2023 13:49:28 +0100 Subject: [PATCH 6/6] Clean up logging. --- .../Upgrade/UpgradeLiabilitiesEight.php | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php index 2024db6570..f138ec78e2 100644 --- a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php +++ b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php @@ -73,8 +73,6 @@ class UpgradeLiabilitiesEight extends Command return 0; } $this->upgradeLiabilities(); - - // TODO uncomment me $this->markAsExecuted(); $end = round(microtime(true) - $start, 2); @@ -136,10 +134,11 @@ class UpgradeLiabilitiesEight extends Command */ private function upgradeLiability(Account $account): void { + Log::debug(sprintf('Upgrade liability #%d ("%s")', $account->id, $account->name)); + /** @var AccountRepositoryInterface $repository */ $repository = app(AccountRepositoryInterface::class); $repository->setUser($account->user); - Log::debug(sprintf('Upgrade liability #%d ("%s")', $account->id, $account->name)); $direction = $repository->getMetaValue($account, 'liability_direction'); if ('debit' === $direction) { @@ -148,7 +147,7 @@ class UpgradeLiabilitiesEight extends Command if ('credit' === $direction && $this->hasBadOpening($account)) { $this->deleteCreditTransaction($account); $this->reverseOpeningBalance($account); - $this->line(sprintf('Fixed correct bad opening for liability #%d ("%s")', $account->id, $account->name)); + $this->line(sprintf('Corrected opening balance for liability #%d ("%s")', $account->id, $account->name)); } if ('credit' === $direction) { $count = $this->deleteTransactions($account); @@ -167,7 +166,7 @@ class UpgradeLiabilitiesEight extends Command { $count = 0; $journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transactions.account_id', $account->id)->get([]); + ->where('transactions.account_id', $account->id)->get(['transaction_journals.*']); Log::debug(sprintf('Found %d journals to analyse.', $journals->count())); /** @var TransactionJournal $journal */ foreach ($journals as $journal) { @@ -176,6 +175,7 @@ class UpgradeLiabilitiesEight extends Command $source = $journal->transactions()->where('amount', '<', 0)->first(); /** @var Transaction $dest */ $dest = $journal->transactions()->where('amount', '>', 0)->first(); + // if source is this liability and destination is expense, remove transaction. // if source is revenue and destination is liability, remove transaction. if ((int)$source->account_id === (int)$account->id && $dest->account->accountType->type === AccountType::EXPENSE) { @@ -185,9 +185,18 @@ class UpgradeLiabilitiesEight extends Command $delete = true; } if ($delete) { - Log::debug(sprintf('Will delete journal #%d ("%s")', $journal->id, $journal->description)); + Log::debug( + sprintf( + 'Deleted %s journal #%d ("%s") (%s %s).', + $journal->transactionType->type, + $journal->id, + $journal->description, + $journal->transactionCurrency->code, + $dest->amount + ) + ); $service = app(TransactionGroupDestroyService::class); - $service->destroy($journal); + $service->destroy($journal->transactionGroup); $count++; } } @@ -200,6 +209,7 @@ class UpgradeLiabilitiesEight extends Command */ private function deleteCreditTransaction(Account $account): void { + Log::debug('Will delete credit transaction.'); $liabilityType = TransactionType::whereType(TransactionType::LIABILITY_CREDIT)->first(); $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->where('transactions.account_id', $account->id) @@ -210,7 +220,9 @@ class UpgradeLiabilitiesEight extends Command $service = new TransactionGroupDestroyService(); $service->destroy($group); Log::debug(sprintf('Deleted liability credit group #%d', $group->id)); + return; } + Log::debug('No liability credit journal found.'); }