mirror of
https://github.com/we-promise/sure.git
synced 2026-04-25 06:54:07 +00:00
Record dividends and interest as Trades in investment accounts (#1311)
* Record dividends and interest as Trades in investment accounts
All investment income (dividends and interest) is now modeled as a
Trade with qty: 0 and price: 0, keeping security_id NOT NULL on trades
intact. Dividends require a security; interest falls back to a
per-account synthetic cash security (kind: "cash", offline: true) when
none is selected, matching how brokerages handle uninvested cash
internally.
- Add `kind` column to securities ("standard" | "cash") with DB check
constraint; `Security.cash_for(account)` lazily finds or creates the
synthetic cash security; `scope :standard` excludes synthetic
securities from user-facing pickers
- Trade::CreateForm: new `dividend` type (security required); `interest`
now creates a Trade instead of a Transaction
- Trade form: Dividend and Interest in the type dropdown with a security
combobox (required for dividend, optional for interest)
- transactions table: untouched
* UI fixes
* HealthChecker — both scopes now chain .standard to exclude cash securities from provider health checks.
DB query moved to model — Account#traded_standard_securities in app/models/account.rb, view uses account.traded_standard_securities.
DRY income creation — create_income_trade(sec:, label:, name:) extracted as shared private method; create_dividend_income and create_interest_income delegate to it.
show.html.erb blocks merged — single unless trade.qty.zero? block covers qty/price/fee fields.
Test extended — assert_response :unprocessable_entity added after the assert_no_difference block.
* Hide cash account ticker from no-security trade detail
* Fix CodeRabbit review issues from PR #1311
- Remove duplicate YAML keys in translation files (de, es, fr)
- Add error handling for security resolution in create_dividend_income
- Extract income trade check to reduce duplication in header template
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* Include holdings in dividend/interest security picker
The security picker for dividend/interest trades should include all securities
in holdings, not just those with trade history. This fixes the issue where
accounts with imported holdings (e.g., SimpleFIN) but no trades would have an
empty picker and be unable to record dividends.
Uses UNION to combine securities from both trades and holdings.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* scope picker to holdings only (a trade creates a holding anyway)
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,24 +6,35 @@ de:
|
||||
account_prompt: Konto suchen
|
||||
amount: Betrag
|
||||
holding: Tickersymbol
|
||||
holding_optional: Tickersymbol (optional)
|
||||
price: Preis pro Anteil
|
||||
qty: Menge
|
||||
submit: Transaktion hinzufügen
|
||||
ticker_placeholder: AAPL
|
||||
type: Typ
|
||||
type_buy: Kaufen
|
||||
type_sell: Verkaufen
|
||||
type_deposit: Einzahlung
|
||||
type_withdrawal: Auszahlung
|
||||
type_dividend: Dividende
|
||||
type_interest: Zinsen
|
||||
dividend_requires_security: Für Dividenden ist ein Wertpapier erforderlich
|
||||
header:
|
||||
buy: Kaufen
|
||||
sell: Verkaufen
|
||||
dividend: Dividende
|
||||
interest: Zinsen
|
||||
current_market_price_label: Aktueller Marktpreis
|
||||
overview: Übersicht
|
||||
purchase_price_label: Kaufpreis
|
||||
purchase_qty_label: Kaufmenge
|
||||
sell: Verkaufen
|
||||
symbol_label: Symbol
|
||||
total_return_label: Nicht realisierter Gewinn/Verlust
|
||||
new:
|
||||
title: Neue Transaktion
|
||||
show:
|
||||
additional: Zusätzlich
|
||||
amount_label: Betrag
|
||||
buy: Kaufen
|
||||
category_label: Kategorie
|
||||
cost_per_share_label: Kosten pro Anteil
|
||||
|
||||
@@ -7,24 +7,35 @@ en:
|
||||
amount: Amount
|
||||
fee: Transaction fee
|
||||
holding: Ticker symbol
|
||||
holding_optional: Ticker symbol (optional)
|
||||
price: Price per share
|
||||
qty: Quantity
|
||||
submit: Add transaction
|
||||
ticker_placeholder: AAPL
|
||||
type: Type
|
||||
type_buy: Buy
|
||||
type_sell: Sell
|
||||
type_deposit: Deposit
|
||||
type_withdrawal: Withdrawal
|
||||
type_dividend: Dividend
|
||||
type_interest: Interest
|
||||
dividend_requires_security: Security is required for dividends
|
||||
header:
|
||||
buy: Buy
|
||||
sell: Sell
|
||||
dividend: Dividend
|
||||
interest: Interest
|
||||
current_market_price_label: Current Market Price
|
||||
overview: Overview
|
||||
purchase_price_label: Purchase Price
|
||||
purchase_qty_label: Purchase Quantity
|
||||
sell: Sell
|
||||
symbol_label: Symbol
|
||||
total_return_label: Unrealized gain/loss
|
||||
new:
|
||||
title: New transaction
|
||||
show:
|
||||
additional: Additional
|
||||
amount_label: Amount
|
||||
buy: Buy
|
||||
category_label: Category
|
||||
cost_per_share_label: Cost per Share
|
||||
|
||||
@@ -6,24 +6,35 @@ es:
|
||||
account_prompt: Buscar cuenta
|
||||
amount: Importe
|
||||
holding: Símbolo del ticker
|
||||
holding_optional: Símbolo del ticker (opcional)
|
||||
price: Precio por acción
|
||||
qty: Cantidad
|
||||
submit: Añadir transacción
|
||||
ticker_placeholder: AAPL
|
||||
type: Tipo
|
||||
type_buy: Comprar
|
||||
type_sell: Vender
|
||||
type_deposit: Depósito
|
||||
type_withdrawal: Retiro
|
||||
type_dividend: Dividendo
|
||||
type_interest: Interés
|
||||
dividend_requires_security: Se requiere un valor para los dividendos
|
||||
header:
|
||||
buy: Comprar
|
||||
sell: Vender
|
||||
dividend: Dividendo
|
||||
interest: Interés
|
||||
current_market_price_label: Precio de mercado actual
|
||||
overview: Resumen
|
||||
purchase_price_label: Precio de compra
|
||||
purchase_qty_label: Cantidad comprada
|
||||
sell: Vender
|
||||
symbol_label: Símbolo
|
||||
total_return_label: Ganancia/pérdida no realizada
|
||||
new:
|
||||
title: Nueva transacción
|
||||
show:
|
||||
additional: Adicional
|
||||
amount_label: Importe
|
||||
buy: Compra
|
||||
category_label: Categoría
|
||||
cost_per_share_label: Costo por acción
|
||||
|
||||
@@ -6,24 +6,35 @@ fr:
|
||||
account_prompt: Rechercher un compte
|
||||
amount: Montant
|
||||
holding: Symbole boursier
|
||||
holding_optional: Symbole boursier (facultatif)
|
||||
price: Prix par action
|
||||
qty: Quantité
|
||||
submit: Ajouter la transaction
|
||||
ticker_placeholder: AAPL
|
||||
type: Type
|
||||
type_buy: Acheter
|
||||
type_sell: Vendre
|
||||
type_deposit: Dépôt
|
||||
type_withdrawal: Retrait
|
||||
type_dividend: Dividende
|
||||
type_interest: Intérêts
|
||||
dividend_requires_security: Un titre est requis pour les dividendes
|
||||
header:
|
||||
buy: Acheter
|
||||
sell: Vendre
|
||||
dividend: Dividende
|
||||
interest: Intérêts
|
||||
current_market_price_label: Prix du marché actuel
|
||||
overview: Aperçu
|
||||
purchase_price_label: Prix d'achat
|
||||
purchase_qty_label: Quantité achetée
|
||||
sell: Vendre
|
||||
symbol_label: Symbole
|
||||
total_return_label: Gain/perte non réalisé(e)
|
||||
new:
|
||||
title: Nouvelle transaction
|
||||
show:
|
||||
additional: Détails supplémentaires
|
||||
amount_label: Montant
|
||||
cost_per_share_label: Coût par action
|
||||
date_label: Date
|
||||
delete: Supprimer
|
||||
|
||||
Reference in New Issue
Block a user