diff --git a/app/Console/Commands/Correction/FixAccountTypes.php b/app/Console/Commands/Correction/FixAccountTypes.php index 8b6bd26d8e..2d9ac3aff0 100644 --- a/app/Console/Commands/Correction/FixAccountTypes.php +++ b/app/Console/Commands/Correction/FixAccountTypes.php @@ -222,7 +222,7 @@ class FixAccountTypes extends Command */ private function inspectJournal(TransactionJournal $journal): void { - Log::debug(sprintf('Now trying to fix journal #%d', $journal->id)); + //Log::debug(sprintf('Now trying to fix journal #%d', $journal->id)); $count = $journal->transactions()->count(); if (2 !== $count) { Log::debug(sprintf('Journal has %d transactions, so cant fix.', $count)); diff --git a/app/Console/Commands/Correction/FixTransactionTypes.php b/app/Console/Commands/Correction/FixTransactionTypes.php new file mode 100644 index 0000000000..d4a1f46156 --- /dev/null +++ b/app/Console/Commands/Correction/FixTransactionTypes.php @@ -0,0 +1,169 @@ +collectJournals(); + /** @var TransactionJournal $journal */ + foreach ($journals as $journal) { + $fixed = $this->fixJournal($journal); + if (true === $fixed) { + $count++; + } + } + $end = round(microtime(true) - $start, 2); + if ($count > 0) { + $this->info(sprintf('Corrected transaction type of %d transaction journals in %s seconds.', $count, $end)); + + return 0; + } + $this->line(sprintf('All transaction journals are of the correct type (in %s seconds).', $end)); + + return 0; + } + + /** + * @param TransactionJournal $journal + * @param string $expectedType + */ + private function changeJournal(TransactionJournal $journal, string $expectedType): void + { + $type = TransactionType::whereType($expectedType)->first(); + if (null !== $type) { + $journal->transaction_type_id = $type->id; + $journal->save(); + } + } + + /** + * Collect all transaction journals. + * + * @return Collection + */ + private function collectJournals(): Collection + { + return TransactionJournal + ::with(['transactionType', 'transactions', 'transactions.account', 'transactions.account.accountType']) + ->get(); + } + + /** + * @param TransactionJournal $journal + * + * @return bool + */ + private function fixJournal(TransactionJournal $journal): bool + { + $type = $journal->transactionType->type; + try { + $source = $this->getSourceAccount($journal); + $destination = $this->getDestinationAccount($journal); + } catch (FireflyException $e) { + $this->error($e->getMessage()); + + return false; + } + $expectedType = (string) config(sprintf('firefly.account_to_transaction.%s.%s', $source->accountType->type, $destination->accountType->type)); + if ($expectedType !== $type) { + $this->line(sprintf('Transaction journal #%d was of type "%s" but is corrected to "%s"', $journal->id, $type, $expectedType)); + $this->changeJournal($journal, $expectedType); + + return true; + } + + return false; + } + + /** + * @param TransactionJournal $journal + * + * @throws FireflyException + * @return Account + */ + private function getDestinationAccount(TransactionJournal $journal): Account + { + $collection = $journal->transactions->filter( + static function (Transaction $transaction) { + return $transaction->amount > 0; + } + ); + if (0 === $collection->count()) { + throw new FireflyException(sprintf('Journal #%d has no destination transaction.', $journal->id)); + } + if (1 !== $collection->count()) { + throw new FireflyException(sprintf('Journal #%d has multiple destination transactions.', $journal->id)); + } + /** @var Transaction $transaction */ + $transaction = $collection->first(); + $account = $transaction->account; + if (null === $account) { + throw new FireflyException(sprintf('Journal #%d, transaction #%d has no destination account.', $journal->id, $transaction->id)); + } + + return $account; + } + + /** + * @param TransactionJournal $journal + * + * @throws FireflyException + * @return Account + */ + private function getSourceAccount(TransactionJournal $journal): Account + { + $collection = $journal->transactions->filter( + static function (Transaction $transaction) { + return $transaction->amount < 0; + } + ); + if (0 === $collection->count()) { + throw new FireflyException(sprintf('Journal #%d has no source transaction.', $journal->id)); + } + if (1 !== $collection->count()) { + throw new FireflyException(sprintf('Journal #%d has multiple source transactions.', $journal->id)); + } + /** @var Transaction $transaction */ + $transaction = $collection->first(); + $account = $transaction->account; + if (null === $account) { + throw new FireflyException(sprintf('Journal #%d, transaction #%d has no source account.', $journal->id, $transaction->id)); + } + + return $account; + } +} diff --git a/app/Console/Commands/DecryptDatabase.php b/app/Console/Commands/DecryptDatabase.php index d4457a64a7..42d200fa94 100644 --- a/app/Console/Commands/DecryptDatabase.php +++ b/app/Console/Commands/DecryptDatabase.php @@ -98,7 +98,7 @@ class DecryptDatabase extends Command } catch(JsonException $e) { Log::error($e->getMessage()); } - Log::debug(sprintf('Decrypted field "%s" "%s" to "%s" in table "%s" (row #%d)', $field, $original, print_r($value, true), $table, $id)); + //Log::debug(sprintf('Decrypted field "%s" "%s" to "%s" in table "%s" (row #%d)', $field, $original, print_r($value, true), $table, $id)); /** @var Preference $object */ $object = Preference::find((int) $id); @@ -110,7 +110,7 @@ class DecryptDatabase extends Command } if ($value !== $original) { - Log::debug(sprintf('Decrypted field "%s" "%s" to "%s" in table "%s" (row #%d)', $field, $original, $value, $table, $id)); + //Log::debug(sprintf('Decrypted field "%s" "%s" to "%s" in table "%s" (row #%d)', $field, $original, $value, $table, $id)); DB::table($table)->where('id', $id)->update([$field => $value]); } }