mega-plant/app/api/purchases/[id]/invoices/[invoiceId]/document/route.ts
David 5f86657849 Purchase invoices, Suppliers 2 with payments, multi-page PO parsing
- Supplier invoices on purchase orders (several per PO), global Upload invoice with search and drag-drop
- PO invoice status line (red/orange/teal), week/month filter, group by supplier, drag-drop PO upload
- Suppliers 2: spend, payable by terms, cash hidden by default, manual payments with surplus/shortfall
- Fix multi-page PO parsing (per-page rows, header filter direction)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-29 20:29:08 +02:00

33 lines
1.4 KiB
TypeScript

import { serverAuth } from "@/lib/pb";
export const dynamic = "force-dynamic";
// GET /api/purchases/:id/invoices/:invoiceId/document — proxies the invoice PDF, for the
// same reason /api/invoices/:id/document does: the collection is rule-locked.
export async function GET(
_req: Request,
{ params }: { params: Promise<{ id: string; invoiceId: string }> },
) {
const { id, invoiceId } = await params;
try {
const pb = await serverAuth();
const inv = await pb.collection("purchase_invoices").getOne(invoiceId).catch(() => null);
if (!inv || inv.purchase !== id || !inv.source_pdf) {
return Response.json({ ok: false, error: "No document attached" }, { status: 404 });
}
const res = await fetch(pb.files.getURL(inv, inv.source_pdf), {
headers: pb.authStore.token ? { Authorization: pb.authStore.token } : undefined,
});
if (!res.ok) return Response.json({ ok: false, error: "Document could not be read from storage" }, { status: 502 });
return new Response(res.body, {
status: 200,
headers: {
"Content-Type": res.headers.get("Content-Type") ?? "application/pdf",
"Content-Disposition": `inline; filename="${String(inv.invoice_no).replace(/[^\w.-]/g, "_")}.pdf"`,
"Cache-Control": "private, max-age=0, must-revalidate",
},
});
} catch (e: any) {
return Response.json({ ok: false, error: e?.message || "Could not load document" }, { status: 500 });
}
}