1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-05 05:25:24 +02:00

Add income and spending insight cards to dashboard (#668)

* Generate time series for rolling 30 day sum of income and spending

* Highlight accounts with most income and spending in the last 30 days

* Aggregate chips after 3 top accounts in insight card

* Refactor aggregation filter

I think this is easier to read and understand whats happening at a
glance

* Refactor and tidy

* Use family currency for insight cards

* Further reduce risk of sql injection

* Fix lint

* Refactor rolling total queries

* Add test for transaction snapshot
This commit is contained in:
Josh Brown 2024-04-24 13:34:50 +01:00 committed by GitHub
parent 1f6e83ee91
commit 461fa672ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 207 additions and 64 deletions

View file

@ -1,32 +1,32 @@
date_offset,net_worth,assets,liabilities,depositories,investments,loans,credits,properties,vehicles,other_assets,other_liabilities
-30,48278.57,49318.57,1040.00,48918.57,0.00,0.00,1040.00,0.00,0.00,400.00,0.00
-29,49298.96,50238.96,940.00,49838.96,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-28,49311.01,50251.01,940.00,49851.01,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-27,49248.35,50188.35,940.00,49788.35,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-26,49200.15,50140.15,940.00,49740.15,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-25,48447.74,49387.74,940.00,48987.74,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-24,48428.46,49368.46,940.00,48968.46,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-23,48388.70,49328.70,940.00,48928.70,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-22,49502.26,50442.26,940.00,50042.26,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-21,49509.49,50449.49,940.00,50049.49,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-20,49520.33,50460.33,940.00,50060.33,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-19,49265.33,50205.33,940.00,49805.33,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-18,47267.72,48207.72,940.00,47807.72,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-17,47260.55,48200.55,940.00,47800.55,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-16,47249.80,48189.80,940.00,47789.80,0.00,0.00,940.00,0.00,0.00,400.00,0.00
-15,47175.14,48135.14,960.00,47735.14,0.00,0.00,960.00,0.00,0.00,400.00,0.00
-14,47172.75,48132.75,960.00,47732.75,0.00,0.00,960.00,0.00,0.00,400.00,0.00
-13,47166.78,48126.78,960.00,47726.78,0.00,0.00,960.00,0.00,0.00,400.00,0.00
-12,47854.20,48844.20,990.00,48144.20,0.00,0.00,990.00,0.00,0.00,700.00,0.00
-11,47830.30,48820.30,990.00,48120.30,0.00,0.00,990.00,0.00,0.00,700.00,0.00
-10,47906.78,48896.78,990.00,48196.78,0.00,0.00,990.00,0.00,0.00,700.00,0.00
-9,48022.64,49012.64,990.00,48312.64,0.00,0.00,990.00,0.00,0.00,700.00,0.00
-8,48016.64,49006.64,990.00,48306.64,0.00,0.00,990.00,0.00,0.00,700.00,0.00
-7,48011.84,49001.84,990.00,48301.84,0.00,0.00,990.00,0.00,0.00,700.00,0.00
-6,47989.04,48979.04,990.00,48279.04,0.00,0.00,990.00,0.00,0.00,700.00,0.00
-5,48154.64,49154.64,1000.00,48454.64,0.00,0.00,1000.00,0.00,0.00,700.00,0.00
-4,47195.60,48195.60,1000.00,47645.60,0.00,0.00,1000.00,0.00,0.00,550.00,0.00
-3,48096.40,49096.40,1000.00,48546.40,0.00,0.00,1000.00,0.00,0.00,550.00,0.00
-2,48032.80,49032.80,1000.00,48482.80,0.00,0.00,1000.00,0.00,0.00,550.00,0.00
-1,48064.00,49064.00,1000.00,48514.00,0.00,0.00,1000.00,0.00,0.00,550.00,0.00
0,47550.80,48550.80,1000.00,48000.80,0.00,0.00,1000.00,0.00,0.00,550.00,0.00
date_offset,net_worth,assets,liabilities,depositories,investments,loans,credits,properties,vehicles,other_assets,other_liabilities,spending,income,rolling_spend,rolling_income
-30,48278.57,49318.57,1040.00,48918.57,0.00,0.00,1040.00,0.00,0.00,400.00,0.00,0,0,0,0
-29,49298.96,50238.96,940.00,49838.96,0.00,0.00,940.00,0.00,0.00,400.00,0.00,15,1018.8,15,1018.8
-28,49311.01,50251.01,940.00,49851.01,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,1018.8
-27,49248.35,50188.35,940.00,49788.35,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,1018.8
-26,49200.15,50140.15,940.00,49740.15,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,1018.8
-25,48447.74,49387.74,940.00,48987.74,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,1018.8
-24,48428.46,49368.46,940.00,48968.46,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,1018.8
-23,48388.70,49328.70,940.00,48928.70,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,1018.8
-22,49502.26,50442.26,940.00,50042.26,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,1075,15,2093.8
-21,49509.49,50449.49,940.00,50049.49,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,2093.8
-20,49520.33,50460.33,940.00,50060.33,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,15,2093.8
-19,49265.33,50205.33,940.00,49805.33,0.00,0.00,940.00,0.00,0.00,400.00,0.00,216.44,0,231.44,2093.8
-18,47267.72,48207.72,940.00,47807.72,0.00,0.00,940.00,0.00,0.00,400.00,0.00,2000,0,2231.44,2093.8
-17,47260.55,48200.55,940.00,47800.55,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,2231.44,2093.8
-16,47249.80,48189.80,940.00,47789.80,0.00,0.00,940.00,0.00,0.00,400.00,0.00,0,0,2231.44,2093.8
-15,47175.14,48135.14,960.00,47735.14,0.00,0.00,960.00,0.00,0.00,400.00,0.00,40,0,2271.44,2093.8
-14,47172.75,48132.75,960.00,47732.75,0.00,0.00,960.00,0.00,0.00,400.00,0.00,0,0,2271.44,2093.8
-13,47166.78,48126.78,960.00,47726.78,0.00,0.00,960.00,0.00,0.00,400.00,0.00,0,0,2271.44,2093.8
-12,47854.20,48844.20,990.00,48144.20,0.00,0.00,990.00,0.00,0.00,700.00,0.00,60,50,2331.44,2143.8
-11,47830.30,48820.30,990.00,48120.30,0.00,0.00,990.00,0.00,0.00,700.00,0.00,0,0,2331.44,2143.8
-10,47906.78,48896.78,990.00,48196.78,0.00,0.00,990.00,0.00,0.00,700.00,0.00,0,0,2331.44,2143.8
-9,48022.64,49012.64,990.00,48312.64,0.00,0.00,990.00,0.00,0.00,700.00,0.00,0,103.915,2331.44,2247.715
-8,48016.64,49006.64,990.00,48306.64,0.00,0.00,990.00,0.00,0.00,700.00,0.00,0,0,2331.44,2247.715
-7,48011.84,49001.84,990.00,48301.84,0.00,0.00,990.00,0.00,0.00,700.00,0.00,0,0,2331.44,2247.715
-6,47989.04,48979.04,990.00,48279.04,0.00,0.00,990.00,0.00,0.00,700.00,0.00,0,0,2331.44,2247.715
-5,48154.64,49154.64,1000.00,48454.64,0.00,0.00,1000.00,0.00,0.00,700.00,0.00,20,200,2351.44,2447.715
-4,47195.60,48195.60,1000.00,47645.60,0.00,0.00,1000.00,0.00,0.00,550.00,0.00,863.04,0,3214.48,2447.715
-3,48096.40,49096.40,1000.00,48546.40,0.00,0.00,1000.00,0.00,0.00,550.00,0.00,0,0,3214.48,2447.715
-2,48032.80,49032.80,1000.00,48482.80,0.00,0.00,1000.00,0.00,0.00,550.00,0.00,0,0,3214.48,2447.715
-1,48064.00,49064.00,1000.00,48514.00,0.00,0.00,1000.00,0.00,0.00,550.00,0.00,0,0,3214.48,2447.715
0,47550.80,48550.80,1000.00,48000.80,0.00,0.00,1000.00,0.00,0.00,550.00,0.00,0,0,3214.48,2447.715
1 date_offset net_worth assets liabilities depositories investments loans credits properties vehicles other_assets other_liabilities spending income rolling_spend rolling_income
2 -30 48278.57 49318.57 1040.00 48918.57 0.00 0.00 1040.00 0.00 0.00 400.00 0.00 0 0 0 0
3 -29 49298.96 50238.96 940.00 49838.96 0.00 0.00 940.00 0.00 0.00 400.00 0.00 15 1018.8 15 1018.8
4 -28 49311.01 50251.01 940.00 49851.01 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 1018.8
5 -27 49248.35 50188.35 940.00 49788.35 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 1018.8
6 -26 49200.15 50140.15 940.00 49740.15 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 1018.8
7 -25 48447.74 49387.74 940.00 48987.74 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 1018.8
8 -24 48428.46 49368.46 940.00 48968.46 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 1018.8
9 -23 48388.70 49328.70 940.00 48928.70 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 1018.8
10 -22 49502.26 50442.26 940.00 50042.26 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 1075 15 2093.8
11 -21 49509.49 50449.49 940.00 50049.49 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 2093.8
12 -20 49520.33 50460.33 940.00 50060.33 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 15 2093.8
13 -19 49265.33 50205.33 940.00 49805.33 0.00 0.00 940.00 0.00 0.00 400.00 0.00 216.44 0 231.44 2093.8
14 -18 47267.72 48207.72 940.00 47807.72 0.00 0.00 940.00 0.00 0.00 400.00 0.00 2000 0 2231.44 2093.8
15 -17 47260.55 48200.55 940.00 47800.55 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 2231.44 2093.8
16 -16 47249.80 48189.80 940.00 47789.80 0.00 0.00 940.00 0.00 0.00 400.00 0.00 0 0 2231.44 2093.8
17 -15 47175.14 48135.14 960.00 47735.14 0.00 0.00 960.00 0.00 0.00 400.00 0.00 40 0 2271.44 2093.8
18 -14 47172.75 48132.75 960.00 47732.75 0.00 0.00 960.00 0.00 0.00 400.00 0.00 0 0 2271.44 2093.8
19 -13 47166.78 48126.78 960.00 47726.78 0.00 0.00 960.00 0.00 0.00 400.00 0.00 0 0 2271.44 2093.8
20 -12 47854.20 48844.20 990.00 48144.20 0.00 0.00 990.00 0.00 0.00 700.00 0.00 60 50 2331.44 2143.8
21 -11 47830.30 48820.30 990.00 48120.30 0.00 0.00 990.00 0.00 0.00 700.00 0.00 0 0 2331.44 2143.8
22 -10 47906.78 48896.78 990.00 48196.78 0.00 0.00 990.00 0.00 0.00 700.00 0.00 0 0 2331.44 2143.8
23 -9 48022.64 49012.64 990.00 48312.64 0.00 0.00 990.00 0.00 0.00 700.00 0.00 0 103.915 2331.44 2247.715
24 -8 48016.64 49006.64 990.00 48306.64 0.00 0.00 990.00 0.00 0.00 700.00 0.00 0 0 2331.44 2247.715
25 -7 48011.84 49001.84 990.00 48301.84 0.00 0.00 990.00 0.00 0.00 700.00 0.00 0 0 2331.44 2247.715
26 -6 47989.04 48979.04 990.00 48279.04 0.00 0.00 990.00 0.00 0.00 700.00 0.00 0 0 2331.44 2247.715
27 -5 48154.64 49154.64 1000.00 48454.64 0.00 0.00 1000.00 0.00 0.00 700.00 0.00 20 200 2351.44 2447.715
28 -4 47195.60 48195.60 1000.00 47645.60 0.00 0.00 1000.00 0.00 0.00 550.00 0.00 863.04 0 3214.48 2447.715
29 -3 48096.40 49096.40 1000.00 48546.40 0.00 0.00 1000.00 0.00 0.00 550.00 0.00 0 0 3214.48 2447.715
30 -2 48032.80 49032.80 1000.00 48482.80 0.00 0.00 1000.00 0.00 0.00 550.00 0.00 0 0 3214.48 2447.715
31 -1 48064.00 49064.00 1000.00 48514.00 0.00 0.00 1000.00 0.00 0.00 550.00 0.00 0 0 3214.48 2447.715
32 0 47550.80 48550.80 1000.00 48000.80 0.00 0.00 1000.00 0.00 0.00 550.00 0.00 0 0 3214.48 2447.715

View file

@ -16,7 +16,9 @@ class FamilyTest < ActiveSupport::TestCase
"date" => (Date.current + row["date_offset"].to_i.days).to_date,
"net_worth" => row["net_worth"],
"assets" => row["assets"],
"liabilities" => row["liabilities"]
"liabilities" => row["liabilities"],
"rolling_spend" => row["rolling_spend"],
"rolling_income" => row["rolling_income"]
}
end
end
@ -83,6 +85,22 @@ class FamilyTest < ActiveSupport::TestCase
end
end
test "should calculate transaction snapshot correctly" do
spending_series = @family.snapshot_transactions[:spending_series]
income_series = @family.snapshot_transactions[:income_series]
assert_equal @expected_snapshots.count, spending_series.values.count
assert_equal @expected_snapshots.count, income_series.values.count
@expected_snapshots.each_with_index do |row, index|
expected_spending = TimeSeries::Value.new(date: row["date"], value: Money.new(row["rolling_spend"].to_d))
expected_income = TimeSeries::Value.new(date: row["date"], value: Money.new(row["rolling_income"].to_d))
assert_in_delta expected_spending.value.amount, Money.new(spending_series.values[index].value).amount, 0.01
assert_in_delta expected_income.value.amount, Money.new(income_series.values[index].value).amount, 0.01
end
end
test "should exclude disabled accounts from calculations" do
assets_before = @family.assets
liabilities_before = @family.liabilities