From 6e4f2c0c8a7c7ea5e24d7f70ba95471ba9ab02c7 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 15 Oct 2016 06:19:21 +0200 Subject: [PATCH] Small script to upgrade transactions. --- app/Console/Commands/UpgradeDatabase.php | 120 +++++++++++++++++++++++ app/Console/Kernel.php | 2 + 2 files changed, 122 insertions(+) create mode 100644 app/Console/Commands/UpgradeDatabase.php diff --git a/app/Console/Commands/UpgradeDatabase.php b/app/Console/Commands/UpgradeDatabase.php new file mode 100644 index 0000000000..d97003cfea --- /dev/null +++ b/app/Console/Commands/UpgradeDatabase.php @@ -0,0 +1,120 @@ +setTransactionIdentifier(); + + + } + + /** + * This is strangely complex, because the HAVING modifier is a no-no. And subqueries in Laravel are weird. + */ + private function setTransactionIdentifier() + { + $subQuery = TransactionJournal + ::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->whereNull('transaction_journals.deleted_at') + ->whereNull('transactions.deleted_at') + ->groupBy(['transaction_journals.id']) + ->select(['transaction_journals.id', DB::raw('COUNT(transactions.id) AS t_count')]); + + $result = DB::table(DB::raw('(' . $subQuery->toSql() . ') AS derived')) + ->mergeBindings($subQuery->getQuery()) + ->where('t_count', '>', 2) + ->select(['id', 't_count']); + $journalIds = array_unique($result->pluck('id')->toArray()); + + foreach ($journalIds as $journalId) { + // grab all positive transactiosn from this journal that are not deleted. + // for each one, grab the negative opposing one which has 0 as an identifier and give it the same identifier. + $identifier = 0; + $processed = []; + $transactions = Transaction::where('transaction_journal_id', $journalId)->where('amount', '>', 0)->get(); + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + // find opposing: + $amount = bcmul(strval($transaction->amount), '-1'); + + try { + /** @var Transaction $opposing */ + $opposing = Transaction + ::where('transaction_journal_id', $journalId) + ->where('amount', $amount)->where('identifier', '=', 0) + ->whereNotIn('id', $processed) + ->first(); + } catch (QueryException $e) { + Log::error($e->getMessage()); + $this->error('Firefly III could not find the "identifier" field in the "transactions" table.'); + $this->error('This field is required for Firefly III version ' . config('firefly.version') . ' to run.'); + $this->error('Please run "php artisan migrate" to upgrade your database.'); + $this->info('Then, run "php artisan firefly:upgrade-database" to try again.'); + break 2; + } + + // give both a new identifier: + $transaction->identifier = $identifier; + $transaction->save(); + $opposing->identifier = $identifier; + $opposing->save(); + $processed[] = $transaction->id; + $processed[] = $opposing->id; + $this->line(sprintf('Database upgrade for journal #%d, transactions #%d and #%d', $journalId, $transaction->id, $opposing->id)); + $identifier++; + } + } + } +} \ No newline at end of file diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index d3f6037429..f52e0c1570 100755 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -16,6 +16,7 @@ namespace FireflyIII\Console; use FireflyIII\Console\Commands\EncryptFile; use FireflyIII\Console\Commands\Import; use FireflyIII\Console\Commands\ScanAttachments; +use FireflyIII\Console\Commands\UpgradeDatabase; use FireflyIII\Console\Commands\UpgradeFireflyInstructions; use FireflyIII\Console\Commands\VerifyDatabase; use Illuminate\Console\Scheduling\Schedule; @@ -59,6 +60,7 @@ class Kernel extends ConsoleKernel Import::class, EncryptFile::class, ScanAttachments::class, + UpgradeDatabase::class, ];