From c400b4c69b2c35d66cb42952632871caecb9ee1a Mon Sep 17 00:00:00 2001 From: SJCoetz Date: Thu, 30 Jul 2026 15:45:49 +0200 Subject: [PATCH] feat(process-modal): show resolved supplier on Recent Orders rows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Process Order Item modal already fetched order_items history with the supplier id, but the rendered row only showed description, order number, cost, selling, and markup — leaving the operator to guess which supplier fulfilled each past order. Now each Recent Orders row also shows the resolved supplier name, tinted with the same deterministic supplier colour used by the buyer-tasks cards (djb2 → 18-swatch palette). The id is looked up locally against the modal's existing `suppliers` prop — no extra PB expand needed. Unknown supplier ids (e.g. supplier deleted since the past order) are silently omitted rather than surfaced as a stale id. Two new tests cover the resolved-name and missing-id cases. Co-Authored-By: Claude Opus 4.8 Co-authored-by: Orca --- .../order-sprint-process-modal.test.tsx | 66 +++++++++++++++++ src/components/order-sprint-process-modal.tsx | 71 ++++++++++++------- 2 files changed, 113 insertions(+), 24 deletions(-) diff --git a/src/components/order-sprint-process-modal.test.tsx b/src/components/order-sprint-process-modal.test.tsx index 8f1b497..4946a3e 100644 --- a/src/components/order-sprint-process-modal.test.tsx +++ b/src/components/order-sprint-process-modal.test.tsx @@ -307,6 +307,72 @@ describe("OrderSprintProcessModal", () => { ).toBeInTheDocument(); }); + it("shows the resolved supplier name on each Recent Orders row", async () => { + // The history fetch is the FIRST getList call (PB returns the + // most recent matching order_items). Seed it with a row whose + // supplier id maps to "Steel Co" in our suppliers list — the + // row should render that name so the operator can see who + // supplied it last time without expanding the PB relation. + getListMock.mockResolvedValueOnce({ + items: [{ + id: "hist-1", + description: "HSS drill bit", + sku: "DRL-001", + supplier: "sup-1", + cost_price: 20, + selling_price: 50, + markup: 150, + order: "order-prev", + updated: "2026-07-01", + expand: { order: { order_number: "ORD-PREV" } }, + }], + totalItems: 1, + totalPages: 1, + }); + // Subsequent fetches (price_list) stay empty. + getListMock.mockResolvedValue({ items: [], totalItems: 0, totalPages: 1 }); + + renderModal(); + await waitFor(() => { + expect(screen.getByText("Steel Co")).toBeInTheDocument(); + }); + // Order number + cost + selling still show alongside. + expect(screen.getByText("ORD-PREV")).toBeInTheDocument(); + expect(screen.getByText(/R20\.00/)).toBeInTheDocument(); + }); + + it("omits the supplier chip when the history row's supplier id is not in the suppliers list", async () => { + getListMock.mockResolvedValueOnce({ + items: [{ + id: "hist-1", + description: "HSS drill bit", + sku: "DRL-001", + supplier: "sup-deleted", + cost_price: 20, + selling_price: 50, + markup: 150, + order: "order-prev", + updated: "2026-07-01", + expand: { order: { order_number: "ORD-PREV" } }, + }], + totalItems: 1, + totalPages: 1, + }); + getListMock.mockResolvedValue({ items: [], totalItems: 0, totalPages: 1 }); + + renderModal(); + await waitFor(() => { + expect(screen.getByText("ORD-PREV")).toBeInTheDocument(); + }); + // The unknown supplier id should not be surfaced as a fallback + // — the chip is omitted entirely so the operator doesn't see a + // stale id. (Both "Steel Co" and "Bolt Suppliers" appear in the + // mocked SupplierSearch