Add command.

This commit is contained in:
James Cole 2020-07-19 13:06:01 +02:00
parent 1e313f80a4
commit 3653469dda
No known key found for this signature in database
GPG Key ID: B5669F9493CDE38D
3 changed files with 172 additions and 3 deletions

View File

@ -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));

View File

@ -0,0 +1,169 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
/**
* Class FixTransactionTypes
*/
class FixTransactionTypes extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Make sure all transactions are of the correct type, based on source + dest.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:fix-transaction-types';
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$start = microtime(true);
$count = 0;
$journals = $this->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;
}
}

View File

@ -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]);
}
}