mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-07 22:45:20 +02:00
Additional cache columns on balances for activity view breakdowns (#2505)
* Initial schema iteration * Add new balance components * Add existing data migrator to backfill components * Update calculator test assertions for new balance components * Update flow assertions for forward calculator * Update reverse calculator flows assumptions * Forward calculator tests passing * Get all calculator tests passing * Assert flows factor
This commit is contained in:
parent
347c0a7906
commit
da2045dbd8
13 changed files with 1159 additions and 177 deletions
|
@ -11,6 +11,8 @@ class Balance::ReverseCalculator < Balance::BaseCalculator
|
|||
|
||||
# Calculates in reverse-chronological order (End of day -> Start of day)
|
||||
account.current_anchor_date.downto(account.opening_anchor_date).map do |date|
|
||||
flows = flows_for_date(date)
|
||||
|
||||
if use_opening_anchor_for_date?(date)
|
||||
end_cash_balance = derive_cash_balance_on_date_from_total(
|
||||
total_balance: account.opening_anchor_balance,
|
||||
|
@ -20,29 +22,30 @@ class Balance::ReverseCalculator < Balance::BaseCalculator
|
|||
|
||||
start_cash_balance = end_cash_balance
|
||||
start_non_cash_balance = end_non_cash_balance
|
||||
|
||||
build_balance(
|
||||
date: date,
|
||||
cash_balance: end_cash_balance,
|
||||
non_cash_balance: end_non_cash_balance
|
||||
)
|
||||
market_value_change = 0
|
||||
else
|
||||
start_cash_balance = derive_start_cash_balance(end_cash_balance: end_cash_balance, date: date)
|
||||
start_non_cash_balance = derive_start_non_cash_balance(end_non_cash_balance: end_non_cash_balance, date: date)
|
||||
|
||||
# Even though we've just calculated "start" balances, we set today equal to end of day, then use those
|
||||
# in our next iteration (slightly confusing, but just the nature of a "reverse" sync)
|
||||
output_balance = build_balance(
|
||||
date: date,
|
||||
cash_balance: end_cash_balance,
|
||||
non_cash_balance: end_non_cash_balance
|
||||
)
|
||||
|
||||
end_cash_balance = start_cash_balance
|
||||
end_non_cash_balance = start_non_cash_balance
|
||||
|
||||
output_balance
|
||||
market_value_change = market_value_change_on_date(date, flows)
|
||||
end
|
||||
|
||||
output_balance = build_balance(
|
||||
date: date,
|
||||
balance: end_cash_balance + end_non_cash_balance,
|
||||
cash_balance: end_cash_balance,
|
||||
start_cash_balance: start_cash_balance,
|
||||
start_non_cash_balance: start_non_cash_balance,
|
||||
cash_inflows: flows[:cash_inflows],
|
||||
cash_outflows: flows[:cash_outflows],
|
||||
non_cash_inflows: flows[:non_cash_inflows],
|
||||
non_cash_outflows: flows[:non_cash_outflows],
|
||||
net_market_flows: market_value_change
|
||||
)
|
||||
|
||||
end_cash_balance = start_cash_balance
|
||||
end_non_cash_balance = start_non_cash_balance
|
||||
|
||||
output_balance
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -58,13 +61,6 @@ class Balance::ReverseCalculator < Balance::BaseCalculator
|
|||
account.asset? ? entry_flows : -entry_flows
|
||||
end
|
||||
|
||||
# Reverse syncs are a bit different than forward syncs because we do not allow "reconciliation" valuations
|
||||
# to be used at all. This is primarily to keep the code and the UI easy to understand. For a more detailed
|
||||
# explanation, see the test suite.
|
||||
def use_opening_anchor_for_date?(date)
|
||||
account.has_opening_anchor? && date == account.opening_anchor_date
|
||||
end
|
||||
|
||||
# Alias method, for algorithmic clarity
|
||||
# Derives cash balance, starting from the end-of-day, applying entries in reverse to get the start-of-day balance
|
||||
def derive_start_cash_balance(end_cash_balance:, date:)
|
||||
|
@ -76,4 +72,11 @@ class Balance::ReverseCalculator < Balance::BaseCalculator
|
|||
def derive_start_non_cash_balance(end_non_cash_balance:, date:)
|
||||
derive_non_cash_balance(end_non_cash_balance, date, direction: :reverse)
|
||||
end
|
||||
|
||||
# Reverse syncs are a bit different than forward syncs because we do not allow "reconciliation" valuations
|
||||
# to be used at all. This is primarily to keep the code and the UI easy to understand. For a more detailed
|
||||
# explanation, see the test suite.
|
||||
def use_opening_anchor_for_date?(date)
|
||||
account.has_opening_anchor? && date == account.opening_anchor_date
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue