diff --git a/src/pages/accounting/components/CashDisbursementReport.tsx b/src/pages/accounting/components/CashDisbursementReport.tsx index 1703d40..4e7823b 100644 --- a/src/pages/accounting/components/CashDisbursementReport.tsx +++ b/src/pages/accounting/components/CashDisbursementReport.tsx @@ -72,8 +72,9 @@ export function CashDisbursementReport({ companyId, companyName, logoUrl, from: ]); const accounts = (accountsRes.data ?? []) as GLAccount[]; const lines = (linesRes.data ?? []) as any[]; + const bankIds = new Set(accounts.filter((a) => a.is_bank).map((a) => a.id)); - // Enrich register-posted entries with check # / vendor / bill from banking + // Enrich app-posted (acmacc_txn) entries with check #/vendor/bill from banking. const txnIds = [...new Set(lines .filter((l) => l.journal_entries?.external_source === "acmacc_txn" && l.journal_entries?.external_id) .map((l) => String(l.journal_entries.external_id)))]; @@ -85,7 +86,20 @@ export function CashDisbursementReport({ companyId, companyName, logoUrl, from: .in("id", txnIds); txns = t ?? []; } - return { accounts, lines, txns }; + + // Buildium-GL (and any) payments carry their vendor/bill on the register + // transaction linked to the GL bank line via journal_entry_line_id. Pull those + // so imported disbursements show the matched vendor/bill, not "No vendor". + const bankLineIds = lines.filter((l) => Number(l.credit || 0) > 0 && bankIds.has(l.account_id)).map((l) => String(l.id)); + const linkedTxns: any[] = []; + for (let i = 0; i < bankLineIds.length; i += 200) { + const { data: tl } = await accounting + .from("transactions") + .select("journal_entry_line_id,reference,description,vendor_id,bill_id,vendors(name),bills(number,issue_date,vendors(name))") + .in("journal_entry_line_id", bankLineIds.slice(i, i + 200)); + if (tl) linkedTxns.push(...tl); + } + return { accounts, lines, txns, linkedTxns }; }, }); @@ -95,6 +109,8 @@ export function CashDisbursementReport({ companyId, companyName, logoUrl, from: for (const a of data.accounts) acctById.set(a.id, a); const txnById = new Map(); for (const t of data.txns) txnById.set(String(t.id), t); + const txnByLineId = new Map(); + for (const t of (data.linkedTxns ?? [])) if (t.journal_entry_line_id) txnByLineId.set(String(t.journal_entry_line_id), t); // Group lines per journal entry const byJe = new Map(); @@ -123,7 +139,9 @@ export function CashDisbursementReport({ companyId, companyName, logoUrl, from: const mainBank = bankCredits.reduce((a, b) => (Number(b.credit) > Number(a.credit) ? b : a)); const bankLabel = acctLabel(acctById.get(mainBank.account_id)); - const txn = je.external_source === "acmacc_txn" && je.external_id ? txnById.get(String(je.external_id)) : null; + let txn = je.external_source === "acmacc_txn" && je.external_id ? txnById.get(String(je.external_id)) : null; + // For imported (Buildium GL) payments, resolve the register txn linked to a bank line. + if (!txn) { for (const bc of bankCredits) { const lt = txnByLineId.get(String(bc.id)); if (lt) { txn = lt; break; } } } const bill = txn?.bills ?? null; // Only attribute a vendor when it's reliably linked (payment→vendor or // payment→bill→vendor). GL-pull (Buildium) disbursements carry no vendor,