diff --git a/src/app/(protected)/workorders/_components/list/table/cells/status-cell.tsx b/src/app/(protected)/workorders/_components/list/table/cells/status-cell.tsx index d2e4c78a..c5857f1e 100644 --- a/src/app/(protected)/workorders/_components/list/table/cells/status-cell.tsx +++ b/src/app/(protected)/workorders/_components/list/table/cells/status-cell.tsx @@ -49,7 +49,7 @@ export function StatusCell({ setAnchorEl(e.currentTarget); }} - title="This WO missed its deadline. Update the Due Date to unlock status updates." + title="This WO missed its deadline. Update Schedule On to unlock status updates." className="group/cell flex w-full cursor-pointer items-center gap-1.5 whitespace-nowrap leading-none transition-opacity hover:opacity-80" style={{ fontSize: 12.5, fontWeight: 600, color: "var(--status-pastdue-text)" }} > @@ -83,7 +83,7 @@ export function StatusCell({ color: "var(--status-pending-text)", }} > - This work order is past due. Update the Due Date before the status can be updated. + This work order is past due. Update Schedule On before the status can be updated. diff --git a/src/domain/work-orders/utils/table-filter-utils.ts b/src/domain/work-orders/utils/table-filter-utils.ts index 4a3046d3..6938c74c 100644 --- a/src/domain/work-orders/utils/table-filter-utils.ts +++ b/src/domain/work-orders/utils/table-filter-utils.ts @@ -12,18 +12,18 @@ import { weekRange } from "@/domain/work-orders/utils/list-week-utils"; const TERMINAL_STATUSES = new Set(["Completed", "Canceled", "Done", "Cancelled"]); export function computeIsPastDue(row: WorkOrderTableRow): boolean { - if (!row.dueDate || TERMINAL_STATUSES.has(row.status)) { + if (!row.scheduledOn || TERMINAL_STATUSES.has(row.status)) { return false; } const today = new Date().toISOString().slice(0, 10); - return row.dueDate < today; + return row.scheduledOn.slice(0, 10) < today; } export function enrichTableRow(row: WorkOrderTableRow): WorkOrderTableRow { return { ...row, - // Recompute from dueDate (same date-only rule as BE). Avoid sticky - // `apiTrue || compute` so a future Due Date clears Past Due immediately. + // Recompute from Schedule On (SH-185). Avoid sticky `apiTrue || compute` + // so a future Schedule On clears Past Due immediately. isPastDue: computeIsPastDue(row), }; } diff --git a/src/test/app/(protected)/workorders/status-cell-past-due-copy.test.tsx b/src/test/app/(protected)/workorders/status-cell-past-due-copy.test.tsx new file mode 100644 index 00000000..961e830c --- /dev/null +++ b/src/test/app/(protected)/workorders/status-cell-past-due-copy.test.tsx @@ -0,0 +1,38 @@ +import { fireEvent, render, screen } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; +import { StatusCell } from "@/app/(protected)/workorders/_components/list/table/cells/status-cell"; +import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row"; + +const pastDueRow = { + id: "wo-1", + status: "Scheduled", + dispatcherId: "", + dispatcherName: "", + company: "", + tech: "", + completedDate: "", + woNumber: "", + pm: "", + docStatus: "", + mediaCount: 0, + type: "PM", + isPastDue: true, + scheduledOn: "2026-06-01", + dueDate: "2026-08-01", +} as WorkOrderTableRow; + +describe("StatusCell Past Due copy (SH-185)", () => { + it("directs the dispatcher to update Schedule On, not Due Date", () => { + render(); + + const trigger = screen.getByRole("button", { name: /past due/i }); + expect(trigger.getAttribute("title") ?? "").toContain("Schedule On"); + expect(trigger.getAttribute("title") ?? "").not.toMatch(/due date/i); + + fireEvent.click(trigger); + + expect(screen.getByText(/update schedule on before the status can be updated/i)).toBeTruthy(); + expect(screen.getByRole("button", { name: /update schedule on/i })).toBeTruthy(); + expect(screen.queryByText(/due date/i)).toBeNull(); + }); +}); diff --git a/src/test/domain/work-orders/utils/table-filter-utils.test.ts b/src/test/domain/work-orders/utils/table-filter-utils.test.ts index e3988d10..ea303e6c 100644 --- a/src/test/domain/work-orders/utils/table-filter-utils.test.ts +++ b/src/test/domain/work-orders/utils/table-filter-utils.test.ts @@ -156,43 +156,43 @@ describe("matchesAdvancedFilters", () => { }); describe("computeIsPastDue", () => { - it("is true when dueDate is before today even if scheduledOn is future", () => { + it("is true when scheduledOn is before today even if dueDate is future", () => { expect( computeIsPastDue( makeRow({ - dueDate: shiftIso(-1), - scheduledOn: shiftIso(5), + dueDate: shiftIso(5), + scheduledOn: shiftIso(-1), status: "Scheduled", }), ), ).toBe(true); }); - it("is false when dueDate is future even if scheduledOn is past", () => { + it("is false when scheduledOn is future even if dueDate is past", () => { expect( computeIsPastDue( makeRow({ - dueDate: shiftIso(5), - scheduledOn: shiftIso(-1), + dueDate: shiftIso(-1), + scheduledOn: shiftIso(5), status: "Incomplete", }), ), ).toBe(false); }); - it("is false when dueDate is empty", () => { + it("is false when scheduledOn is empty", () => { expect( computeIsPastDue( makeRow({ - dueDate: "", - scheduledOn: shiftIso(-3), + dueDate: shiftIso(-3), + scheduledOn: "", status: "Scheduled", }), ), ).toBe(false); }); - it("is false for terminal statuses even with past dueDate", () => { + it("is false for terminal statuses even with past scheduledOn", () => { expect( computeIsPastDue( makeRow({ @@ -205,19 +205,19 @@ describe("computeIsPastDue", () => { expect( computeIsPastDue( makeRow({ - dueDate: shiftIso(-2), + scheduledOn: shiftIso(-2), status: "Canceled", }), ), ).toBe(false); }); - it("is false when dueDate is today", () => { + it("is false when scheduledOn is today", () => { expect( computeIsPastDue( makeRow({ - dueDate: todayIso(), - scheduledOn: shiftIso(-1), + dueDate: shiftIso(-1), + scheduledOn: todayIso(), status: "Scheduled", }), ), @@ -226,11 +226,11 @@ describe("computeIsPastDue", () => { }); describe("enrichTableRow", () => { - it("recomputes isPastDue from dueDate and ignores sticky API true", () => { + it("recomputes isPastDue from scheduledOn and ignores sticky API true", () => { const enriched = enrichTableRow( makeRow({ - dueDate: shiftIso(5), - scheduledOn: shiftIso(-1), + dueDate: shiftIso(-1), + scheduledOn: shiftIso(5), isPastDue: true, status: "Scheduled", }), @@ -238,11 +238,11 @@ describe("enrichTableRow", () => { expect(enriched.isPastDue).toBe(false); }); - it("sets isPastDue true from past dueDate even when API flag is false", () => { + it("sets isPastDue true from past scheduledOn even when API flag is false", () => { const enriched = enrichTableRow( makeRow({ - dueDate: shiftIso(-1), - scheduledOn: shiftIso(5), + dueDate: shiftIso(5), + scheduledOn: shiftIso(-1), isPastDue: false, status: "Incomplete", }),