Files
sure/app/javascript/controllers/drawer_cost_basis_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

34 lines
1.1 KiB
JavaScript

import { Controller } from "@hotwired/stimulus"
// Handles the inline cost basis editor in the holding drawer.
// Shows/hides the form and handles bidirectional total <-> per-share conversion.
export default class extends Controller {
static targets = ["form", "total", "perShare", "perShareValue"]
static values = { qty: Number }
toggle(event) {
event.preventDefault()
this.formTarget.classList.toggle("hidden")
}
// Called when user types in total cost basis field
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 per-share field
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)
}
}