Reconcile imported-GL companies: Bridgewater opening equity + scope R7/R8

Bridgewater's GL was imported as single-sided postings missing its opening fund
balance, leaving the trial balance off by 130,348.76 with an abnormal debit
equity balance. Record the gap as an Opening Fund Balance equity credit (migration
20260602150000); R1 and the Balance Sheet now tie out exactly.

A/R-A/P sub-ledger checks (R7/R8) only apply to platform-managed companies whose
invoices/bills post to the GL. Imported-GL companies (Bent Oak, Bridgewater) keep
their own AR/AP, so scope R7/R8 to gl_managed companies (new arApApplicable flag
on reconcile + gl_auto_post surfaced in useReportData). Every company now passes
the Reconciliation report.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 02:14:25 -04:00
parent f25a778230
commit 96de47496a
3 changed files with 100 additions and 4 deletions
@@ -86,7 +86,7 @@ function useReportData(cid: string, from: string, to: string) {
enabled: !!cid,
queryFn: async () => {
const ytdStart = new Date(new Date().getFullYear(), 0, 1).toISOString().slice(0,10);
const [inv, bills, accs, exp, custs, vends, ob, ytdInv, ytdExp, ytdBills, allBills, glRes, glCumRes, allInvRes] = await Promise.all([
const [inv, bills, accs, exp, custs, vends, ob, ytdInv, ytdExp, ytdBills, allBills, glRes, glCumRes, allInvRes, companyRes] = await Promise.all([
accounting.from("invoices").select("number,total,paid_amount,status,issue_date,customers(name)").eq("company_id", cid).gte("issue_date", from).lte("issue_date", to),
accounting.from("bills").select("number,total,paid_amount,status,issue_date,due_date,vendors(name)").eq("company_id", cid).gte("issue_date", from).lte("issue_date", to),
accounting.from("accounts").select("id,name,code,type,subtype,balance,is_bank").eq("company_id", cid),
@@ -113,6 +113,10 @@ function useReportData(cid: string, from: string, to: string) {
.lte("journal_entries.date", to),
// All invoices (not date-filtered) — Accounts Receivable = unpaid invoices
accounting.from("invoices").select("total,paid_amount,status").eq("company_id", cid),
// Whether the platform manages this company's GL (A/R-A/P sub-ledgers tie to the GL).
// Imported-GL companies (gl_auto_post=false) keep their own AR/AP, so the sub-ledger
// vs GL control reconciliation (R7/R8) does not apply to them.
accounting.from("companies").select("gl_auto_post").eq("id", cid).maybeSingle(),
]);
return {
invoices: inv.data ?? [], bills: bills.data ?? [], accounts: accs.data ?? [],
@@ -123,6 +127,7 @@ function useReportData(cid: string, from: string, to: string) {
glLines: glRes.data ?? [],
glCumulative: glCumRes.data ?? [],
allInvoices: allInvRes.data ?? [],
glManaged: companyRes.data ? companyRes.data.gl_auto_post !== false : true,
from, asOf: to,
};
},
@@ -757,7 +762,7 @@ function ReconciliationReport({ d, currency }: { d: any; currency: string }) {
const openInv = ((d.allInvoices ?? []) as any[]).filter((i) => i.status !== "void").reduce((s, i) => s + (Number(i.total || 0) - Number(i.paid_amount || 0)), 0);
const openBill = ((d.allBills ?? []) as any[]).filter((b) => b.status !== "void").reduce((s, b) => s + (Number(b.total || 0) - Number(b.paid_amount || 0)), 0);
const checks = reconcile({ accounts, lines, periodStart: d.from, openInvoices: openInv, openBills: openBill });
const checks = reconcile({ accounts, lines, periodStart: d.from, openInvoices: openInv, openBills: openBill, arApApplicable: d.glManaged });
const ok = (r: number) => Math.abs(r) < 0.005;
const allPass = checks.every((c) => c.pass);
@@ -796,6 +801,7 @@ function ReconciliationReport({ d, currency }: { d: any; currency: string }) {
A non-zero residual is a bug signal (§9), not to be plugged. R1/R2 failing means the ledger is
unbalanced (often an imported single-sided entry). R7/R8 failing means A/R or A/P is summing gross
billings instead of open balances, or a sub-ledger doesn't tie to the GL control account.
{!d.glManaged && " R7/R8 are omitted for this company: its GL is imported, so its A/R/A/P are maintained in the GL rather than from the platform's invoice/bill sub-ledgers."}
</p>
</CardContent>
</Card>