mirror of
https://github.com/we-promise/sure.git
synced 2026-07-19 16:25:24 +00:00
Fix income trades (interest/dividend) wiping security holdings to $0 (#2673)
Income trades created via Trade::CreateForm#create_income_trade set
price: 0 on the Trade record. This zero price was ingested by
PortfolioCache#load_prices as a valid price source, causing
ForwardCalculator#build_holdings to compute holding amount = qty * 0 = $0,
and overriding the security's market price on that date.
Additionally, Balance::BaseCalculator#flows_for_date misclassified income
trades (qty=0) as sells, producing spurious non_cash_outflows.
Fixes:
- PortfolioCache#load_prices: filter out zero-price trades from trade
price sources using .select { |t| t.entryable.price&.positive? }
- Balance::BaseCalculator#flows_for_date: separate income trades from
regular trades using their qty (income trades have qty=0), so they
contribute only to cash flows, not non-cash flows
- Balance::SyncCache#converted_entries: preserve the entryable association
target on duped entries so that e.entryable.qty access doesn't N+1
Fixes #2672
This commit is contained in:
@@ -88,6 +88,29 @@ module LedgerTestingHelper
|
||||
currency: currency,
|
||||
entryable: trade
|
||||
)
|
||||
when "income_trade"
|
||||
security = Security.find_or_create_by!(ticker: entry_data[:ticker]) do |s|
|
||||
s.name = entry_data[:ticker]
|
||||
end
|
||||
|
||||
currency = entry_data[:currency] || created_account.currency
|
||||
|
||||
trade = Trade.new(
|
||||
qty: 0,
|
||||
security: security,
|
||||
price: 0,
|
||||
fee: 0,
|
||||
currency: currency,
|
||||
investment_activity_label: entry_data[:label] || "Interest"
|
||||
)
|
||||
|
||||
created_account.entries.create!(
|
||||
name: "#{entry_data[:label] || 'Interest'}: #{entry_data[:ticker]}",
|
||||
date: entry_data[:date],
|
||||
amount: -(entry_data[:amount].to_d),
|
||||
currency: currency,
|
||||
entryable: trade
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user