This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { errorResponse, requireRole, ApiError } from "@/lib/api";
|
||||
import { renderPurchaseOrder } from "@/lib/pdf";
|
||||
|
||||
export async function GET(_req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
|
||||
try {
|
||||
await requireRole("admin");
|
||||
const { id } = await ctx.params;
|
||||
|
||||
const po = await prisma.purchaseOrder.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
project: { select: { code: true, name: true } },
|
||||
lines: {
|
||||
include: {
|
||||
fastener: { select: { partNumber: true, description: true, supplier: true, unitCost: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!po) throw new ApiError(404, "not_found", "Purchase order not found");
|
||||
|
||||
const pdf = await renderPurchaseOrder({
|
||||
po: {
|
||||
id: po.id,
|
||||
vendor: po.vendor,
|
||||
status: po.status,
|
||||
createdAt: po.createdAt,
|
||||
sentAt: po.sentAt,
|
||||
notes: po.notes,
|
||||
},
|
||||
project: po.project,
|
||||
lines: po.lines.map((l) => ({
|
||||
partNumber: l.fastener.partNumber,
|
||||
description: l.fastener.description,
|
||||
supplier: l.fastener.supplier,
|
||||
qty: l.qty,
|
||||
// line-level cost overrides the fastener's default if set
|
||||
unitCost: l.unitCost ?? l.fastener.unitCost ?? null,
|
||||
})),
|
||||
});
|
||||
|
||||
const safeName = `PO-${po.id.slice(0, 8)}.pdf`;
|
||||
return new NextResponse(pdf as unknown as BodyInit, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": "application/pdf",
|
||||
"Content-Disposition": `inline; filename="${safeName}"`,
|
||||
"Cache-Control": "private, no-store",
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
return errorResponse(err);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user