Added Wizard for Month/Year End Close

This commit is contained in:
2026-06-09 18:48:52 -05:00
parent 9a9f890494
commit 599465bdac
15 changed files with 1374 additions and 25 deletions

View File

@@ -270,6 +270,8 @@ function createAsset(body, userId, companyId) {
const created = now();
const input = normalizeAssetInput(body);
if (companyId) input.entity_id = companyId; // new assets belong to the active company
// A new capitalization can't land in a closed period (gated by the primary book's locks).
require('./closePeriods').assertSubledgerOpen(input.entity_id, input.in_service_date || input.acquired_date);
const result = tx(() => {
input.asset_id = resolveNewAssetId(input); // category ID template, else default sequence
const insert = run(
@@ -293,6 +295,14 @@ function updateAsset(id, body, userId, companyId) {
const input = normalizeAssetInput({ ...before, ...body });
if (companyId) input.entity_id = companyId; // assets stay within their company in phase 1
// Block changes to the financial dates/cost that would fall in a closed period (either the old or the
// new value), so a locked period's subledger can't be altered. Other field edits are unaffected.
const financialChanged = ['in_service_date', 'acquired_date', 'acquisition_cost'].some((f) => String(before[f] ?? '') !== String(input[f] ?? ''));
if (financialChanged) {
const guard = require('./closePeriods');
guard.assertSubledgerOpen(input.entity_id, before.in_service_date || before.acquired_date);
guard.assertSubledgerOpen(input.entity_id, input.in_service_date || input.acquired_date);
}
// When depreciation-critical fields change, the caller chooses when the change applies.
// 'placed_in_service' rebuilds the whole schedule by clearing prior depreciation;
// 'going_forward' keeps depreciation already recorded (the stored prior depreciation).