From f03430f09b3c1415af1d231a742247d771369c13 Mon Sep 17 00:00:00 2001 From: renee-png Date: Thu, 18 Jun 2026 14:46:52 -0400 Subject: [PATCH] Account Statement PDF: list all owners, not just primary generateLedgerStatement now prints every active owner under 'ACCOUNT HOLDER(S):' (primary first) and flows the property address and tables below the owner block so it never overlaps. Co-Authored-By: Claude Opus 4.8 --- .../unit-profile/UnitLedgerStatementPDF.tsx | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/components/unit-profile/UnitLedgerStatementPDF.tsx b/src/components/unit-profile/UnitLedgerStatementPDF.tsx index 3350abf..03bbd1c 100644 --- a/src/components/unit-profile/UnitLedgerStatementPDF.tsx +++ b/src/components/unit-profile/UnitLedgerStatementPDF.tsx @@ -22,8 +22,12 @@ export function generateLedgerStatement({ unitData, owners, entries, association const doc = new jsPDF({ unit: "pt", format: "letter" }); const m = 40; const pageW = doc.internal.pageSize.getWidth(); - const primaryOwner = owners.find((o: any) => o.is_primary) || owners[0]; - const ownerName = primaryOwner ? `${primaryOwner.first_name} ${primaryOwner.last_name}` : "Unassigned"; + // All active owners on the unit (primary first), not just the primary. + const ownerNames = [...owners] + .sort((a: any, b: any) => (b?.is_primary ? 1 : 0) - (a?.is_primary ? 1 : 0)) + .map((o: any) => `${o.first_name ?? ""} ${o.last_name ?? ""}`.trim()) + .filter(Boolean); + if (ownerNames.length === 0) ownerNames.push("Unassigned"); const propertyAddress = unitData?.address || "N/A"; // Sort entries by date ascending @@ -131,17 +135,20 @@ export function generateLedgerStatement({ unitData, owners, entries, association const totalDue = runningBalance; - // --- Header: left side --- - doc.setFont("helvetica", "bold"); + // --- Header: left side (grows with the number of owners) --- doc.setFontSize(10); - doc.text("ACCOUNT HOLDER:", m, m + 10); - doc.setFont("helvetica", "normal"); - doc.text(ownerName, m, m + 22); - + let leftY = m + 10; doc.setFont("helvetica", "bold"); - doc.text("PROPERTY ADDRESS:", m, m + 42); + doc.text(ownerNames.length > 1 ? "ACCOUNT HOLDERS:" : "ACCOUNT HOLDER:", m, leftY); doc.setFont("helvetica", "normal"); - doc.text(propertyAddress, m, m + 54); + ownerNames.forEach((name) => { leftY += 12; doc.text(name, m, leftY); }); + + leftY += 20; + doc.setFont("helvetica", "bold"); + doc.text("PROPERTY ADDRESS:", m, leftY); + doc.setFont("helvetica", "normal"); + leftY += 12; + doc.text(propertyAddress, m, leftY); // --- Header: right side --- doc.setFont("helvetica", "bold"); @@ -156,7 +163,8 @@ export function generateLedgerStatement({ unitData, owners, entries, association doc.text(`Unit: ${unitData.unit_number}`, pageW - m, m + 50, { align: "right" }); } - const startY = m + 75; + // Push the tables below whichever header column is taller (left grows with owners). + const startY = Math.max(m + 75, leftY + 18); // --- Amounts Due Breakdown table (left) --- const breakdownData = [