fix(boss-dashboard): exclude cancelled orders via order_items.item_status

The cancelled check was reading orders.item_status, which doesn't exist on
the orders collection in PB. Status lives on order_items, so the check
never fired and cancelled orders were counted in orderTotals.total and
each rep's ordersPlaced.

Mirror the delivered fix: derive a cancelled-order-id set from
order_items.item_status in the active window. An order is excluded from
total if ANY of its lines carries item_status="cancelled".

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Dave 2026-08-27 23:52:59 +02:00
parent 9ec621e9f8
commit ebbcc73020
2 changed files with 89 additions and 24 deletions

View file

@ -149,16 +149,17 @@ beforeEach(() => {
describe("getBossDashboardData", () => {
it("returns orderTotals: total/delivered/invoiced for the window", async () => {
// 3 orders in window: 1 delivered, 1 invoiced, 1 pending. 1 cancelled.
// order_items rows back the delivered count via the order relation.
const orderPending = addRow("orders", { created: "2026-08-27T08:00:00.000Z", rep: "rep-1", invoiced: false, item_status: "pending" });
const orderDelivered = addRow("orders", { created: "2026-08-27T09:00:00.000Z", rep: "rep-1", invoiced: false, item_status: "delivered" });
const orderInvoiced = addRow("orders", { created: "2026-08-27T10:00:00.000Z", rep: "rep-2", invoiced: true, item_status: "invoiced" });
addRow("orders", { created: "2026-08-27T11:00:00.000Z", rep: "rep-2", invoiced: false, item_status: "cancelled" });
// order_items rows back both delivered AND cancelled via the order relation.
const orderPending = addRow("orders", { created: "2026-08-27T08:00:00.000Z", rep: "rep-1", invoiced: false });
const orderDelivered = addRow("orders", { created: "2026-08-27T09:00:00.000Z", rep: "rep-1", invoiced: false });
const orderInvoiced = addRow("orders", { created: "2026-08-27T10:00:00.000Z", rep: "rep-2", invoiced: true });
const orderCancelled = addRow("orders", { created: "2026-08-27T11:00:00.000Z", rep: "rep-2", invoiced: false });
// Only the delivered order has an order_item with item_status="delivered".
// order_items carry the actual status (orders.item_status doesn't exist in PB).
addRow("order_items", { order: orderPending, item_status: "pending", created: "2026-08-27T08:00:00.000Z" });
addRow("order_items", { order: orderDelivered, item_status: "delivered", created: "2026-08-27T09:00:00.000Z" });
addRow("order_items", { order: orderInvoiced, item_status: "invoiced", created: "2026-08-27T10:00:00.000Z" });
addRow("order_items", { order: orderCancelled, item_status: "cancelled", created: "2026-08-27T11:00:00.000Z" });
const data = await getBossDashboardData({ window: "today", now: fixedNow });
@ -190,6 +191,67 @@ describe("getBossDashboardData", () => {
expect(data.orderTotals.delivered).toBe(1);
});
it("excludes cancelled orders from total via order_items.item_status", async () => {
// Regression: orders.item_status doesn't exist in PB. The old check
// (o as Record<string, unknown>).item_status === "cancelled" therefore
// never fired and cancelled orders were counted in total + ordersPlaced.
// Cancellation lives on order_items.item_status. If ANY item in an order is
// cancelled, the whole order is excluded from total and ordersPlaced.
addRow("users", { id: "rep-1", name: "Gary" });
addRow("users", { id: "rep-2", name: "Shireen" });
// Mixed order: one delivered line + one cancelled line. Per spec, ANY cancelled
// line excludes the order from total — even if other lines are delivered.
const mixedOrder = addRow("orders", {
rep: "rep-1",
invoiced: false,
created: "2026-08-27T08:00:00.000Z",
});
addRow("order_items", {
order: mixedOrder,
item_status: "delivered",
created: "2026-08-27T08:30:00.000Z",
});
addRow("order_items", {
order: mixedOrder,
item_status: "cancelled",
created: "2026-08-27T08:45:00.000Z",
});
// Fully cancelled order (rep-2).
const cancelledOnly = addRow("orders", {
rep: "rep-2",
invoiced: false,
created: "2026-08-27T09:00:00.000Z",
});
addRow("order_items", {
order: cancelledOnly,
item_status: "cancelled",
created: "2026-08-27T09:00:00.000Z",
});
// Healthy order (rep-1) — should be counted.
const healthyOrder = addRow("orders", {
rep: "rep-1",
invoiced: false,
created: "2026-08-27T10:00:00.000Z",
});
addRow("order_items", {
order: healthyOrder,
item_status: "pending",
created: "2026-08-27T10:00:00.000Z",
});
const data = await getBossDashboardData({ window: "today", now: fixedNow });
// Only the healthy order counts.
expect(data.orderTotals.total).toBe(1);
// rep-1's ordersPlaced drops to 1 (only the healthy order); rep-2 is 0.
const byId = Object.fromEntries(data.reps.map((r) => [r.id, r]));
expect(byId["rep-1"].ordersPlaced).toBe(1);
expect(byId["rep-2"].ordersPlaced).toBe(0);
});
it("groups reps with quotesLoaded/doneFor/doneBy and ordersPlaced", async () => {
// Users
addRow("users", { id: "rep-1", name: "Gary Ndlovu" });

View file

@ -117,9 +117,9 @@ export async function getBossDashboardData({
}),
]);
// Delivered orders are derived from order_items.item_status (not orders.item_status,
// which doesn't exist in PB). Active window only.
const deliveredItems = await pb.collection("order_items").getFullList({
// Delivered + cancelled are derived from order_items.item_status (the orders
// collection doesn't carry item_status in PB). Active window only.
const orderItemsInWindow = await pb.collection("order_items").getFullList({
filter: rangeFilter,
fields: "order,item_status",
});
@ -137,6 +137,23 @@ export async function getBossDashboardData({
customerRepById.set(c.id, String((c as Record<string, unknown>).rep ?? ""));
}
// Build sets of order ids that have a delivered item vs a cancelled item.
// Definition: an order is "cancelled" if ANY of its order_items in the active
// window carries item_status="cancelled". This matches the spec: total counts
// orders placed in the window EXCLUDING cancelled ones. (orders.item_status
// doesn't exist in PB — the status lives on order_items.)
const deliveredOrderIds = new Set<string>();
const cancelledOrderIds = new Set<string>();
for (const item of orderItemsInWindow) {
const rec = item as Record<string, unknown>;
const orderId = String(rec.order ?? "").trim();
if (!orderId) continue;
const status = String(rec.item_status ?? "");
if (status === "delivered") deliveredOrderIds.add(orderId);
if (status === "cancelled") cancelledOrderIds.add(orderId);
}
const delivered = deliveredOrderIds.size;
// --- Order totals + per-rep order counts ---------------------------------
let total = 0;
let invoiced = 0;
@ -144,8 +161,7 @@ export async function getBossDashboardData({
for (const o of orders) {
const rec = o as Record<string, unknown>;
const itemStatus = String(rec.item_status ?? "");
const isCancelled = itemStatus === "cancelled";
const isCancelled = cancelledOrderIds.has(o.id);
if (!isCancelled) total += 1;
if (rec.invoiced === true) invoiced += 1;
@ -154,19 +170,6 @@ export async function getBossDashboardData({
if (repId) repOrders.set(repId, (repOrders.get(repId) ?? 0) + 1);
}
// Delivered: count distinct order ids with at least one item_status="delivered"
// in the active window. (orders.item_status doesn't exist in PB; the status lives
// on order_items.)
const deliveredOrderIds = new Set<string>();
for (const item of deliveredItems) {
const rec = item as Record<string, unknown>;
if (String(rec.item_status ?? "") === "delivered") {
const orderId = String(rec.order ?? "").trim();
if (orderId) deliveredOrderIds.add(orderId);
}
}
const delivered = deliveredOrderIds.size;
// --- Per-rep quote stats --------------------------------------------------
// quotesLoaded: claimed_by resolves to this rep
// quotesDoneFor: the quote's customer belongs to this rep