From b5f6c0e16b46103cdf7effcdf5a267f4809737db Mon Sep 17 00:00:00 2001 From: David Date: Thu, 8 Oct 2026 21:45:42 +0200 Subject: [PATCH] Attach the uploaded PDF to the invoice it creates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Importing a PDF built the invoice from that file's figures but stored the file only on the intake row, never on `invoices.source_pdf`. Every invoice therefore opened on a "drop the PDF here to attach it" prompt — asking for the very file the person had just uploaded to create it, and leaving every figure on the page without its source one click away. The intake now writes the document onto the invoice as part of the import, so "Open invoice PDF" is there from the moment the invoice exists. The manual uploader stays as a Replace. Verified end to end: the document endpoint returns 200, application/pdf, 49,085 bytes starting %PDF-, and the drop prompt is gone from the expanded detail. --- app/api/invoices/intake/route.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/api/invoices/intake/route.ts b/app/api/invoices/intake/route.ts index 0648122..bbcb102 100644 --- a/app/api/invoices/intake/route.ts +++ b/app/api/invoices/intake/route.ts @@ -149,6 +149,7 @@ export async function POST(req: Request) { const bookedYear = periodEnd.getUTCFullYear(); let invoiceRec; + const safeFileName = file.name.replace(/[^\w.\- ]+/g, "_").slice(-120); try { invoiceRec = await pb.collection("invoices").create({ invoice_no: parsed.invoice_no, @@ -165,6 +166,12 @@ export async function POST(req: Request) { currency: parsed.currency, vat_reg_no: parsed.vat_reg_no, source_file: file.name, + // The document the figures were READ FROM is attached to the invoice as part of + // the import. Previously it was stored only on the intake row, so every invoice + // opened on a "drop the PDF here to attach it" prompt — asking for the very file + // the person had just uploaded to create it. Every figure on the page is + // transcribed from this PDF, so it belongs beside them. + source_pdf: new File([bytes], safeFileName, { type: "application/pdf" }), subtotal: parsed.subtotal, escalation: parsed.escalation, vat: parsed.vat,