diff --git a/supabase/functions/buildium-payee-backfill/index.ts b/supabase/functions/buildium-payee-backfill/index.ts index 9c61074..543043a 100644 --- a/supabase/functions/buildium-payee-backfill/index.ts +++ b/supabase/functions/buildium-payee-backfill/index.ts @@ -156,11 +156,46 @@ Deno.serve(async (req) => { if (gid) glIds.add(gid); } const allGlIds = [...glIds]; + const CHUNK = 50; + + // report mode: pull /v1/generalledger (signed amounts, debit +/credit −) and + // sum net movement per account for the window, to diff against our books. + if (mode === "report") { + const glMeta = new Map(); + const collectMeta = (g: any) => { + if (g?.Id) glMeta.set(String(g.Id), { number: String(g.AccountNumber ?? ""), name: String(g.Name ?? ""), type: String(g.Type ?? "") }); + if (Array.isArray(g.SubAccounts)) for (const s of g.SubAccounts) collectMeta(s); + }; + for (const g of glAccounts) collectMeta(g); + const netById = new Map(); + const txnIds = new Set(); + for (let i = 0; i < allGlIds.length; i += CHUNK) { + const params = new URLSearchParams(); + params.set("accountingbasis", "Accrual"); + params.set("startdate", dateFrom); + params.set("enddate", dateTo); + params.set("entitytype", "Association"); + params.set("entityid", String(bAssocId)); + for (const id of allGlIds.slice(i, i + CHUNK)) params.append("glaccountids", id); + const ledgers = await buildiumFetchAll("/v1/generalledger", clientId, clientSecret, params); + for (const ledger of ledgers) { + const gid = String(ledger.GLAccountId ?? ledger.GLAccount?.Id ?? ""); + for (const e of ledger.Entries ?? []) { + netById.set(gid, (netById.get(gid) ?? 0) + (Number(e.Amount) || 0)); + if (e.Id) txnIds.add(String(e.Id)); + } + } + } + const rows = [...netById.entries()] + .map(([gid, net]) => ({ ...(glMeta.get(gid) ?? { number: "", name: gid, type: "" }), net: Math.round(net * 100) / 100 })) + .filter((r) => Math.abs(r.net) > 0.005) + .sort((a, b) => a.number.localeCompare(b.number)); + return json({ mode, company: company.name, window: [dateFrom, dateTo], distinctTxns: txnIds.size, accounts: rows.length, rows }); + } // Pull GL transactions for the window. /v1/generalledger/transactions is the // Journal view — one row per transaction with its Id, type and party data. const txById = new Map(); - const CHUNK = 50; for (let i = 0; i < allGlIds.length; i += CHUNK) { const params = new URLSearchParams(); params.set("startdate", dateFrom);