#!/usr/bin/env node /** * Renders a quote PDF against live data so the layout can be checked by * eye - especially the wrapped item descriptions. * * Usage: * node --experimental-strip-types scripts/preview-quote-pdf.mjs [out.pdf] * * Example: * node --experimental-strip-types scripts/preview-quote-pdf.mjs QT-20260914-001 /tmp/quote.pdf */ import PocketBase from "pocketbase"; import fs from "node:fs/promises"; import { buildQuotePdf } from "../src/components/quotes/quotePdf.ts"; const PB_URL = process.env.POCKETBASE_URL || "https://pb.jeistk.apphub.co.za"; const PB_EMAIL = process.env.POCKETBASE_ADMIN_EMAIL || "david@wfsales.co.za"; const PB_PASSWORD = process.env.POCKETBASE_ADMIN_PASSWORD || "1234567890"; const QUOTE_NUMBER = process.argv[2] || "QT-20260914-001"; const OUT = process.argv[3] || `/tmp/quote-${QUOTE_NUMBER}.pdf`; const pb = new PocketBase(PB_URL); pb.autoCancellation(false); await pb.admins.authWithPassword(PB_EMAIL, PB_PASSWORD); const rec = await pb.collection("quotes").getFirstListItem( `quote_number = "${QUOTE_NUMBER}"`, { expand: "customerName" }, ); const cust = rec.expand?.customerName || {}; const quantities = Array.isArray(rec.quantities) ? rec.quantities : []; const unitPrices = Array.isArray(rec.unitPrices) ? rec.unitPrices : []; const itemIds = Array.isArray(rec.items) ? rec.items : []; let items = []; if (itemIds.length) { const filter = itemIds.map((id) => `id = "${id}"`).join(" || "); const stock = await pb.collection("stock_items").getList(1, 200, { filter }); const byId = new Map(stock.items.map((s) => [s.id, s])); items = itemIds.map((id, i) => ({ stockItemId: id, itemName: byId.get(id)?.name || "(item)", sku: byId.get(id)?.sku || "", sellingPrice: unitPrices[i] || 0, })); } const quote = { id: rec.id, quote_number: rec.quote_number, customerName: cust.comapny_name || "", customerRef: rec.customerRef || "", quoteDate: rec.quoteDate, validUntil: rec.validUntil, status: rec.status, quantities, unitPrices, items, customer: { name: cust.comapny_name || "", address: cust.address || "", email: cust.email || "", phone: cust.phone || "", vatNumber: cust.vatNumber || "", }, notes: rec.notes || "", }; const doc = buildQuotePdf(quote); await fs.writeFile(OUT, Buffer.from(doc.output("arraybuffer"))); console.log(`Wrote ${OUT}`); console.log(` customer: ${quote.customer.name}`); console.log(` items : ${items.length}`); for (const it of items) { console.log(` - "${it.itemName}"`); }