import autoTable from "jspdf-autotable"; import { createBrandedPdf, addBrandedFooter, COLORS, TABLE_HEAD_STYLES, TABLE_BODY_STYLES, TABLE_STYLES, } from "./pdf-template"; interface SupplierPackingPdfItem { part_number: string; component_name: string; quantity: number; used_in_products: string | null; } interface SupplierPackingPdfData { packing_number: string; created_at: string; supplier_name: string; supplier_code: string; supplier_email?: string | null; supplier_phone?: string | null; supplier_address?: string | null; supplier_contact?: string | null; notes?: string | null; items: SupplierPackingPdfItem[]; } export function generateSupplierPackingPdf(data: SupplierPackingPdfData) { const { doc, contentY } = createBrandedPdf({ title: "SUPPLIER PACKING LIST", documentNumber: data.packing_number, date: new Date(data.created_at).toLocaleDateString("en-GB"), recipient: { label: "SUPPLIER", name: data.supplier_name, code: data.supplier_code, contact: data.supplier_contact, address: data.supplier_address, phone: data.supplier_phone, email: data.supplier_email, }, }); const pageWidth = doc.internal.pageSize.getWidth(); const margin = 14; const contentWidth = pageWidth - margin * 2; // --- Summary bar --- let y = contentY; const totalQty = data.items.reduce((sum, item) => sum + item.quantity, 0); doc.setFillColor(...COLORS.bgLight); doc.setDrawColor(...COLORS.border); doc.setLineWidth(0.2); doc.roundedRect(margin, y, contentWidth, 14, 1.5, 1.5, "FD"); const summaryItems = [ { label: "Total Components", value: String(data.items.length) }, { label: "Total Quantity", value: String(totalQty) }, ]; summaryItems.forEach((item, i) => { const x = margin + 4 + i * (contentWidth / 2); doc.setFontSize(6.5); doc.setFont("helvetica", "normal"); doc.setTextColor(...COLORS.muted); doc.text(item.label, x, y + 5); doc.setFontSize(9); doc.setFont("helvetica", "bold"); doc.setTextColor(...COLORS.primary); doc.text(item.value, x, y + 11); }); y += 20; // --- Components table --- doc.setFontSize(9); doc.setFont("helvetica", "bold"); doc.setTextColor(...COLORS.primary); doc.text("Components", margin, y); y += 4; const tableData = data.items.map((item, i) => [ String(i + 1), item.part_number, item.component_name, String(item.quantity), item.used_in_products || "-", ]); autoTable(doc, { startY: y, head: [["#", "Part Number", "Name", "Qty", "Used In Products"]], body: tableData, theme: "grid", headStyles: TABLE_HEAD_STYLES, bodyStyles: TABLE_BODY_STYLES, alternateRowStyles: { fillColor: [252, 252, 252] }, columnStyles: { 0: { cellWidth: 12, halign: "center" }, 1: { cellWidth: 32, font: "courier" }, 2: { cellWidth: 45 }, 3: { cellWidth: 16, halign: "center" }, 4: { cellWidth: "auto" }, }, margin: { left: margin, right: margin }, styles: TABLE_STYLES, }); // --- Notes --- // eslint-disable-next-line @typescript-eslint/no-explicit-any const finalY = (doc as any).lastAutoTable?.finalY || y + 30; if (data.notes) { const noteY = finalY + 6; doc.setFillColor(...COLORS.bgLight); doc.setDrawColor(...COLORS.border); doc.setLineWidth(0.2); doc.roundedRect(margin, noteY, contentWidth, 16, 1.5, 1.5, "FD"); doc.setFontSize(6.5); doc.setFont("helvetica", "bold"); doc.setTextColor(...COLORS.accent); doc.text("NOTES", margin + 4, noteY + 5); doc.setFontSize(7.5); doc.setFont("helvetica", "normal"); doc.setTextColor(...COLORS.secondary); const noteLines = doc.splitTextToSize(data.notes, contentWidth - 8); doc.text(noteLines, margin + 4, noteY + 11); } addBrandedFooter(doc); return doc; }