buildium-sync: robustly resolve bill line GL account into expense_account_id

Buildium bill imports left expense_account_id null on all bills because the
importer only read firstLine.GLAccountId, but the bill-line payload exposes the
GL id under GLAccount.Id (nested). chart_of_accounts.account_number already
stores the Buildium GL Id, so resolve the line's GL id from either shape before
mapping it. Re-syncing backfills existing bills via the update path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 20:17:07 -04:00
parent 84c8483169
commit 756ebce121
+12 -3
View File
@@ -2123,12 +2123,21 @@ Deno.serve(async (req) => {
const buildiumVendor = buildiumVendorById.get(String(bb.VendorId)) || null;
const vendorId = await ensureVendor(buildiumVendor, assocLocalId);
// Pick first line's GL account as expense account if available
// Pick first line's GL account as expense account if available.
// chart_of_accounts.account_number stores the Buildium GL Id (see the
// glaccounts upsert: account_number = String(gl.Id ...)), so resolve the
// line's GL Id from whichever shape Buildium returns it in.
const firstLine = Array.isArray(bb.Lines) && bb.Lines.length > 0 ? bb.Lines[0] : null;
let expenseAccountId: string | null = null;
if (firstLine?.GLAccountId) {
const lineGlId = firstLine
? (firstLine.GLAccountId
?? firstLine.GLAccount?.Id
?? firstLine.GLAccount?.GLAccountId
?? null)
: null;
if (lineGlId !== null && lineGlId !== undefined && String(lineGlId) !== "") {
const coa = await getCoa(assocLocalId);
expenseAccountId = coa.get(String(firstLine.GLAccountId)) || null;
expenseAccountId = coa.get(String(lineGlId)) || null;
}
let amount = Number(bb.TotalAmount ?? bb.Amount ?? 0);