Update installation commands.

This commit is contained in:
James Cole
2021-03-12 06:30:40 +01:00
parent 748d61fb8f
commit a05d006fa7
40 changed files with 1624 additions and 1470 deletions

View File

@@ -89,6 +89,7 @@ class CorrectOpeningBalanceCurrencies extends Command
}
Log::debug(sprintf('Done with %s', __METHOD__));
return 0;
}
@@ -133,6 +134,7 @@ class CorrectOpeningBalanceCurrencies extends Command
$account = $transaction->account()->first();
if (null !== $account && AccountType::INITIAL_BALANCE !== $account->accountType()->first()->type) {
Log::debug(sprintf('Account of transaction #%d is opposite of IB account (%s).', $transaction->id, $account->accountType()->first()->type));
return $account;
}
}
@@ -143,6 +145,7 @@ class CorrectOpeningBalanceCurrencies extends Command
/**
* @param Account $account
*
* @return TransactionCurrency
* @throws JsonException
*/
@@ -156,15 +159,16 @@ class CorrectOpeningBalanceCurrencies extends Command
}
/**
* @param TransactionJournal $journal
* @param TransactionJournal $journal
* @param TransactionCurrency $currency
*
* @return int
*/
private function setCurrency(TransactionJournal $journal, TransactionCurrency $currency): int
{
Log::debug('Now in setCurrency');
$count = 0;
if ((int) $journal->transaction_currency_id !== (int) $currency->id) {
if ((int)$journal->transaction_currency_id !== (int)$currency->id) {
Log::debug(sprintf('Currency ID of journal #%d was #%d, now set to #%d', $journal->id, $journal->transaction_currency_id, $currency->id));
$journal->transaction_currency_id = $currency->id;
$journal->save();
@@ -173,8 +177,10 @@ class CorrectOpeningBalanceCurrencies extends Command
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
if ((int) $transaction->transaction_currency_id !== (int) $currency->id) {
Log::debug(sprintf('Currency ID of transaction #%d was #%d, now set to #%d', $transaction->id, $transaction->transaction_currency_id, $currency->id));
if ((int)$transaction->transaction_currency_id !== (int)$currency->id) {
Log::debug(
sprintf('Currency ID of transaction #%d was #%d, now set to #%d', $transaction->id, $transaction->transaction_currency_id, $currency->id)
);
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
$count = 1;

View File

@@ -50,8 +50,8 @@ class CreateAccessTokens extends Command
/**
* Execute the console command.
*
* @throws Exception
* @return int
* @throws Exception
*/
public function handle(): int
{

View File

@@ -50,9 +50,9 @@ class DeleteEmptyGroups extends Command
/**
* Execute the console command.
*
* @return int
* @throws Exception;
*
* @return int
*/
public function handle(): int
{

View File

@@ -62,6 +62,38 @@ class DeleteEmptyJournals extends Command
return 0;
}
/**
* Delete transactions and their journals if they have an uneven number of transactions.
*/
private function deleteUnevenJournals(): void
{
$set = Transaction
::whereNull('deleted_at')
->groupBy('transactions.transaction_journal_id')
->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']);
$total = 0;
foreach ($set as $row) {
$count = (int)$row->the_count;
if (1 === $count % 2) {
// uneven number, delete journal and transactions:
try {
TransactionJournal::find((int)$row->transaction_journal_id)->delete();
// @codeCoverageIgnoreStart
} catch (Exception $e) {
Log::info(sprintf('Could not delete journal: %s', $e->getMessage()));
}
// @codeCoverageIgnoreEnd
Transaction::where('transaction_journal_id', (int)$row->transaction_journal_id)->delete();
$this->info(sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $row->transaction_journal_id));
$total++;
}
}
if (0 === $total) {
$this->info('No uneven transaction journals.');
}
}
private function deleteEmptyJournals(): void
{
$start = microtime(true);
@@ -90,36 +122,4 @@ class DeleteEmptyJournals extends Command
$this->info(sprintf('Verified empty journals in %s seconds', $end));
}
/**
* Delete transactions and their journals if they have an uneven number of transactions.
*/
private function deleteUnevenJournals(): void
{
$set = Transaction
::whereNull('deleted_at')
->groupBy('transactions.transaction_journal_id')
->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']);
$total = 0;
foreach ($set as $row) {
$count = (int) $row->the_count;
if (1 === $count % 2) {
// uneven number, delete journal and transactions:
try {
TransactionJournal::find((int) $row->transaction_journal_id)->delete();
// @codeCoverageIgnoreStart
} catch (Exception $e) {
Log::info(sprintf('Could not delete journal: %s', $e->getMessage()));
}
// @codeCoverageIgnoreEnd
Transaction::where('transaction_journal_id', (int) $row->transaction_journal_id)->delete();
$this->info(sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $row->transaction_journal_id));
$total++;
}
}
if (0 === $total) {
$this->info('No uneven transaction journals.');
}
}
}

View File

@@ -52,8 +52,8 @@ class DeleteOrphanedTransactions extends Command
/**
* Execute the console command.
*
* @throws Exception
* @return int
* @throws Exception
*/
public function handle(): int
{
@@ -66,45 +66,6 @@ class DeleteOrphanedTransactions extends Command
return 0;
}
/**
*
*/
private function deleteFromOrphanedAccounts(): void
{
$set
= Transaction
::leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
->whereNotNull('accounts.deleted_at')
->get(['transactions.*']);
$count = 0;
/** @var Transaction $transaction */
foreach ($set as $transaction) {
// delete journals
$journal = TransactionJournal::find((int) $transaction->transaction_journal_id);
if ($journal) {
try {
$journal->delete();
// @codeCoverageIgnoreStart
} catch (Exception $e) {
Log::info(sprintf('Could not delete journal %s', $e->getMessage()));
}
// @codeCoverageIgnoreEnd
}
Transaction::where('transaction_journal_id', (int) $transaction->transaction_journal_id)->delete();
$this->line(
sprintf(
'Deleted transaction journal #%d because account #%d was already deleted.',
$transaction->transaction_journal_id,
$transaction->account_id
)
);
$count++;
}
if (0 === $count) {
$this->info('No orphaned accounts.');
}
}
/**
* @throws Exception
*/
@@ -124,7 +85,7 @@ class DeleteOrphanedTransactions extends Command
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$transaction = Transaction::find((int) $entry->transaction_id);
$transaction = Transaction::find((int)$entry->transaction_id);
$transaction->delete();
$this->info(
sprintf(
@@ -139,4 +100,43 @@ class DeleteOrphanedTransactions extends Command
$this->info('No orphaned transactions.');
}
}
/**
*
*/
private function deleteFromOrphanedAccounts(): void
{
$set
= Transaction
::leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
->whereNotNull('accounts.deleted_at')
->get(['transactions.*']);
$count = 0;
/** @var Transaction $transaction */
foreach ($set as $transaction) {
// delete journals
$journal = TransactionJournal::find((int)$transaction->transaction_journal_id);
if ($journal) {
try {
$journal->delete();
// @codeCoverageIgnoreStart
} catch (Exception $e) {
Log::info(sprintf('Could not delete journal %s', $e->getMessage()));
}
// @codeCoverageIgnoreEnd
}
Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete();
$this->line(
sprintf(
'Deleted transaction journal #%d because account #%d was already deleted.',
$transaction->transaction_journal_id,
$transaction->account_id
)
);
$count++;
}
if (0 === $count) {
$this->info('No orphaned accounts.');
}
}
}

View File

@@ -64,35 +64,39 @@ class EnableCurrencies extends Command
/** @var Collection $meta */
$meta = AccountMeta::where('name', 'currency_id')->groupBy('data')->get(['data']);
foreach ($meta as $entry) {
$found[] = (int) $entry->data;
$found[] = (int)$entry->data;
}
// get all from journals:
/** @var Collection $journals */
$journals = TransactionJournal::groupBy('transaction_currency_id')->get(['transaction_currency_id']);
foreach ($journals as $entry) {
$found[] = (int) $entry->transaction_currency_id;
$found[] = (int)$entry->transaction_currency_id;
}
// get all from transactions
/** @var Collection $transactions */
$transactions = Transaction::groupBy('transaction_currency_id', 'foreign_currency_id')->get(['transaction_currency_id','foreign_currency_id']);
$transactions = Transaction::groupBy('transaction_currency_id', 'foreign_currency_id')->get(['transaction_currency_id', 'foreign_currency_id']);
foreach ($transactions as $entry) {
$found[] = (int) $entry->transaction_currency_id;
$found[] = (int) $entry->foreign_currency_id;
$found[] = (int)$entry->transaction_currency_id;
$found[] = (int)$entry->foreign_currency_id;
}
// get all from budget limits
/** @var Collection $limits */
$limits = BudgetLimit::groupBy('transaction_currency_id')->get(['transaction_currency_id']);
foreach ($limits as $entry) {
$found[] = (int) $entry->transaction_currency_id;
$found[] = (int)$entry->transaction_currency_id;
}
$found = array_values(array_unique($found));
$found = array_values(array_filter($found, function (int $currencyId) {
return $currencyId !== 0;
}));
$found = array_values(
array_filter(
$found, function (int $currencyId) {
return $currencyId !== 0;
}
)
);
$message = sprintf('%d different currencies are currently in use.', count($found));
$this->info($message);
Log::debug($message, $found);

View File

@@ -39,11 +39,13 @@ class FixAccountTypes extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Make sure all journals have the correct from/to account types.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:fix-account-types';
@@ -54,6 +56,7 @@ class FixAccountTypes extends Command
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
*/
@@ -84,11 +87,87 @@ class FixAccountTypes extends Command
return 0;
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
* @codeCoverageIgnore
*/
private function stupidLaravel(): void
{
$this->count = 0;
}
/**
* @param TransactionJournal $journal
*
* @throws FireflyException
*/
private function inspectJournal(TransactionJournal $journal): void
{
$transactions = $journal->transactions()->count();
if (2 !== $transactions) {
Log::debug(sprintf('Journal has %d transactions, so can\'t fix.', $transactions));
$this->info(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $transactions));
return;
}
$type = $journal->transactionType->type;
$sourceTransaction = $this->getSourceTransaction($journal);
$destTransaction = $this->getDestinationTransaction($journal);
$sourceAccount = $sourceTransaction->account;
$sourceAccountType = $sourceAccount->accountType->type;
$destAccount = $destTransaction->account;
$destAccountType = $destAccount->accountType->type;
if (!array_key_exists($type, $this->expected)) {
// @codeCoverageIgnoreStart
Log::info(sprintf('No source/destination info for transaction type %s.', $type));
$this->info(sprintf('No source/destination info for transaction type %s.', $type));
return;
// @codeCoverageIgnoreEnd
}
if (!array_key_exists($sourceAccountType, $this->expected[$type])) {
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
return;
}
$expectedTypes = $this->expected[$type][$sourceAccountType];
if (!in_array($destAccountType, $expectedTypes, true)) {
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
}
}
/**
* @param TransactionJournal $journal
*
* @return Transaction
*/
private function getSourceTransaction(TransactionJournal $journal): Transaction
{
return $journal->transactions->firstWhere('amount', '<', 0);
}
/**
* @param TransactionJournal $journal
*
* @return Transaction
*/
private function getDestinationTransaction(TransactionJournal $journal): Transaction
{
return $journal->transactions->firstWhere('amount', '>', 0);
}
/**
* @param TransactionJournal $journal
* @param string $type
* @param Transaction $source
* @param Transaction $dest
*
* @throws FireflyException
*/
private function fixJournal(TransactionJournal $journal, string $type, Transaction $source, Transaction $dest): void
@@ -132,7 +211,10 @@ class FixAccountTypes extends Command
$result = $this->factory->findOrCreate($dest->account->name, AccountType::EXPENSE);
$dest->account()->associate($result);
$dest->save();
$message = sprintf('Transaction journal #%d, destination account changed from #%d ("%s") to #%d ("%s").', $journal->id, $oldDest->id, $oldDest->name, $result->id, $result->name);
$message = sprintf(
'Transaction journal #%d, destination account changed from #%d ("%s") to #%d ("%s").', $journal->id, $oldDest->id, $oldDest->name,
$result->id, $result->name
);
$this->info($message);
Log::debug($message);
$this->inspectJournal($journal);
@@ -145,7 +227,10 @@ class FixAccountTypes extends Command
$oldSource = $dest->account;
$source->account()->associate($result);
$source->save();
$message = sprintf('Transaction journal #%d, source account changed from #%d ("%s") to #%d ("%s").', $journal->id, $oldSource->id, $oldSource->name, $result->id, $result->name);
$message = sprintf(
'Transaction journal #%d, source account changed from #%d ("%s") to #%d ("%s").', $journal->id, $oldSource->id, $oldSource->name,
$result->id, $result->name
);
$this->info($message);
Log::debug($message);
$this->inspectJournal($journal);
@@ -163,75 +248,4 @@ class FixAccountTypes extends Command
}
}
/**
* @param TransactionJournal $journal
* @return Transaction
*/
private function getDestinationTransaction(TransactionJournal $journal): Transaction
{
return $journal->transactions->firstWhere('amount', '>', 0);
}
/**
* @param TransactionJournal $journal
* @return Transaction
*/
private function getSourceTransaction(TransactionJournal $journal): Transaction
{
return $journal->transactions->firstWhere('amount', '<', 0);
}
/**
* @param TransactionJournal $journal
* @throws FireflyException
*/
private function inspectJournal(TransactionJournal $journal): void
{
$transactions = $journal->transactions()->count();
if (2 !== $transactions) {
Log::debug(sprintf('Journal has %d transactions, so can\'t fix.', $transactions));
$this->info(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $transactions));
return;
}
$type = $journal->transactionType->type;
$sourceTransaction = $this->getSourceTransaction($journal);
$destTransaction = $this->getDestinationTransaction($journal);
$sourceAccount = $sourceTransaction->account;
$sourceAccountType = $sourceAccount->accountType->type;
$destAccount = $destTransaction->account;
$destAccountType = $destAccount->accountType->type;
if (!array_key_exists($type, $this->expected)) {
// @codeCoverageIgnoreStart
Log::info(sprintf('No source/destination info for transaction type %s.', $type));
$this->info(sprintf('No source/destination info for transaction type %s.', $type));
return;
// @codeCoverageIgnoreEnd
}
if (!array_key_exists($sourceAccountType, $this->expected[$type])) {
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
return;
}
$expectedTypes = $this->expected[$type][$sourceAccountType];
if (!in_array($destAccountType, $expectedTypes, true)) {
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
}
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
* @codeCoverageIgnore
*/
private function stupidLaravel(): void
{
$this->count = 0;
}
}

