From cebfaa32bfd3cf05679d2a1734f088d37965e923 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 12 May 2024 06:24:11 +0200 Subject: [PATCH] Add routine that caches account balances. Add it to the /flush routine as well. --- .../Correction/CorrectBalanceAmounts.php | 49 +++++++++++++++++++ .../Commands/Correction/CorrectDatabase.php | 1 + app/Handlers/Observer/TransactionObserver.php | 19 +++++++ app/Http/Controllers/DebugController.php | 10 ++-- app/Models/AccountBalance.php | 12 +++++ ...12_060551_create_account_balance_table.php | 35 +++++++++++++ 6 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 app/Console/Commands/Correction/CorrectBalanceAmounts.php create mode 100644 app/Models/AccountBalance.php create mode 100644 database/migrations/2024_05_12_060551_create_account_balance_table.php diff --git a/app/Console/Commands/Correction/CorrectBalanceAmounts.php b/app/Console/Commands/Correction/CorrectBalanceAmounts.php new file mode 100644 index 0000000000..54f0fc9096 --- /dev/null +++ b/app/Console/Commands/Correction/CorrectBalanceAmounts.php @@ -0,0 +1,49 @@ +correctBalanceAmounts(); + + + return 0; + } + + private function correctBalanceAmounts(): void + { + $result = Transaction + ::groupBy(['account_id', 'transaction_currency_id']) + ->get(['account_id', 'transaction_currency_id', DB::raw('SUM(amount) as amount_sum')]); + /** @var stdClass $entry */ + foreach ($result as $entry) { + $account = (int) $entry->account_id; + $currency = (int) $entry->transaction_currency_id; + $sum = $entry->amount_sum; + + AccountBalance::updateOrCreate( + ['account_id' => $account, 'transaction_currency_id' => $currency], + ['balance' => $sum] + ); + } + } +} diff --git a/app/Console/Commands/Correction/CorrectDatabase.php b/app/Console/Commands/Correction/CorrectDatabase.php index 82750c1a9d..e7286ef62f 100644 --- a/app/Console/Commands/Correction/CorrectDatabase.php +++ b/app/Console/Commands/Correction/CorrectDatabase.php @@ -74,6 +74,7 @@ class CorrectDatabase extends Command 'firefly-iii:unify-group-accounts', 'firefly-iii:trigger-credit-recalculation', 'firefly-iii:migrate-preferences', + 'firefly-iii:correct-balance-amounts', ]; foreach ($commands as $command) { $this->friendlyLine(sprintf('Now executing command "%s"', $command)); diff --git a/app/Handlers/Observer/TransactionObserver.php b/app/Handlers/Observer/TransactionObserver.php index 1c39335bc1..1bbd8e336f 100644 --- a/app/Handlers/Observer/TransactionObserver.php +++ b/app/Handlers/Observer/TransactionObserver.php @@ -23,7 +23,10 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; +use DB; +use FireflyIII\Models\AccountBalance; use FireflyIII\Models\Transaction; +use stdClass; /** * Class TransactionObserver @@ -35,4 +38,20 @@ class TransactionObserver app('log')->debug('Observe "deleting" of a transaction.'); $transaction?->transactionJournal?->delete(); } + + public function updated(Transaction $transaction): void + { + app('log')->debug('Observe "updated" of a transaction.'); + // refresh account balance: + /** @var stdClass $result */ + $result = Transaction::groupBy(['account_id', 'transaction_currency_id'])->where('account_id', $transaction->account_id)->first(['account_id', 'transaction_currency_id', DB::raw('SUM(amount) as amount_sum')]); + if (null !== $result) { + $account = (int) $result->account_id; + $currency = (int) $result->transaction_currency_id; + $sum = $result->amount_sum; + + AccountBalance::updateOrCreate(['account_id' => $account, 'transaction_currency_id' => $currency], ['balance' => $sum]); + } + + } } diff --git a/app/Http/Controllers/DebugController.php b/app/Http/Controllers/DebugController.php index 01c8cec108..365c041f37 100644 --- a/app/Http/Controllers/DebugController.php +++ b/app/Http/Controllers/DebugController.php @@ -86,14 +86,15 @@ class DebugController extends Controller { app('preferences')->mark(); $request->session()->forget(['start', 'end', '_previous', 'viewRange', 'range', 'is_custom_range', 'temp-mfa-secret', 'temp-mfa-codes']); - app('log')->debug('Call cache:clear...'); Artisan::call('cache:clear'); - app('log')->debug('Call config:clear...'); Artisan::call('config:clear'); - app('log')->debug('Call route:clear...'); Artisan::call('route:clear'); - app('log')->debug('Call twig:clean...'); + Artisan::call('view:clear'); + + // also do some recalculations. + Artisan::call('firefly-iii:correct-balance-amounts'); + Artisan::call('firefly-iii:trigger-credit-recalculation'); try { Artisan::call('twig:clean'); @@ -101,7 +102,6 @@ class DebugController extends Controller throw new FireflyException($e->getMessage(), 0, $e); } - app('log')->debug('Call view:clear...'); Artisan::call('view:clear'); return redirect(route('index')); diff --git a/app/Models/AccountBalance.php b/app/Models/AccountBalance.php new file mode 100644 index 0000000000..d718af79d7 --- /dev/null +++ b/app/Models/AccountBalance.php @@ -0,0 +1,12 @@ +id(); + $table->timestamps(); + $table->integer('account_id', false, true); + $table->integer('transaction_currency_id', false, true); + $table->decimal('balance', 32, 12); + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); + $table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade'); + $table->unique(['account_id','transaction_currency_id'],'unique_account_currency'); + }); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('account_balances'); + } +};