From ed3f4f62ee09ac86789998e156262e29856bf2ee Mon Sep 17 00:00:00 2001 From: RiDEN Date: Sun, 22 Feb 2026 18:37:00 +0200 Subject: [PATCH] Fix chart API balance carry-forward bug and add missing deleted_at filter The chart loop used exact-date lookup into the range array, silently dropping transactions that fell between chart boundary dates when period > 1D. Replace with a range-walking approach that advances through all intervening entries. Also add whereNull('transaction_journals.deleted_at') to accountsBalancesOptimized() to match the daily-delta query, and fix a double-space typo in a date format string. Co-Authored-By: Claude Opus 4.6 --- .../Controllers/Chart/AccountController.php | 31 ++++++++++++------- app/Support/Steam.php | 3 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/Api/V1/Controllers/Chart/AccountController.php b/app/Api/V1/Controllers/Chart/AccountController.php index 36effec09a..4d6714e651 100644 --- a/app/Api/V1/Controllers/Chart/AccountController.php +++ b/app/Api/V1/Controllers/Chart/AccountController.php @@ -142,23 +142,30 @@ class AccountController extends Controller } // create array of values to collect. - while ($currentStart <= $params['end']) { - $format = $currentStart->format('Y-m-d'); - $label = $currentStart->toAtomString(); - $balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous; - $previous = $balance; - $currentSet['entries'][$label] = $balance; + $rangeDates = array_keys($range); + $rangeIdx = 0; + $rangeCount = count($rangeDates); - // do the same for the primary currency balance, if relevant: + while ($currentStart <= $params['end']) { + $format = $currentStart->format('Y-m-d'); + $label = $currentStart->toAtomString(); + + // Advance through all range entries up to current chart date + while ($rangeIdx < $rangeCount && $rangeDates[$rangeIdx] <= $format) { + $previous = $range[$rangeDates[$rangeIdx]]['balance']; + if ($this->convertToPrimary) { + $pcPrevious = $range[$rangeDates[$rangeIdx]]['pc_balance']; + } + ++$rangeIdx; + } + + $currentSet['entries'][$label] = $previous; $pcBalance = null; if ($this->convertToPrimary) { - $pcBalance = array_key_exists($format, $range) ? $range[$format]['pc_balance'] : $pcPrevious; - $pcPrevious = $pcBalance; - $currentSet['pc_entries'][$label] = $pcBalance; + $currentSet['pc_entries'][$label] = $pcPrevious; } - $currentStart = Navigation::addPeriod($currentStart, $period); - // $currentStart->addDay(); + $currentStart = Navigation::addPeriod($currentStart, $period); } $this->chartData[] = $currentSet; } diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 860bb4d53e..5326d6ccf1 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -87,6 +87,7 @@ class Steam ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') ->where('transaction_journals.date', $inclusive ? '<=' : '<', $date->format('Y-m-d H:i:s')) + ->whereNull('transaction_journals.deleted_at') ->groupBy(['transactions.account_id', 'transaction_currencies.code']) ->get(['transactions.account_id', 'transaction_currencies.code', DB::raw('SUM(transactions.amount) as sum_of_amount')]) ->toArray() @@ -469,7 +470,7 @@ class Steam ->transactions() ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) ->groupBy('transaction_journals.date') ->groupBy('transactions.transaction_currency_id') ->orderBy('transaction_journals.date', 'ASC')