Fix avg_cost to return per-share cost basis (#1692)

* Fix avg_cost to return per-share cost basis

* Revert "Fix avg_cost to return per-share cost basis"

This reverts commit 38c438a614.

* Normalize SimpleFIN holding cost basis

* Track SimpleFIN cost basis source field

* Add SimpleFIN cost basis normalization tests

* Update SimpleFIN value cost basis expectation

* Handle missing SimpleFIN quantity for cost basis

* Ignore missing SimpleFIN cost basis fields

* Fix SimpleFIN holdings processor test setup
This commit is contained in:
Elvis De Abreu
2026-05-07 16:31:26 -05:00
committed by GitHub
parent 7e1de420ca
commit cf31c6e398
3 changed files with 125 additions and 3 deletions

View File

@@ -124,7 +124,7 @@ class SimplefinHoldingsApplyJobTest < ActiveSupport::TestCase
# Price derived from market_value
assert_in_delta 500.0, holding.price.to_f, 0.01
# cost_basis should fall back to "value" field (45000)
assert_in_delta 45000.0, holding.cost_basis.to_f, 0.01
# cost_basis should fall back to "value" field and normalize total basis to per-share basis
assert_in_delta 450.0, holding.cost_basis.to_f, 0.01
end
end

View File

@@ -0,0 +1,95 @@
require "test_helper"
class SimplefinAccount::Investments::HoldingsProcessorTest < ActiveSupport::TestCase
setup do
@processor = SimplefinAccount::Investments::HoldingsProcessor.new(nil)
end
test "cost_basis source is used unchanged as per share basis" do
payload = {
"cost_basis" => "16.61",
"total_cost" => "9588.61",
"value" => "10108.16"
}
raw_cost_basis, source_key = @processor.send(:cost_basis_from, payload)
cost_basis = @processor.send(:normalize_cost_basis, raw_cost_basis, BigDecimal("577.279"), source_key)
assert_equal BigDecimal("16.61"), cost_basis
assert_equal "cost_basis", source_key
end
test "basis source is used unchanged as per share basis" do
payload = {
"basis" => "16.61",
"total_cost" => "9588.61"
}
raw_cost_basis, source_key = @processor.send(:cost_basis_from, payload)
cost_basis = @processor.send(:normalize_cost_basis, raw_cost_basis, BigDecimal("577.279"), source_key)
assert_equal BigDecimal("16.61"), cost_basis
assert_equal "basis", source_key
end
test "total_cost source is normalized to per share basis" do
payload = {
"total_cost" => "9588.61"
}
raw_cost_basis, source_key = @processor.send(:cost_basis_from, payload)
cost_basis = @processor.send(:normalize_cost_basis, raw_cost_basis, BigDecimal("577.279"), source_key)
assert_equal BigDecimal("9588.61") / BigDecimal("577.279"), cost_basis
assert_equal "total_cost", source_key
end
test "value source is normalized to per share basis" do
payload = {
"value" => "9588.61"
}
raw_cost_basis, source_key = @processor.send(:cost_basis_from, payload)
cost_basis = @processor.send(:normalize_cost_basis, raw_cost_basis, BigDecimal("577.279"), source_key)
assert_equal BigDecimal("9588.61") / BigDecimal("577.279"), cost_basis
assert_equal "value", source_key
end
test "total cost source with zero quantity returns nil" do
payload = {
"total_cost" => "9588.61"
}
raw_cost_basis, source_key = @processor.send(:cost_basis_from, payload)
cost_basis = @processor.send(:normalize_cost_basis, raw_cost_basis, BigDecimal("0"), source_key)
assert_nil cost_basis
assert_equal "total_cost", source_key
end
test "total cost source with nil quantity returns nil" do
payload = {
"total_cost" => "9588.61"
}
raw_cost_basis, source_key = @processor.send(:cost_basis_from, payload)
cost_basis = @processor.send(:normalize_cost_basis, raw_cost_basis, nil, source_key)
assert_nil cost_basis
assert_equal "total_cost", source_key
end
test "missing cost basis fields return nil" do
payload = {
"market_value" => "10108.16"
}
raw_cost_basis, source_key = @processor.send(:cost_basis_from, payload)
cost_basis = @processor.send(:normalize_cost_basis, raw_cost_basis, BigDecimal("577.279"), source_key)
assert_nil raw_cost_basis
assert_nil source_key
assert_nil cost_basis
end
end