diff --git a/app/schemas/ticket.py b/app/schemas/ticket.py index d17737b..e3d9ae0 100644 --- a/app/schemas/ticket.py +++ b/app/schemas/ticket.py @@ -54,6 +54,7 @@ class TicketUpdate(BaseModel): category_id: int | None = None priority: str | None = None reporter: str | None = None + phone: str | None = None reported_via: str | None = None description: str | None = None assigned_to: int | None = None diff --git a/app/services/ticket.py b/app/services/ticket.py index c767756..0c642f1 100644 --- a/app/services/ticket.py +++ b/app/services/ticket.py @@ -18,7 +18,7 @@ from app.services.sla import compute_sla_deadline # ── Status Transition Map ──────────────────────────────────────────── # Keys: current status → list of valid next statuses VALID_TRANSITIONS: dict[str, list[str]] = { - "New": ["Logged"], + "New": ["Logged", "Cancelled"], "Logged": ["Triage", "Closed", "Cancelled"], "Triage": ["Assigned", "Escalated", "Cancelled"], "Assigned": ["Accepted", "Triage", "Cancelled"], @@ -28,11 +28,11 @@ VALID_TRANSITIONS: dict[str, list[str]] = { "In Progress": ["Waiting Parts", "Escalated", "Completed", "Cancelled"], "Waiting Parts": ["In Progress", "Escalated", "Cancelled"], "Escalated": ["Triage", "In Progress", "Completed", "Closed", "Cancelled"], - "Completed": ["On-Field Verification", "In Progress"], - "On-Field Verification": ["Wahab Review", "Completed", "Closed"], - "Wahab Review": ["Closed", "On-Field Verification"], + "Completed": ["On-Field Verification", "In Progress", "Cancelled"], + "On-Field Verification": ["Wahab Review", "Completed", "Closed", "Cancelled"], + "Wahab Review": ["Closed", "On-Field Verification", "Cancelled"], "Closed": ["Reopened"], - "Reopened": ["Triage", "Logged"], + "Reopened": ["Triage", "Logged", "Cancelled"], # Terminal: cancelled tickets cannot resume work. "Cancelled": [], } diff --git a/app/templates/dashboard/ceo.html b/app/templates/dashboard/ceo.html index 4df986d..97b7a57 100644 --- a/app/templates/dashboard/ceo.html +++ b/app/templates/dashboard/ceo.html @@ -288,7 +288,7 @@ }, calcAvgResolution(all) { - const closed = all.filter(t => ['Closed', 'Completed', 'Cancelled'].includes(t.status) && t.created_at && t.updated_at); + const closed = all.filter(t => ['Closed', 'Completed'].includes(t.status) && t.created_at && t.updated_at); if (!closed.length) return '—'; const avgHrs = closed.reduce((sum, t) => { const diff = (new Date(t.updated_at) - new Date(t.created_at)) / (1000 * 60 * 60); diff --git a/tests/test_workflow_hardening.py b/tests/test_workflow_hardening.py index e5a223b..f879cbb 100644 --- a/tests/test_workflow_hardening.py +++ b/tests/test_workflow_hardening.py @@ -60,7 +60,11 @@ async def test_cancelled_reachable_from_active_states(client): """Logged/Triage/In Progress → Cancelled are all valid transitions.""" from app.services.ticket import VALID_TRANSITIONS - for state in ("Logged", "Triage", "Assigned", "Accepted", "In Progress", "Escalated"): + for state in ( + "New", "Logged", "Triage", "Assigned", "Accepted", "Travelling", "On Site", + "In Progress", "Waiting Parts", "Escalated", "On-Field Verification", + "Wahab Review", "Reopened", + ): assert "Cancelled" in VALID_TRANSITIONS[state], f"{state} should allow Cancelled"