diff --git a/src/pages/BillApprovalsPage.tsx b/src/pages/BillApprovalsPage.tsx index f3e5c81..51c6e87 100644 --- a/src/pages/BillApprovalsPage.tsx +++ b/src/pages/BillApprovalsPage.tsx @@ -4,7 +4,8 @@ import { supabase } from "@/integrations/supabase/client"; import { useToast } from "@/hooks/use-toast"; import { useAuth } from "@/contexts/AuthContext"; import { UserCheck, Plus, Search, Eye, Upload, X, ArrowUpDown, Edit, Trash2, MoreHorizontal, AlertTriangle, Loader2, Bell, Printer, Sparkles, Download } from "lucide-react"; -import { downloadChecksPdf, type CheckData } from "@/utils/checkPdfGenerator"; +import { generateCheckPDF, type CheckData } from "@/pages/accounting/lib/checkPdf"; +import { accounting } from "@/lib/accountingClient"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Checkbox } from "@/components/ui/checkbox"; import { Button } from "@/components/ui/button"; @@ -697,13 +698,19 @@ export default function BillApprovalsPage({ boardAssociationIds }: { boardAssoci try { const { data: userData } = await supabase.auth.getUser(); - // Load per-association check layouts (optional) - const { data: layoutsData } = await supabase - .from("check_layouts") - .select("*") - .in("association_id", assocIds); - const layoutsByAssoc: Record = {}; - (layoutsData || []).forEach((l: any) => { layoutsByAssoc[l.association_id] = l; }); + // Load the accounting company (return address = association name + mailing + // address) and the saved Check Setup settings per association, so printed + // checks match the Check Setup sample exactly. + const { data: companiesData } = await accounting + .from("companies").select("id, association_id, name, address").in("association_id", assocIds); + const companyByAssoc: Record = {}; + (companiesData || []).forEach((c: any) => { companyByAssoc[c.association_id] = c; }); + const companyIds = (companiesData || []).map((c: any) => c.id); + const settingsByCompany: Record = {}; + if (companyIds.length) { + const { data: settingsData } = await accounting.from("check_settings").select("*").in("company_id", companyIds); + (settingsData || []).forEach((s: any) => { settingsByCompany[s.company_id] = s; }); + } let totalPrinted = 0; let totalReprinted = 0; @@ -717,7 +724,10 @@ export default function BillApprovalsPage({ boardAssociationIds }: { boardAssoci const billStatusUpdates: Array<{ billId: string; checkId: string; checkNumber: string }> = []; const txInserts: any[] = []; const today = new Date().toISOString().slice(0, 10); + const todayDisplay = new Date(today + "T00:00:00").toLocaleDateString("en-US", { month: "2-digit", day: "2-digit", year: "numeric" }); const assocName = associations.find((a: any) => a.id === assocId)?.name || ""; + const company = companyByAssoc[assocId] || null; + const settings: any = company ? (settingsByCompany[company.id] || {}) : {}; // Group bills by payee (vendor) when combining is enabled. // Otherwise treat each bill as its own group. @@ -845,18 +855,27 @@ export default function BillApprovalsPage({ boardAssociationIds }: { boardAssoci } checkDataList.push({ - check_number: checkNumber, - check_date: today, + companyName: company?.name || assocName || "", + companyAddress: company?.address || undefined, + bankName: bank.bank_name || undefined, + bankAddress: settings.bank_address || undefined, + routingNumber: printIncludeMicr ? (bank.routing_number || undefined) : undefined, + accountNumber: printIncludeMicr ? (bank.account_number || undefined) : undefined, + fractionalRouting: settings.fractional_routing || undefined, + checkNumber: Number(checkNumber) || 0, + date: todayDisplay, payee, - payee_address: payeeAddress, + payeeAddress: payeeAddress || undefined, amount: totalAmount, - memo, - line_items: lineItems.length > 1 ? lineItems : null, - bank_account_name: bank.account_name, - bank_routing_number: bank.routing_number, - bank_account_number: bank.account_number, - association_name: assocName, - layout: (layoutsByAssoc[assocId] as any) || null, + memo: memo || undefined, + lineItems: lineItems.length > 1 + ? lineItems.map((li: any) => ({ + description: [li.invoice_number ? `Inv #${li.invoice_number}` : null, li.description].filter(Boolean).join(" — ") || "Payment", + amount: Number(li.amount) || 0, + })) + : undefined, + printSignature: !!settings.print_signature, + signatureDataUrl: settings.signature_url || undefined, }); } @@ -882,7 +901,24 @@ export default function BillApprovalsPage({ boardAssociationIds }: { boardAssoci } const safeName = (assocName || "association").replace(/[^a-z0-9-_]+/gi, "_"); - await downloadChecksPdf(checkDataList, `checks-${safeName}-${today}.pdf`, { includeMicr: printIncludeMicr }); + const opts: any = { + style: settings.default_style || "voucher", + position: settings.default_position || "top", + fontSize: settings.font_size || "medium", + offsetX: Number(settings.offset_x ?? 0), + offsetY: Number(settings.offset_y ?? 0), + micrOffsetY: Number(settings.micr_offset_y ?? 0), + micrGap1: Number(settings.micr_gap_1 ?? 1), + micrGap2: Number(settings.micr_gap_2 ?? 1), + fieldPositions: { ...(settings.field_positions || {}), ...(printIncludeMicr ? {} : { micr: { hidden: true } }) }, + }; + const dataUrl = generateCheckPDF(checkDataList, opts); + const a = document.createElement("a"); + a.href = dataUrl; + a.download = `checks-${safeName}-${today}.pdf`; + document.body.appendChild(a); + a.click(); + a.remove(); } const parts: string[] = [];