diff --git a/app/models/transaction/search.rb b/app/models/transaction/search.rb index 442324461..d60e39fb4 100644 --- a/app/models/transaction/search.rb +++ b/app/models/transaction/search.rb @@ -52,7 +52,7 @@ class Transaction::Search # because those transactions are retirement savings, not daily income/expenses. def totals @totals ||= begin - Rails.cache.fetch("transaction_search_totals/#{cache_key_base}") do + Rails.cache.fetch("transaction_search_totals/v2/#{cache_key_base}") do scope = transactions_scope # Exclude tax-advantaged accounts from totals calculation @@ -69,6 +69,14 @@ class Transaction::Search "COALESCE(SUM(CASE WHEN entries.amount < 0 AND transactions.kind NOT IN (?) THEN ABS(entries.amount * COALESCE(er.rate, 1)) ELSE 0 END), 0) as income_total", Transaction::TRANSFER_KINDS ]), + ActiveRecord::Base.sanitize_sql_array([ + "COALESCE(SUM(CASE WHEN entries.amount < 0 AND transactions.kind IN (?) THEN ABS(entries.amount * COALESCE(er.rate, 1)) ELSE 0 END), 0) as transfer_inflow_total", + Transaction::TRANSFER_KINDS + ]), + ActiveRecord::Base.sanitize_sql_array([ + "COALESCE(SUM(CASE WHEN entries.amount >= 0 AND transactions.kind IN (?) THEN ABS(entries.amount * COALESCE(er.rate, 1)) ELSE 0 END), 0) as transfer_outflow_total", + Transaction::TRANSFER_KINDS + ]), "COUNT(entries.id) as transactions_count" ) .joins( @@ -82,7 +90,9 @@ class Transaction::Search Totals.new( count: result.transactions_count.to_i, income_money: Money.new(result.income_total, family.currency), - expense_money: Money.new(result.expense_total, family.currency) + expense_money: Money.new(result.expense_total, family.currency), + transfer_inflow_money: Money.new(result.transfer_inflow_total, family.currency), + transfer_outflow_money: Money.new(result.transfer_outflow_total, family.currency) ) end end @@ -99,7 +109,7 @@ class Transaction::Search end private - Totals = Data.define(:count, :income_money, :expense_money) + Totals = Data.define(:count, :income_money, :expense_money, :transfer_inflow_money, :transfer_outflow_money) def apply_active_accounts_filter(query, active_accounts_only_filter) if active_accounts_only_filter diff --git a/app/views/transactions/_summary.html.erb b/app/views/transactions/_summary.html.erb index 117b4e933..b77853cc7 100644 --- a/app/views/transactions/_summary.html.erb +++ b/app/views/transactions/_summary.html.erb @@ -1,19 +1,39 @@ <%# locals: (totals:) %> +<%# Show Inflow/Outflow labels only when the result set contains exclusively transfers + (income and expense are both $0). For mixed filters (e.g. Expense+Transfer), + we keep Income/Expenses labels — transfer amounts aren't included in the summary + bar in that case, though the transaction list still shows both types. %> +<% show_transfers = totals.income_money.zero? && totals.expense_money.zero? && + (totals.transfer_inflow_money.amount > 0 || totals.transfer_outflow_money.amount > 0) %>
Total transactions
+<%= t("transactions.summary.total_transactions") %>
<%= totals.count.round(0) %>
Income
-- <%= totals.income_money.format %> -
+ <% if show_transfers %> +<%= t("transactions.summary.inflow") %>
++ <%= (totals.income_money + totals.transfer_inflow_money).format %> +
+ <% else %> +<%= t("transactions.summary.income") %>
++ <%= totals.income_money.format %> +
+ <% end %>Expenses
-- <%= totals.expense_money.format %> -
+ <% if show_transfers %> +<%= t("transactions.summary.outflow") %>
++ <%= (totals.expense_money + totals.transfer_outflow_money).format %> +
+ <% else %> +<%= t("transactions.summary.expenses") %>
++ <%= totals.expense_money.format %> +
+ <% end %>