From 66d08c00be9ebc39da4d2a828831b1b9b81195bf Mon Sep 17 00:00:00 2001 From: johnnyq Date: Wed, 4 Nov 2026 14:29:01 -0500 Subject: [PATCH] Fix Transactions Money in and Money out on All accounts counting every transfer twice - a transfer is money moved between your own accounts, so across all accounts both of its lines are now left out of the totals, the Money in and Money out pills and their export, while the Transfers pill still lists them and a single account's view still counts them as money in and out of that account --- agent/transactions.php | 13 ++++++++----- functions/accounts.php | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/agent/transactions.php b/agent/transactions.php index 90f970c9a..3e340832a 100644 --- a/agent/transactions.php +++ b/agent/transactions.php @@ -90,8 +90,11 @@ $count_sql = []; foreach ($shows as $key => $s) { $count_sql[] = $key === '' ? 'COUNT(*)' : "COALESCE(SUM({$s['where']}), 0)"; } -$count_sql[] = "COALESCE(SUM(CASE WHEN 1 $show_query AND ledger.txn_amount > 0 THEN ledger.txn_amount END), 0)"; -$count_sql[] = "COALESCE(SUM(CASE WHEN 1 $show_query AND ledger.txn_amount < 0 THEN -ledger.txn_amount END), 0)"; +// Across every account a transfer is money moved between them, so Money in and Money out +// leave it out (accountLedgerShows()) - except on Transfers, where it is what is listed +$not_transfer = $all && $show !== 'transfers' ? "AND ledger.txn_kind NOT IN ('transfer_in', 'transfer_out')" : ''; +$count_sql[] = "COALESCE(SUM(CASE WHEN 1 $show_query $not_transfer AND ledger.txn_amount > 0 THEN ledger.txn_amount END), 0)"; +$count_sql[] = "COALESCE(SUM(CASE WHEN 1 $show_query $not_transfer AND ledger.txn_amount < 0 THEN -ledger.txn_amount END), 0)"; if ($transfer_cards) { $count_sql[] = "COALESCE(SUM(CASE WHEN 1 $show_query THEN -ledger.txn_amount END), 0)"; $count_sql[] = "COALESCE(SUM(CASE WHEN 1 $show_query AND ledger.other_account_type = 3 THEN -ledger.txn_amount END), 0)"; @@ -186,14 +189,14 @@ $is_card = $account && $account['type'] === 3;
Money in
-
+
Money out
-
+
@@ -428,7 +431,7 @@ $is_card = $account && $account['type'] === 3; - line count($rows) ? ' - the totals are for all of them, not just this page' : '' ?> + line count($rows) ? ' - the totals are for all of them, not just this page' : '' ?> diff --git a/functions/accounts.php b/functions/accounts.php index d26ac92de..8fd10f2bf 100644 --- a/functions/accounts.php +++ b/functions/accounts.php @@ -471,14 +471,17 @@ function accountLedgerWhat(array $row) { } /** - * The ways the ledger can be cut - ?show=. Across every account a transfer - * shows once on Transfers, from the account it left. + * The ways the ledger can be cut - ?show=. Across every account a transfer is + * money moved between them, not money in or out: Money in and Money out leave + * both of its lines out, and Transfers shows it once, from the account it left. + * On one account a transfer is money in or out of that account like any other. */ function accountLedgerShows($all_accounts = false) { + $not_transfer = $all_accounts ? " AND ledger.txn_kind NOT IN ('transfer_in', 'transfer_out')" : ''; return [ '' => ['label' => 'All', 'where' => ''], - 'in' => ['label' => 'Money in', 'icon' => 'fa-arrow-down', 'where' => 'ledger.txn_amount > 0'], - 'out' => ['label' => 'Money out', 'icon' => 'fa-arrow-up', 'where' => 'ledger.txn_amount < 0'], + 'in' => ['label' => 'Money in', 'icon' => 'fa-arrow-down', 'where' => 'ledger.txn_amount > 0' . $not_transfer], + 'out' => ['label' => 'Money out', 'icon' => 'fa-arrow-up', 'where' => 'ledger.txn_amount < 0' . $not_transfer], 'transfers' => ['label' => 'Transfers', 'icon' => 'fa-exchange-alt', 'where' => $all_accounts ? "ledger.txn_kind = 'transfer_out'" : "ledger.txn_kind IN ('transfer_in', 'transfer_out')"], 'uncleared' => ['label' => 'Uncleared', 'icon' => 'fa-hourglass-half', 'where' => 'ledger.txn_cleared_id IS NULL'], ];