From 64cd8c72e75abcb6b2d5c04c203fb35a36f0e7dd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 10:13:11 +0000 Subject: [PATCH] Address review feedback for dashboard outflows investment contributions Agent-Logs-Url: https://github.com/we-promise/sure/sessions/81bb8eeb-1c0b-4a7f-b939-187061c41f22 Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> --- app/controllers/pages_controller.rb | 20 +++++++++++--------- test/controllers/pages_controller_test.rb | 10 +++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index e2ff9f22a..8739f976b 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -351,9 +351,8 @@ class PagesController < ApplicationController end donut_total = total + investment_contributions_total - categories = categories - .reject { |category| category[:amount].zero? } - .sort_by { |category| -category[:amount] } + categories.reject! { |category| category[:amount].zero? } + categories.sort_by! { |category| -category[:amount] } categories.each do |category| category[:percentage] = donut_total.zero? ? 0 : ((category[:amount] / donut_total) * 100).round(1) @@ -362,6 +361,9 @@ class PagesController < ApplicationController { categories: categories, total: donut_total.to_f.round(2), currency: net_totals.currency, currency_symbol: currency_symbol } end + # Total transfer outflows to investment/crypto accounts for dashboard outflow visibility. + # These transactions are excluded from budget/report expense analytics, but still shown + # in outflows so users can track where cash moved during the selected period. def investment_contributions_outflow_total(period) scope = Current.family.transactions .visible @@ -369,12 +371,12 @@ class PagesController < ApplicationController .in_period(period) .where(kind: "investment_contribution") .joins(entry: :account) - .joins(<<~SQL.squish) - LEFT JOIN exchange_rates er - ON er.date = entries.date - AND er.from_currency = entries.currency - AND er.to_currency = #{ActiveRecord::Base.connection.quote(Current.family.currency)} - SQL + .joins(ApplicationRecord.sanitize_sql_array( + [ + "LEFT JOIN exchange_rates er ON er.date = entries.date AND er.from_currency = entries.currency AND er.to_currency = ?", + Current.family.currency + ] + )) .merge(Account.included_in_finances_for(Current.user)) scope.sum("ABS(entries.amount * COALESCE(er.rate, 1))") diff --git a/test/controllers/pages_controller_test.rb b/test/controllers/pages_controller_test.rb index 6669367d5..a8e12330b 100644 --- a/test/controllers/pages_controller_test.rb +++ b/test/controllers/pages_controller_test.rb @@ -55,7 +55,15 @@ class PagesControllerTest < ActionDispatch::IntegrationTest get root_path assert_response :ok - assert_select "#outflows-donut-section", text: /#{Regexp.escape(Category.investment_contributions_name)}/ + expected_name = Category.investment_contributions_name + assert_select "#outflows-donut-section", text: /#{Regexp.escape(expected_name)}/ + + donut_node = Nokogiri::HTML(response.body).at_css("[data-controller='donut-chart']") + segments = JSON.parse(donut_node["data-donut-chart-segments-value"]) + contribution_segment = segments.find { |segment| segment["name"] == expected_name } + + assert_not_nil contribution_segment + assert_equal 300.0, contribution_segment["amount"] end test "changelog" do