Opening Balances: allow entering Retained Earnings + Current Year Earnings

Auto-provision "Retained Earnings" and "Current Year Earnings" equity accounts
per company so they appear as inputtable rows in the Chart of Accounts Opening
Balances grid. The Balance Sheet folds the posted "Current Year Earnings"
account into the Net Income line (already did this for Retained Earnings), so a
mid-year import can seed both equity figures without entering income/expense
detail, and Total Equity stays balanced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 18:11:01 -04:00
parent f3b81eaeeb
commit 7fd8ad2c52
2 changed files with 32 additions and 3 deletions
+10 -3
View File
@@ -1174,14 +1174,21 @@ function buildBalanceSheet(d: any, p?: any, useCompare?: boolean): StructuredRep
// A real "Retained Earnings" equity account is postable via journal entries.
// Fold its posted balance into the calculated "Retained Earnings (prior years)"
// line so manual JE adjustments show there instead of as a separate line.
// Posted "Retained Earnings" and "Current Year Earnings" equity accounts are
// postable via journal entries / opening balances. Fold their balances into the
// calculated prior-years and Net Income lines (instead of separate lines) so the
// figures the user enters in Opening Balances show up where expected.
const reAccts = equityAccs.filter((a) => /retained\s+earnings/i.test(String(a.name || "")));
const reIds = new Set(reAccts.map((a) => a.id));
const otherEquity = equityAccs.filter((a) => !reIds.has(a.id));
const cyeAccts = equityAccs.filter((a) => /current\s*year\s*earnings/i.test(String(a.name || "")));
const foldedIds = new Set([...reAccts, ...cyeAccts].map((a) => a.id));
const otherEquity = equityAccs.filter((a) => !foldedIds.has(a.id));
for (const a of otherEquity) rows.push({ kind: "sub", label: a.name, code: a.code ?? undefined, amount: balOf(a), compare: cmp(balOfP(a)), accountId: a.id });
const rePosted = reAccts.reduce((s, a) => s + balOf(a), 0);
const rePostedP = prev ? reAccts.reduce((s, a) => s + (prev.glByAcct.get(a.id) ?? 0), 0) : undefined;
const cyePosted = cyeAccts.reduce((s, a) => s + balOf(a), 0);
const cyePostedP = prev ? cyeAccts.reduce((s, a) => s + (prev.glByAcct.get(a.id) ?? 0), 0) : undefined;
rows.push({ kind: "sub", label: "Retained Earnings (prior years)", amount: cur.rePrior + rePosted, compare: cmp(prev ? prev.rePrior + (rePostedP ?? 0) : undefined) });
rows.push({ kind: "sub", label: "Net Income", amount: cur.cye, compare: cmp(prev?.cye) });
rows.push({ kind: "sub", label: "Net Income", amount: cur.cye + cyePosted, compare: cmp(prev ? prev.cye + (cyePostedP ?? 0) : undefined) });
const totalE = sumBal(equityAccs) + cur.rePrior + cur.cye;
const totalEP = prev ? (sumBalP(equityAccs)! + prev.rePrior + prev.cye) : undefined;
rows.push({ kind: "total", label: "Total Equity", amount: totalE, compare: cmp(totalEP) });