fix: allow refreshes from the same source for cost basis updates (#917)

* fix: allow refreshes from the same source for cost basis updates

* test: update cost basis priority expectations
This commit is contained in:
Ang Wei Feng (Ted)
2026-02-07 01:30:50 +08:00
committed by GitHub
parent 6779951194
commit b88734fb5e
4 changed files with 36 additions and 6 deletions

View File

@@ -75,4 +75,22 @@ class Holding::MaterializerTest < ActiveSupport::TestCase
assert_equal BigDecimal("180.00"), holding.cost_basis,
"Trade-derived cost_basis should override provider cost_basis when available"
end
test "recalculates calculated cost_basis when new trades are added" do
date = Date.current
create_trade(@aapl, account: @account, qty: 1, price: 3000, date: date)
Holding::Materializer.new(@account, strategy: :forward).materialize_holdings
holding = @account.holdings.find_by!(security: @aapl, date: date, currency: "USD")
assert_equal "calculated", holding.cost_basis_source
assert_equal BigDecimal("3000.0"), holding.cost_basis
create_trade(@aapl, account: @account, qty: 1, price: 2500, date: date)
Holding::Materializer.new(@account, strategy: :forward).materialize_holdings
holding.reload
assert_equal "calculated", holding.cost_basis_source
assert_equal BigDecimal("2750.0"), holding.cost_basis
end
end

View File

@@ -129,17 +129,18 @@ class HoldingTest < ActiveSupport::TestCase
assert_not @amzn.cost_basis_replaceable_by?("manual")
end
test "cost_basis_replaceable_by? respects priority hierarchy" do
# Provider data can be replaced by calculated or manual
test "cost_basis_replaceable_by? respects priority hierarchy and allows refreshes" do
# Provider data can be replaced by higher-priority sources (calculated/manual)
# and can be refreshed by provider again.
@amzn.update!(cost_basis: 200, cost_basis_source: "provider", cost_basis_locked: false)
assert @amzn.cost_basis_replaceable_by?("calculated")
assert @amzn.cost_basis_replaceable_by?("manual")
assert_not @amzn.cost_basis_replaceable_by?("provider")
assert @amzn.cost_basis_replaceable_by?("provider")
# Calculated data can be replaced by manual only
# Calculated data can be replaced by manual and can be refreshed by calculated again.
@amzn.update!(cost_basis: 200, cost_basis_source: "calculated", cost_basis_locked: false)
assert @amzn.cost_basis_replaceable_by?("manual")
assert_not @amzn.cost_basis_replaceable_by?("calculated")
assert @amzn.cost_basis_replaceable_by?("calculated")
assert_not @amzn.cost_basis_replaceable_by?("provider")
# Manual data when LOCKED cannot be replaced by anything