feat(pin-model): add aggregateDriverStatus helper (TDD)
This commit is contained in:
parent
8c21347ecc
commit
56626c8270
2 changed files with 116 additions and 0 deletions
|
|
@ -48,3 +48,41 @@ export function splitSupplierBucket<
|
|||
}
|
||||
return { assignedByDriver, poolItems };
|
||||
}
|
||||
|
||||
export interface DriverStatus {
|
||||
total: number;
|
||||
collected: number;
|
||||
ready: number;
|
||||
waiting: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts a driver's stops into the four buckets the driver card surfaces:
|
||||
* - collected : item_status === "collected" (the green anchor)
|
||||
* - ready : ready_for_collection === true and not collected
|
||||
* - waiting : ready_for_collection !== true and not collected
|
||||
* - total : items.length
|
||||
*
|
||||
* Items with `ready_for_collection` undefined or null are treated as
|
||||
* not ready (waiting). Pure — no DB / side effects.
|
||||
*/
|
||||
export function aggregateDriverStatus<
|
||||
T extends {
|
||||
item_status: string;
|
||||
ready_for_collection?: boolean | null;
|
||||
}
|
||||
>(items: T[]): DriverStatus {
|
||||
let collected = 0;
|
||||
let ready = 0;
|
||||
let waiting = 0;
|
||||
for (const it of items) {
|
||||
if (it.item_status === "collected") {
|
||||
collected++;
|
||||
} else if (it.ready_for_collection) {
|
||||
ready++;
|
||||
} else {
|
||||
waiting++;
|
||||
}
|
||||
}
|
||||
return { total: items.length, collected, ready, waiting };
|
||||
}
|
||||
|
|
|
|||
78
src/lib/pin-model.test.ts
Normal file
78
src/lib/pin-model.test.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { aggregateDriverStatus } from "@/app/(app)/collection-map/pin-model";
|
||||
|
||||
describe("aggregateDriverStatus", () => {
|
||||
it("returns zeros for an empty array", () => {
|
||||
expect(aggregateDriverStatus([])).toEqual({
|
||||
total: 0,
|
||||
collected: 0,
|
||||
ready: 0,
|
||||
waiting: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("counts every item as collected when every item is collected", () => {
|
||||
const items = [
|
||||
{ item_status: "collected" as const, ready_for_collection: true },
|
||||
{ item_status: "collected" as const, ready_for_collection: true },
|
||||
{ item_status: "collected" as const, ready_for_collection: false },
|
||||
];
|
||||
expect(aggregateDriverStatus(items)).toEqual({
|
||||
total: 3,
|
||||
collected: 3,
|
||||
ready: 0,
|
||||
waiting: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("counts every item as waiting when nothing is ready or collected", () => {
|
||||
const items = [
|
||||
{ item_status: "collection_pool" as const, ready_for_collection: false },
|
||||
{ item_status: "assigned" as const, ready_for_collection: false },
|
||||
];
|
||||
expect(aggregateDriverStatus(items)).toEqual({
|
||||
total: 2,
|
||||
collected: 0,
|
||||
ready: 0,
|
||||
waiting: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it("rolls up mixed states (collected + ready + waiting)", () => {
|
||||
const items = [
|
||||
{ item_status: "collected" as const, ready_for_collection: true },
|
||||
{ item_status: "collected" as const, ready_for_collection: true },
|
||||
{ item_status: "assigned" as const, ready_for_collection: true },
|
||||
{ item_status: "assigned" as const, ready_for_collection: true },
|
||||
{ item_status: "assigned" as const, ready_for_collection: true },
|
||||
{ item_status: "collection_pool" as const, ready_for_collection: false },
|
||||
];
|
||||
expect(aggregateDriverStatus(items)).toEqual({
|
||||
total: 6,
|
||||
collected: 2,
|
||||
ready: 3,
|
||||
waiting: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it("treats undefined ready_for_collection as waiting", () => {
|
||||
const items = [
|
||||
{ item_status: "assigned" as const },
|
||||
{ item_status: "collection_pool" as const },
|
||||
];
|
||||
expect(aggregateDriverStatus(items).waiting).toBe(2);
|
||||
expect(aggregateDriverStatus(items).ready).toBe(0);
|
||||
expect(aggregateDriverStatus(items).collected).toBe(0);
|
||||
expect(aggregateDriverStatus(items).total).toBe(2);
|
||||
});
|
||||
|
||||
it("treats null ready_for_collection as waiting", () => {
|
||||
const items = [
|
||||
{ item_status: "assigned" as const, ready_for_collection: null },
|
||||
{ item_status: "collection_pool" as const, ready_for_collection: null },
|
||||
];
|
||||
expect(aggregateDriverStatus(items).waiting).toBe(2);
|
||||
expect(aggregateDriverStatus(items).ready).toBe(0);
|
||||
expect(aggregateDriverStatus(items).collected).toBe(0);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue