mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 09:50:01 +00:00
Accounting: add report mode to buildium-payee-backfill
report mode pulls /v1/generalledger signed balances per account for the window so imported books can be diffed against Buildium's authoritative GL to verify completeness. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -156,11 +156,46 @@ Deno.serve(async (req) => {
|
|||||||
if (gid) glIds.add(gid);
|
if (gid) glIds.add(gid);
|
||||||
}
|
}
|
||||||
const allGlIds = [...glIds];
|
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<string, { number: string; name: string; type: string }>();
|
||||||
|
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<string, number>();
|
||||||
|
const txnIds = new Set<string>();
|
||||||
|
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
|
// Pull GL transactions for the window. /v1/generalledger/transactions is the
|
||||||
// Journal view — one row per transaction with its Id, type and party data.
|
// Journal view — one row per transaction with its Id, type and party data.
|
||||||
const txById = new Map<string, any>();
|
const txById = new Map<string, any>();
|
||||||
const CHUNK = 50;
|
|
||||||
for (let i = 0; i < allGlIds.length; i += CHUNK) {
|
for (let i = 0; i < allGlIds.length; i += CHUNK) {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set("startdate", dateFrom);
|
params.set("startdate", dateFrom);
|
||||||
|
|||||||
Reference in New Issue
Block a user