fix(invoicing): restore expand data on delivery-note PDF generation
PocketBase silently drops `expand` from the response once a `fields` projection is present, unless the expand sub-paths are explicitly listed in that same `fields` string. The `exclude_from_invoice` projection added on 2026-08-30 didn't list any `expand.*` paths, so order/company/customer all rendered blank on the delivery note PDF (e.g. DN26090702). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
95d93791f9
commit
6dc7204477
2 changed files with 37 additions and 1 deletions
|
|
@ -256,6 +256,30 @@ describe("POST /api/invoicing/delivery-note", () => {
|
|||
expect(payload.order).toBeNull();
|
||||
});
|
||||
|
||||
it("requests expand.order.* in the fields projection so PocketBase doesn't strip the expand data", async () => {
|
||||
// Root cause of a real bug (DN26090702 rendered "(no company)" /
|
||||
// "(no customer)" / "(no order number)"): PocketBase silently
|
||||
// drops `expand` from the response when a `fields` projection is
|
||||
// present, UNLESS the expand sub-paths are explicitly listed in
|
||||
// that same `fields` string (see item-intel-service.ts /
|
||||
// visits-service.ts for the established pattern). The route
|
||||
// requests `expand: "order.company,order.customer"` but the
|
||||
// `fields` projection added for `exclude_from_invoice` didn't
|
||||
// list any `expand.*` paths, so PB returned every item with
|
||||
// `expand: undefined` even though the relations were populated.
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-07-14T13:00:00.000Z"));
|
||||
|
||||
await POST(makeRequest({ orderItemIds: ["row-1", "row-2"] }) as any);
|
||||
|
||||
const [[opts]] = getFullList.mock.calls;
|
||||
const fields = (opts as { fields?: string })?.fields ?? "";
|
||||
expect(fields).toContain("expand.order.order_number");
|
||||
expect(fields).toContain("expand.order.notes");
|
||||
expect(fields).toContain("expand.order.expand.company.company");
|
||||
expect(fields).toContain("expand.order.expand.customer.customer");
|
||||
});
|
||||
|
||||
it("populates customer/company/order on the header when all items share them", async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-07-14T13:00:00.000Z"));
|
||||
|
|
|
|||
|
|
@ -225,9 +225,21 @@ export async function POST(request: NextRequest) {
|
|||
// line list. Without it the field comes back undefined and every
|
||||
// extra silently lands on the customer delivery note — the same
|
||||
// load-bearing-projection concern documented for INVOICING_FIELDS.
|
||||
//
|
||||
// The `expand.order.*` / `expand.order.expand.*` entries are
|
||||
// load-bearing too: PocketBase silently drops `expand` from the
|
||||
// response whenever a `fields` projection is present, unless the
|
||||
// expand sub-paths are explicitly listed inside that same
|
||||
// `fields` string (same pattern as item-intel-service.ts /
|
||||
// visits-service.ts). Without them, `order?.order_number`,
|
||||
// `order?.expand?.company?.company`, and
|
||||
// `order?.expand?.customer?.customer` all come back undefined
|
||||
// even though `expand: "order.company,order.customer"` below
|
||||
// asked PB to populate them — the PDF then renders "(no company)"
|
||||
// / "(no customer)" / "(no order number)".
|
||||
const items = await pb.collection("order_items").getFullList<OrderItemRecord>({
|
||||
filter: orderItemIds.map((id) => `id = "${id}"`).join(" || "),
|
||||
fields: "id,description,delivery_note_number,order_item_details,order_item_attachements,quantity,order_qty,qty_collected,exclude_from_invoice",
|
||||
fields: "id,description,delivery_note_number,order_item_details,order_item_attachements,quantity,order_qty,qty_collected,exclude_from_invoice,expand.order.id,expand.order.order_number,expand.order.notes,expand.order.expand.company.id,expand.order.expand.company.company,expand.order.expand.customer.id,expand.order.expand.customer.customer",
|
||||
expand: "purchase_order.supplier,order.company,order.customer",
|
||||
});
|
||||
if (items.length === 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue