James Cole
2026-06-30 14:42:20 +02:00
parent 86118b4318
commit fb3eead982
3 changed files with 107 additions and 2 deletions
@@ -60,8 +60,11 @@ class CorrectsAmounts extends Command
{
$this->service = new JournalDestroyService();
$this->genericService = new GenericDestroyService();
// transfers must not have foreign currency info if both accounts have the same currency.
$this->correctTransfers();
// deposits between assets and liabilities must not have foreign currency info if both accounts have the same currency.
$this->correctDeposits();
// auto budgets must be positive
$this->fixAutoBudgets();
// available budgets must be positive
@@ -181,6 +184,107 @@ class CorrectsAmounts extends Command
}
}
private function correctDeposits(): void
{
Log::debug('Will now correct deposits.');
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$type = TransactionType::query()->where('type', TransactionTypeEnum::DEPOSIT->value)->first();
$journals = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereNotNull('transactions.foreign_amount')
->where('transaction_journals.transaction_type_id', $type->id)
->distinct()
->get(['transaction_journals.*'])
;
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$repository->setUser($journal->user);
$primary = Amount::getPrimaryCurrencyByUserGroup($journal->userGroup);
$valid = $this->validateJournal($journal);
if (false === $valid) {
// Log::debug(sprintf('Journal #%d does not need to be fixed or is invalid (see previous messages)', $journal->id));
continue;
}
Log::debug(sprintf('Journal #%d is ready to be corrected (if necessary).', $journal->id));
$source = $journal->transactions()->where('amount', '<', '0')->first();
$destination = $journal->transactions()->where('amount', '>', '0')->first();
$sourceAccount = $source->account;
$destAccount = $destination->account;
$sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $primary;
$destCurrency = $repository->getAccountCurrency($destAccount) ?? $primary;
Log::debug(sprintf('Currency of source account #%d "%s" is %s', $sourceAccount->id, $sourceAccount->name, $sourceCurrency->code));
Log::debug(sprintf('Currency of destination account #%d "%s" is %s', $destAccount->id, $destAccount->name, $destCurrency->code));
if ($sourceCurrency->id === $destCurrency->id) {
Log::debug('Both accounts have the same currency. Removing foreign currency info.');
$source->foreign_currency_id = null;
$source->foreign_amount = null;
$source->save();
$destination->foreign_currency_id = null;
$destination->foreign_amount = null;
// also make sure that both transactions use the same amounts and currencies, since the currency is the same anyway.
$destination->amount = bcmul($source->amount ,'-1');
$destination->save();
continue;
}
// validate source transaction
if ($destCurrency->id !== $source->foreign_currency_id) {
Log::debug(sprintf(
'[a] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".',
$journal->id,
$source->id,
$source->foreignCurrency->code,
$destCurrency->code
));
$source->foreign_currency_id = $destCurrency->id;
$source->save();
}
if ($sourceCurrency->id !== $source->transaction_currency_id) {
Log::debug(sprintf(
'[b] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".',
$journal->id,
$source->id,
$source->transactionCurrency->code,
$sourceCurrency->code
));
$source->transaction_currency_id = $sourceCurrency->id;
$source->save();
}
// validate destination:
if ($sourceCurrency->id !== $destination->foreign_currency_id) {
Log::debug(sprintf(
'[c] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".',
$journal->id,
$destination->id,
$destination->foreignCurrency->code,
$sourceCurrency->code
));
$destination->foreign_currency_id = $sourceCurrency->id;
$destination->save();
}
if ($destCurrency->id !== $destination->transaction_currency_id) {
Log::debug(sprintf(
'[d] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".',
$journal->id,
$destination->id,
$destination->transactionCurrency->code,
$destCurrency->code
));
$destination->transaction_currency_id = $destCurrency->id;
$destination->save();
}
Log::debug(sprintf('Done with journal #%d.', $journal->id));
}
}
private function deleteJournal(TransactionJournal $journal): void
{
$this->service->destroy($journal);
@@ -139,7 +139,7 @@ class AccountBalanceCalculator
/** @var Transaction $entry */
foreach ($set as $entry) {
// Log::debug(sprintf('Processing transaction #%d with currency #%d and amount %s', $entry->id, $entry->transaction_currency_id, Steam::bcround($entry->amount, 2)));
Log::debug(sprintf('[%s] Processing transaction #%d on acount #%d with currency #%d and amount %s',$entry->date, $entry->id, $entry->account_id, $entry->transaction_currency_id, Steam::bcround($entry->amount, 2)));
// start with empty array:
$entry->account_id = (int) $entry->account_id;
$entry->transaction_currency_id = (int) $entry->transaction_currency_id;
+2 -1
View File
@@ -285,7 +285,8 @@
{% if transaction.source_account_type == 'Revenue account' %}
<span title="Deposit from revenue">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% else %}
<span title="Deposit from liab">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.foreign_currency_symbol, transaction.foreign_currency_decimal_places) }}</span>
{# #}
<span title="Deposit from liab">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% endif %}
{# if this is a deposit from revenue account, use the destination account currency? For #12043 and #12169 #}
{# otherwise, keep at source account #}