WFDASH-WEBAPP/src/lib/supplier-color.test.ts
SJCoetz 172d562f06 fix(buyer-tasks): generate PO succeeds + supplier stripe + PO badge
generatePoForGroup was creating purchase_orders records without
`po_number`, which is required by the PB schema. PB rejected the
create with 500 ("Failed to create record.") and the operator never
got a PO. Fix:

- New src/lib/server/po-number.ts — server-side generatePONumber()
  that mirrors the client version in pb-helpers.ts (PO-YYYY-MM-NNN
  format) but uses getAdminPocketBase(). Per the data-access rules,
  don't extend pb-helpers.ts; server business logic lives under
  lib/server/.
- generatePoForGroup now generates the PO number, includes
  total_amount (sum of costPrice * quantity) and order_item
  (back-link to the items) in the create payload — mirrors the
  canonical /orders/[id]/process PO-creation flow so the PB admin
  row shows related lines without an extra getList call.
- Test updated to assert the new payload (po_number regex,
  total_amount computed, order_item back-link).

UI while here:
- BuyerTaskGroupCard now renders a deterministic supplier colour
  stripe on the left edge. New src/lib/supplier-color.ts hashes the
  supplierId into a small Tailwind 600 palette (18 colours) so the
  same supplier always shows the same colour, and the supplier name
  gets tinted with the same colour for quick scanning.
- PO number is now shown prominently at the top of the card (in a
  warm-toned badge that matches the AI Insights theme) when one
  exists — po_draft and po_sent tabs. Needs PO tab omits it.

Co-authored-by: Orca <help@stably.ai>
2026-07-30 15:00:18 +02:00

28 lines
No EOL
1.1 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { supplierColor } from "./supplier-color";
describe("supplierColor", () => {
it("returns a hex string", () => {
expect(supplierColor("sup-1")).toMatch(/^#[0-9a-f]{6}$/);
});
it("is deterministic — same id always gives the same colour", () => {
expect(supplierColor("sup-1")).toBe(supplierColor("sup-1"));
expect(supplierColor("abc123")).toBe(supplierColor("abc123"));
});
it("returns distinct colours for different suppliers", () => {
// Sample a handful of ids; at least two of them should differ.
// (With 18 palette slots, hash collisions are possible — but a
// 6-id sample will almost certainly produce >1 distinct colour.)
const ids = ["a", "b", "c", "d", "e", "f"];
const distinct = new Set(ids.map(supplierColor));
expect(distinct.size).toBeGreaterThan(1);
});
it("returns the fallback colour for empty / null ids", () => {
expect(supplierColor("")).toBe(supplierColor(null));
expect(supplierColor(null)).toBe(supplierColor(undefined));
expect(supplierColor("")).toMatch(/^#[0-9a-f]{6}$/);
});
});