fix(boss-dashboard): pin drivers to today window + count delivered orders via order_items

This commit is contained in:
Dave 2026-08-27 23:50:54 +02:00
parent 721b310f4d
commit 9ec621e9f8
2 changed files with 60 additions and 9 deletions

View file

@ -149,19 +149,47 @@ 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.
addRow("orders", { created: "2026-08-27T08:00:00.000Z", rep: "rep-1", invoiced: false, item_status: "pending" });
addRow("orders", { created: "2026-08-27T09:00:00.000Z", rep: "rep-1", invoiced: false, item_status: "delivered" });
addRow("orders", { created: "2026-08-27T10:00:00.000Z", rep: "rep-2", invoiced: true, item_status: "invoiced" });
// 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" });
// Only the delivered order has an order_item with item_status="delivered".
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" });
const data = await getBossDashboardData({ window: "today", now: fixedNow });
expect(data.window).toBe("today");
expect(data.orderTotals.total).toBe(3); // cancelled excluded
expect(data.orderTotals.delivered).toBe(1);
expect(data.orderTotals.delivered).toBe(1); // only orderDelivered has a delivered item
expect(data.orderTotals.invoiced).toBe(1);
});
it("counts delivered via order_items.item_status, not orders.item_status", async () => {
// An order is "delivered" only via its order_items — the order row itself
// does NOT carry item_status in real PB. The old code read orders.item_status
// (always undefined) and so would have reported 0 forever.
const orderId = addRow("orders", {
rep: "rep-1",
invoiced: false,
// No item_status on the orders row — that's the fix scenario.
created: "2026-08-27T08:00:00.000Z",
});
// An order_item with item_status="delivered" in the active window.
addRow("order_items", {
order: orderId,
item_status: "delivered",
created: "2026-08-27T09:00:00.000Z",
});
const data = await getBossDashboardData({ window: "today", now: fixedNow });
expect(data.orderTotals.delivered).toBe(1);
});
it("groups reps with quotesLoaded/doneFor/doneBy and ordersPlaced", async () => {
// Users
addRow("users", { id: "rep-1", name: "Gary Ndlovu" });

View file

@ -93,11 +93,13 @@ export async function getBossDashboardData({
now?: Date;
}): Promise<BossDashboardData> {
const { rangeStart, rangeEnd } = windowRange(window, now);
const todayRange = windowRange("today", now);
const pb = await getAdminPocketBase();
const rangeFilter = `created >= "${rangeStart}" && created < "${rangeEnd}"`;
const todayRangeFilter = `created >= "${todayRange.rangeStart}" && created < "${todayRange.rangeEnd}"`;
const [users, customers, orders, quotes, items] = await Promise.all([
const [users, customers, orders, quotes, todayItems] = await Promise.all([
pb.collection("users").getFullList({ fields: "id,name" }),
pb.collection("customers").getFullList({ fields: "id,rep" }),
pb.collection("orders").getFullList({
@ -108,12 +110,20 @@ export async function getBossDashboardData({
filter: rangeFilter,
fields: "id,claimed_by,customer,status,created",
}),
// Driver stops are always today-only regardless of the active tab.
pb.collection("order_items").getFullList({
filter: rangeFilter,
filter: todayRangeFilter,
fields: "id,drv_id,item_status,drv_status,drv_collected_at,created",
}),
]);
// 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({
filter: rangeFilter,
fields: "order,item_status",
});
const userById = new Map<string, { id: string; name: string }>();
for (const u of users) {
userById.set(u.id, {
@ -129,7 +139,6 @@ export async function getBossDashboardData({
// --- Order totals + per-rep order counts ---------------------------------
let total = 0;
let delivered = 0;
let invoiced = 0;
const repOrders = new Map<string, number>();
@ -138,7 +147,6 @@ export async function getBossDashboardData({
const itemStatus = String(rec.item_status ?? "");
const isCancelled = itemStatus === "cancelled";
if (!isCancelled) total += 1;
if (itemStatus === "delivered") delivered += 1;
if (rec.invoiced === true) invoiced += 1;
if (isCancelled) continue;
@ -146,6 +154,19 @@ 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
@ -214,8 +235,10 @@ export async function getBossDashboardData({
}
// --- Driver stops ---------------------------------------------------------
// Driver stops use the today-only order_items fetch above (todayItems),
// NOT the active-window delivered fetch.
const driverStops = new Map<string, { id: string; stopsToday: number; stopsDone: number }>();
for (const item of items) {
for (const item of todayItems) {
const rec = item as Record<string, unknown>;
const drvId = String(rec.drv_id ?? "").trim();
if (!drvId) continue;