fix(boss-dashboard): pin drivers to today window + count delivered orders via order_items
This commit is contained in:
parent
721b310f4d
commit
9ec621e9f8
2 changed files with 60 additions and 9 deletions
|
|
@ -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" });
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue