mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-20 11:33:59 +00:00
Add a command to sync up currency information
This commit is contained in:
@@ -43,17 +43,76 @@ class FixUnevenAmount extends Command
|
|||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$this->fixUnevenAmounts();
|
||||||
|
$this->matchCurrencies();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fixJournal(int $param): void
|
||||||
|
{
|
||||||
|
// one of the transactions is bad.
|
||||||
|
$journal = TransactionJournal::find($param);
|
||||||
|
if (null === $journal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var null|Transaction $source */
|
||||||
|
$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 ?? ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
|
||||||
|
TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$amount = bcmul('-1', $source->amount);
|
||||||
|
|
||||||
|
// fix amount of destination:
|
||||||
|
/** @var null|Transaction $destination */
|
||||||
|
$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 ?? ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
|
||||||
|
TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$destination->amount = $amount;
|
||||||
|
$destination->save();
|
||||||
|
|
||||||
|
$message = sprintf('Corrected amount in transaction journal #%d', $param);
|
||||||
|
$this->friendlyInfo($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fixUnevenAmounts(): void
|
||||||
{
|
{
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$journals = \DB::table('transactions')
|
$journals = \DB::table('transactions')
|
||||||
->groupBy('transaction_journal_id')
|
->groupBy('transaction_journal_id')
|
||||||
->whereNull('deleted_at')
|
->whereNull('deleted_at')
|
||||||
->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')])
|
->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')]);
|
||||||
;
|
|
||||||
|
|
||||||
/** @var \stdClass $entry */
|
/** @var \stdClass $entry */
|
||||||
foreach ($journals as $entry) {
|
foreach ($journals as $entry) {
|
||||||
$sum = (string)$entry->the_sum;
|
$sum = (string) $entry->the_sum;
|
||||||
if (!is_numeric($sum)
|
if (!is_numeric($sum)
|
||||||
|| '' === $sum // @phpstan-ignore-line
|
|| '' === $sum // @phpstan-ignore-line
|
||||||
|| str_contains($sum, 'e')
|
|| str_contains($sum, 'e')
|
||||||
@@ -93,60 +152,23 @@ class FixUnevenAmount extends Command
|
|||||||
if (0 === $count) {
|
if (0 === $count) {
|
||||||
$this->friendlyPositive('Database amount integrity is OK');
|
$this->friendlyPositive('Database amount integrity is OK');
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function fixJournal(int $param): void
|
private function matchCurrencies(): void
|
||||||
{
|
{
|
||||||
// one of the transactions is bad.
|
$journals = TransactionJournal
|
||||||
$journal = TransactionJournal::find($param);
|
::leftJoin('transactions', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||||
if (null === $journal) {
|
->where('transactions.transaction_currency_id', '!=', \DB::raw('transaction_journals.transaction_currency_id'))
|
||||||
|
->get(['transaction_journals.*']);
|
||||||
|
if (0 === $journals->count()) {
|
||||||
|
$this->friendlyPositive('Journal currency integrity is OK');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/** @var TransactionJournal $journal */
|
||||||
/** @var null|Transaction $source */
|
foreach($journals as $journal) {
|
||||||
$source = $journal->transactions()->where('amount', '<', 0)->first();
|
Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]);
|
||||||
|
|
||||||
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 ?? ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
|
|
||||||
TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
$this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count()));
|
||||||
|
|
||||||
$amount = bcmul('-1', $source->amount);
|
|
||||||
|
|
||||||
// fix amount of destination:
|
|
||||||
/** @var null|Transaction $destination */
|
|
||||||
$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 ?? ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
|
|
||||||
TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$destination->amount = $amount;
|
|
||||||
$destination->save();
|
|
||||||
|
|
||||||
$message = sprintf('Corrected amount in transaction journal #%d', $param);
|
|
||||||
$this->friendlyInfo($message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user