feat(assets): atomic asset disposal workflow (avyttring, utrangering, verksamhetsoverlatelse) (#1391)
* feat(assets): atomic asset disposal workflow (avyttring, utrangering, verksamhetsoverlatelse) Disposal books depreciation to the disposal date, clears cost and accumulated depreciation, books gain (3973) or loss (7973), applies output VAT on third-party sales, honors the ML 5 kap. 38 § verksamhetsoverlatelse exemption, and recalculates ML 15 kap. jamkning server-side from tax years and original input VAT. The voucher, the disposal-date depreciation schedule and the immutable register state commit in one dedicated commit_asset_disposal RPC transaction that delegates voucher numbering to commit_journal_entry. Fixes #325 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(assets): harden disposal per review and pg-real findings - commit_asset_disposal now uses the NULL-safe caller_is_company_member() guard (tenant-guard ratchet) and passes the allowed 'user_accept' commit_method instead of the unlisted 'asset_disposal' value - disposal metadata invariants validated in the RPC (non-negative proceeds/VAT, VAT requires a treatment, VAT <= gross, scrap carries no proceeds) since the RPC is independently callable - new FK and CHECK constraints added NOT VALID + VALIDATE CONSTRAINT so the migration never blocks writes on the hot journal_entries table - disposeAsset paginates fiscal periods and depreciation schedules with fetchAllRows; jamkning_remaining_years keeps a valid 0 (?? not ||) - engine imports shared AssetDisposalType/AssetJamkningDirection/ VatTreatment unions; post-commit reload retries once and logs before surfacing, so a transient read cannot masquerade as a failed disposal - dispose page parses Swedish-formatted amounts (125 000,50) and blocks submission on unparseable proceeds - assets pg tests write disposal attributes in the disposal transition itself and gain a regression test that the register is frozen after Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1c9d378df8
commit
cb3ef45f14
+14
-3
@@ -3334,6 +3334,9 @@ export type DepreciationMethod =
|
||||
| 'declining_balance_20'
|
||||
| 'restvardesavskrivning_25'
|
||||
|
||||
export type AssetDisposalType = 'sale' | 'scrap' | 'business_transfer'
|
||||
export type AssetJamkningDirection = 'increase' | 'decrease' | 'none' | 'transferred'
|
||||
|
||||
/**
|
||||
* K3 component (BFNAR 2012:1 ch 17.4: komponentavskrivning). When a
|
||||
* substantial asset (typically real estate) has significant components with
|
||||
@@ -3378,6 +3381,10 @@ export interface Asset {
|
||||
restvarde_target: number | null
|
||||
disposed_at: string | null
|
||||
disposed_proceeds: number | null
|
||||
/** How the asset left the register. Null for legacy disposal records. */
|
||||
disposal_type?: AssetDisposalType | null
|
||||
/** Posted voucher that atomically completed the disposal. */
|
||||
disposal_journal_entry_id?: string | null
|
||||
/** Output VAT on disposal proceeds (ML 3 kap 3 § / 7 kap 3 §). Defaults to
|
||||
* 0: only nonzero when the sale was momspliktig. The VAT account
|
||||
* (2611/2621/2631) is derived from disposed_vat_treatment. */
|
||||
@@ -3386,9 +3393,7 @@ export interface Asset {
|
||||
* without VAT data. Constrained by DB CHECK to the same enum as
|
||||
* VatTreatment. */
|
||||
disposed_vat_treatment: VatTreatment | null
|
||||
/** Jämkning amount per ML 8a kap 7 §: input VAT paid back on disposal
|
||||
* inside the correction period. Defaults to 0; positive number = debt
|
||||
* to the state booked on 2641 credit. */
|
||||
/** Absolute input VAT adjustment under ML (2023:200), chapter 15. */
|
||||
jamkning_amount: number
|
||||
/** Remaining months in the korrigeringstid at disposal date. Audit
|
||||
* metadata only: the booking sits on the journal entry. */
|
||||
@@ -3399,6 +3404,12 @@ export interface Asset {
|
||||
/** Original input VAT that was deducted at acquisition. Audit metadata
|
||||
* the user supplies (or the system derives from the supplier invoice). */
|
||||
jamkning_original_input_vat: number | null
|
||||
/** Current-law adjustment metadata. Old month fields remain for legacy rows. */
|
||||
jamkning_direction?: AssetJamkningDirection | null
|
||||
jamkning_remaining_years?: number | null
|
||||
jamkning_total_years?: number | null
|
||||
jamkning_original_deduction_percent?: number | null
|
||||
jamkning_new_deduction_percent?: number | null
|
||||
/** K3 component depreciation (BFNAR 2012:1 ch.17.4). When non-null, the
|
||||
* depreciation engine sums per-component linear depreciation instead of
|
||||
* applying `depreciation_method` to the asset as a whole. Null for K2
|
||||
|
||||
Reference in New Issue
Block a user