mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 01:40:01 +00:00
AR Aging (Property): label each unit with its current owner
The per-unit aging picked an arbitrary (often moved-out) owner for the unit label. Fetch owner status/is_primary and prefer the active, primary owner per unit so balances are never tagged to a former owner. Aging is already keyed by unit (funds attach to the unit, not the owner). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -83,8 +83,13 @@ export function ARAgingPropertyReport({ companyId, companyName, logoUrl, to: pro
|
|||||||
for (const u of units) unitById.set(u.id, u);
|
for (const u of units) unitById.set(u.id, u);
|
||||||
const ownerById = new Map<string, OwnerInfo>();
|
const ownerById = new Map<string, OwnerInfo>();
|
||||||
for (const o of owners) ownerById.set(o.id, o);
|
for (const o of owners) ownerById.set(o.id, o);
|
||||||
|
// Show the CURRENT owner per unit (active + primary first) so a unit's
|
||||||
|
// balance is never labeled with a moved-out owner. Funds attach to the unit.
|
||||||
const ownerByUnit = new Map<string, OwnerInfo>();
|
const ownerByUnit = new Map<string, OwnerInfo>();
|
||||||
for (const o of owners) if (o.unit_id && !ownerByUnit.has(o.unit_id)) ownerByUnit.set(o.unit_id, o);
|
const ownerRank = (o: OwnerInfo) =>
|
||||||
|
((o.status == null || o.status === "active") ? 0 : 2) + (o.is_primary ? 0 : 1);
|
||||||
|
for (const o of [...owners].sort((a, b) => ownerRank(a) - ownerRank(b)))
|
||||||
|
if (o.unit_id && !ownerByUnit.has(o.unit_id)) ownerByUnit.set(o.unit_id, o);
|
||||||
|
|
||||||
// Latest collection status per unit (rows came back newest-first)
|
// Latest collection status per unit (rows came back newest-first)
|
||||||
const collByUnit = new Map<string, string>();
|
const collByUnit = new Map<string, string>();
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ export type OwnerInfo = {
|
|||||||
first_name: string | null;
|
first_name: string | null;
|
||||||
last_name: string | null;
|
last_name: string | null;
|
||||||
unit_id: string | null;
|
unit_id: string | null;
|
||||||
|
status: string | null;
|
||||||
|
is_primary: boolean | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function fetchAssociationId(companyId: string): Promise<string | null> {
|
export async function fetchAssociationId(companyId: string): Promise<string | null> {
|
||||||
@@ -73,7 +75,7 @@ export async function fetchOwnerLedger(associationId: string, asOf: string): Pro
|
|||||||
export async function fetchUnitsAndOwners(associationId: string): Promise<{ units: UnitInfo[]; owners: OwnerInfo[] }> {
|
export async function fetchUnitsAndOwners(associationId: string): Promise<{ units: UnitInfo[]; owners: OwnerInfo[] }> {
|
||||||
const [unitsRes, ownersRes] = await Promise.all([
|
const [unitsRes, ownersRes] = await Promise.all([
|
||||||
supabase.from("units").select("id, unit_number, address, account_number").eq("association_id", associationId),
|
supabase.from("units").select("id, unit_number, address, account_number").eq("association_id", associationId),
|
||||||
supabase.from("owners").select("id, first_name, last_name, unit_id").eq("association_id", associationId),
|
supabase.from("owners").select("id, first_name, last_name, unit_id, status, is_primary").eq("association_id", associationId),
|
||||||
]);
|
]);
|
||||||
return {
|
return {
|
||||||
units: (unitsRes.data ?? []) as UnitInfo[],
|
units: (unitsRes.data ?? []) as UnitInfo[],
|
||||||
|
|||||||
Reference in New Issue
Block a user