View File

@@ -62,12 +62,12 @@ class FixGroupAccounts extends Command
::groupBy('transaction_group_id')
->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')]);
foreach ($res as $journal) {
if ((int) $journal->the_count > 1) {
$groups[] = (int) $journal->transaction_group_id;
if ((int)$journal->the_count > 1) {
$groups[] = (int)$journal->transaction_group_id;
}
}
$handler = new UpdatedGroupEventHandler;
foreach($groups as $groupId) {
foreach ($groups as $groupId) {
$group = TransactionGroup::find($groupId);
$event = new UpdatedTransactionGroup($group);
$handler->unifyAccounts($event);

View File

@@ -69,7 +69,7 @@ class FixLongDescriptions extends Command
$groups = TransactionGroup::get(['id', 'title']);
/** @var TransactionGroup $group */
foreach ($groups as $group) {
if (strlen((string) $group->title) > self::MAX_LENGTH) {
if (strlen((string)$group->title) > self::MAX_LENGTH) {
$group->title = substr($group->title, 0, self::MAX_LENGTH);
$group->save();
$this->line(sprintf('Truncated description of transaction group #%d', $group->id));

View File

@@ -73,18 +73,6 @@ class FixRecurringTransactions extends Command
return 0;
}
/**
*
*/
private function correctTransactions(): void
{
$users = $this->userRepos->all();
/** @var User $user */
foreach ($users as $user) {
$this->processUser($user);
}
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
@@ -98,6 +86,18 @@ class FixRecurringTransactions extends Command
$this->userRepos = app(UserRepositoryInterface::class);
}
/**
*
*/
private function correctTransactions(): void
{
$users = $this->userRepos->all();
/** @var User $user */
foreach ($users as $user) {
$this->processUser($user);
}
}
/**
* @param User $user
*/

View File

@@ -79,19 +79,6 @@ class FixTransactionTypes extends Command
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.
*
@@ -120,7 +107,7 @@ class FixTransactionTypes extends Command
return false;
}
$expectedType = (string) config(sprintf('firefly.account_to_transaction.%s.%s', $source->accountType->type, $destination->accountType->type));
$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);
@@ -134,8 +121,37 @@ class FixTransactionTypes extends Command
/**
* @param TransactionJournal $journal
*
* @throws FireflyException
* @return Account
* @throws FireflyException
*/
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;
}
/**
* @param TransactionJournal $journal
*
* @return Account
* @throws FireflyException
*/
private function getDestinationAccount(TransactionJournal $journal): Account
{
@@ -162,30 +178,14 @@ class FixTransactionTypes extends Command
/**
* @param TransactionJournal $journal
*
* @throws FireflyException
* @return Account
* @param string $expectedType
*/
private function getSourceAccount(TransactionJournal $journal): Account
private function changeJournal(TransactionJournal $journal, string $expectedType): void
{
$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));
$type = TransactionType::whereType($expectedType)->first();
if (null !== $type) {
$journal->transaction_type_id = $type->id;
$journal->save();
}
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

@@ -56,10 +56,10 @@ class RemoveBills extends Command
$start = microtime(true);
/** @var TransactionType $withdrawal */
$withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
if(null === $withdrawal) {
if (null === $withdrawal) {
return 0;
}
$journals = TransactionJournal::whereNotNull('bill_id')->where('transaction_type_id', '!=', $withdrawal->id)->get();
$journals = TransactionJournal::whereNotNull('bill_id')->where('transaction_type_id', '!=', $withdrawal->id)->get();
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$this->line(sprintf('Transaction journal #%d should not be linked to bill #%d.', $journal->id, $journal->bill_id));