Add transaction fee support to trades (#1248)

Add an optional fee field (decimal, precision: 19, scale: 4) to trades.
Fee is included in the total amount calculation (qty * price + fee) for
both create and update flows. The fee field appears on both the create
and edit forms, defaults to 0, and auto-submits like other trade fields.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Serge L
2026-03-28 14:03:16 -04:00
committed by GitHub
parent 005d2fac20
commit cc7d675500
10 changed files with 123 additions and 6 deletions

View File

@@ -111,6 +111,89 @@ class TradesControllerTest < ActionDispatch::IntegrationTest
assert_redirected_to @entry.account
end
test "creates trade buy entry with fee" do
assert_difference [ "Entry.count", "Trade.count" ], 1 do
post trades_url(account_id: @entry.account_id), params: {
model: {
type: "buy",
date: Date.current,
ticker: "NVDA (NASDAQ)",
qty: 10,
price: 20,
fee: 9.95,
currency: "USD"
}
}
end
created_entry = Entry.order(created_at: :desc).first
assert_in_delta 209.95, created_entry.amount.to_f, 0.001
assert_in_delta 9.95, created_entry.trade.fee.to_f, 0.001
assert_redirected_to account_url(created_entry.account)
end
test "creates trade sell entry with fee" do
assert_difference [ "Entry.count", "Trade.count" ], 1 do
post trades_url(account_id: @entry.account_id), params: {
model: {
type: "sell",
date: Date.current,
ticker: "AAPL (NYSE)",
qty: 10,
price: 20,
fee: 9.95,
currency: "USD"
}
}
end
created_entry = Entry.order(created_at: :desc).first
# sell: signed_amount = -10 * 20 + 9.95 = -190.05
assert_in_delta(-190.05, created_entry.amount.to_f, 0.001)
assert_in_delta 9.95, created_entry.trade.fee.to_f, 0.001
assert_redirected_to account_url(created_entry.account)
end
test "creates trade buy entry without fee defaults to zero" do
post trades_url(account_id: @entry.account_id), params: {
model: {
type: "buy",
date: Date.current,
ticker: "NVDA (NASDAQ)",
qty: 10,
price: 20,
currency: "USD"
}
}
created_entry = Entry.order(created_at: :desc).first
assert_in_delta 200, created_entry.amount.to_f, 0.001
assert_equal 0, created_entry.trade.fee.to_f
end
test "update includes fee in amount" do
patch trade_url(@entry), params: {
entry: {
currency: "USD",
nature: "outflow",
entryable_attributes: {
id: @entry.entryable_id,
qty: 10,
price: 20,
fee: 9.95
}
}
}
@entry.reload
assert_in_delta 209.95, @entry.amount.to_f, 0.001
assert_in_delta 9.95, @entry.trade.fee.to_f, 0.001
end
test "creates trade buy entry" do
assert_difference [ "Entry.count", "Trade.count", "Security.count" ], 1 do
post trades_url(account_id: @entry.account_id), params: {