Files
sure/app/javascript/controllers/cost_basis_form_controller.js
LPW bbaf7a06cc Add cost basis source tracking with manual override and lock protection (#623)
* Add cost basis tracking and management to holdings

- Added migration to introduce `cost_basis_source` and `cost_basis_locked` fields to `holdings`.
- Implemented backfill for existing holdings to set `cost_basis_source` based on heuristics.
- Introduced `Holding::CostBasisReconciler` to manage cost basis resolution logic.
- Added user interface components for editing and locking cost basis in holdings.
- Updated `materializer` to integrate reconciliation logic and respect locked holdings.
- Extended tests for cost basis-related workflows to ensure accuracy and reliability.

* Fix cost basis calculation in holdings controller

- Ensure `cost_basis` is converted to decimal for accurate arithmetic.
- Fix conditional check to properly validate positive `cost_basis`.

* Improve cost basis validation and error handling in holdings controller

- Allow zero as a valid cost basis for gifted/inherited shares.
- Add error handling with user feedback for invalid cost basis values.

---------

Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
2026-01-12 14:05:46 +01:00

31 lines
1.1 KiB
JavaScript

import { Controller } from "@hotwired/stimulus"
// Handles bidirectional conversion between total cost basis and per-share cost
// in the manual cost basis entry form.
export default class extends Controller {
static targets = ["total", "perShare", "perShareValue"]
static values = { qty: Number }
// Called when user types in the total cost basis field
// Updates the per-share display and input to show the calculated value
updatePerShare() {
const total = Number.parseFloat(this.totalTarget.value) || 0
const qty = this.qtyValue || 1
const perShare = qty > 0 ? (total / qty).toFixed(2) : "0.00"
this.perShareValueTarget.textContent = perShare
if (this.hasPerShareTarget) {
this.perShareTarget.value = perShare
}
}
// Called when user types in the per-share field
// Updates the total cost basis field with the calculated value
updateTotal() {
const perShare = Number.parseFloat(this.perShareTarget.value) || 0
const qty = this.qtyValue || 1
const total = (perShare * qty).toFixed(2)
this.totalTarget.value = total
this.perShareValueTarget.textContent = perShare.toFixed(2)
}
}