diff --git a/src/pages/accounting/components/ARAgingPropertyReport.tsx b/src/pages/accounting/components/ARAgingPropertyReport.tsx index 8c05b2e..98e1569 100644 --- a/src/pages/accounting/components/ARAgingPropertyReport.tsx +++ b/src/pages/accounting/components/ARAgingPropertyReport.tsx @@ -99,10 +99,13 @@ export function ARAgingPropertyReport({ companyId, companyName, logoUrl, to: pro if (c.owner_id && !collByOwner.has(c.owner_id)) collByOwner.set(c.owner_id, c.status); } - // Group ledger entries per unit (fall back to owner when the entry has no unit) + // Group ledger entries per unit. Entries tied only to an owner_id (often a + // former owner) are mapped to that owner's unit so the balance rolls into + // the unit and shows under its current owner — not a separate old-owner row. const byUnit = new Map(); for (const e of entries) { - const key = e.unit_id ? `u:${e.unit_id}` : e.owner_id ? `o:${e.owner_id}` : null; + const unitId = e.unit_id ?? (e.owner_id ? ownerById.get(e.owner_id)?.unit_id ?? null : null); + const key = unitId ? `u:${unitId}` : e.owner_id ? `o:${e.owner_id}` : null; if (!key) continue; const list = byUnit.get(key) ?? []; list.push(e); diff --git a/src/pages/accounting/components/PrepaidHomeownersReport.tsx b/src/pages/accounting/components/PrepaidHomeownersReport.tsx index 8d43906..72cd048 100644 --- a/src/pages/accounting/components/PrepaidHomeownersReport.tsx +++ b/src/pages/accounting/components/PrepaidHomeownersReport.tsx @@ -46,12 +46,21 @@ export function PrepaidHomeownersReport({ companyId, companyName, logoUrl, to: p for (const u of data.units) unitById.set(u.id, u); const ownerById = new Map(); for (const o of data.owners) ownerById.set(o.id, o); + // Current owner per unit (active + primary first) so balances aren't tagged + // to a moved-out owner. + const ownerRank = (o: OwnerInfo) => + ((o.status == null || o.status === "active") ? 0 : 2) + (o.is_primary ? 0 : 1); const ownerByUnit = new Map(); - for (const o of data.owners) if (o.unit_id && !ownerByUnit.has(o.unit_id)) ownerByUnit.set(o.unit_id, o); + for (const o of [...data.owners].sort((a, b) => ownerRank(a) - ownerRank(b))) + if (o.unit_id && !ownerByUnit.has(o.unit_id)) ownerByUnit.set(o.unit_id, o); + // Roll every entry up to its UNIT (funds attach to the unit). Entries tied + // only to an owner_id (often a former owner) are mapped to that owner's unit + // so old-owner credits net against the unit instead of showing separately. const bal = new Map(); for (const e of data.entries) { - const key = e.unit_id ? `u:${e.unit_id}` : e.owner_id ? `o:${e.owner_id}` : null; + const unitId = e.unit_id ?? (e.owner_id ? ownerById.get(e.owner_id)?.unit_id ?? null : null); + const key = unitId ? `u:${unitId}` : e.owner_id ? `o:${e.owner_id}` : null; if (!key) continue; bal.set(key, (bal.get(key) ?? 0) + e.debit - e.credit); }