// ============================================================================ // Order status groups — which RAW `GET /admin/bookings` enums make up each // operator-facing status the Orders page shows as a tab. // // Shared by the Orders page and anything else that counts orders by status, // so a second definition cannot drift from the tabs an operator is looking // at. // // ⚠ This is deliberately NOT the same taxonomy as queries.js's // BOOKING_STATUS_TO_DELIVERY_STATUS, and the two must not be merged: // // • Orders page — tracks the OPERATOR's workflow. "Assigned" // means the operator picked a rider, the moment assign-miler succeeds, so // miler_assigned counts as Assigned. // • Deliveries page (queries.js) — tracks the RIDER's engagement. Its "Accepted" // means the rider accepted, a deliberately later and narrower bar, so it // keeps miler_assigned on 'pending'. // // That split is explicit product direction — it was unified once and // reverted. On Orders, "Assigned" is an operator action; on Deliveries, // "Accepted" is a rider action, and the two screens must keep saying so. // ============================================================================ export const ORDER_STATUS_GROUPS = { pending: ['pending_pickup', 'pending', 'created', 'new', 'booked', 'order_placed', 'unassigned', ''], assigned: ['converted_to_consignment', 'collected_by_miler', 'miler_assigned', 'pickup_scheduled', 'arrived', 'picked', 'assigned', 'rider_assigned'], active: ['out_for_delivery', 'active', 'in_transit', 'picked_up', 'in_progress'], delivered: ['delivered', 'completed', 'success'], cancelled: ['cancelled', 'rejected', 'failed'] }; export const ORDER_STATUS_LABELS = { pending: 'Pending', assigned: 'Assigned', active: 'Out for delivery', delivered: 'Delivered', cancelled: 'Cancelled' }; // Display order — matches the lifecycle, and the order the Orders page's tabs // appear in. export const ORDER_STATUS_ORDER = ['pending', 'assigned', 'active', 'delivered', 'cancelled']; const RAW_TO_GROUP = Object.entries(ORDER_STATUS_GROUPS).reduce((acc, [group, raws]) => { raws.forEach((raw) => { acc[raw] = group; }); return acc; }, {}); export const statusesInGroup = (group) => ORDER_STATUS_GROUPS[group] || []; // Raw booking enum → group key. Returns the lowercased raw value itself for an // enum this map has never seen, so an unmapped backend status stays visible in // a breakdown rather than vanishing from the totals. export const groupForBookingStatus = (raw) => { const key = String(raw || '').toLowerCase(); return RAW_TO_GROUP[key] || key; }; export const isInGroup = (raw, group) => statusesInGroup(group).includes(String(raw || '').toLowerCase());