const ACTIVE_DRIVER_STATUSES = new Set(["Назначен водитель", "Загружен", "В пути"]); const COMPLETED_DRIVER_STATUSES = new Set(["Доставлен", "Закрыт"]); const PROBLEM_DRIVER_STATUSES = new Set(["Проблема доставки"]); const DRIVER_KANBAN_COLUMNS = [ { key: "assigned", title: "Назначен", statuses: ["Назначен водитель"], dropStatus: "Назначен водитель", }, { key: "loaded", title: "Загружен", statuses: ["Загружен"], dropStatus: "Загружен", }, { key: "on_route", title: "В пути", statuses: ["В пути"], dropStatus: "В пути", }, { key: "delivered", title: "Доставлен", statuses: ["Доставлен", "Закрыт"], dropStatus: "Доставлен", }, { key: "problem", title: "Проблема", statuses: ["Проблема доставки"], dropStatus: "Проблема доставки", }, ]; export const getDeliveryDay = (order) => order.deliverySlots?.[0]?.date || order.scheduledDelivery?.slice(0, 10) || ""; export const getDeliveryCity = (order) => order.customer.address?.split(",")[0]?.trim() || "Без города"; export const getDeliveryHalfDay = (order) => { if (order.deliverySlots?.[0]?.time) { return order.deliverySlots[0].time; } const deliveryHour = Number(order.scheduledDelivery?.slice(11, 13) || 0); return deliveryHour >= 12 ? "Вторая половина дня" : "Первая половина дня"; }; const isWithinDateRange = (order, dateFrom, dateTo) => { const deliveryDay = getDeliveryDay(order); if (dateFrom && deliveryDay < dateFrom) { return false; } if (dateTo && deliveryDay > dateTo) { return false; } return true; }; const isIncludedByView = (order, viewMode, showCompleted) => { if (viewMode === "all") { return showCompleted || !COMPLETED_DRIVER_STATUSES.has(order.status); } if (viewMode === "active") { return ACTIVE_DRIVER_STATUSES.has(order.status) || (showCompleted && COMPLETED_DRIVER_STATUSES.has(order.status)); } if (viewMode === "problems") { return PROBLEM_DRIVER_STATUSES.has(order.status); } return true; }; export const filterDriverDeliveries = (orders, filters) => { const { dateFrom = "", dateTo = "", city = "all", timeSlot = "all", viewMode = "active", showCompleted = false, } = filters; return orders.filter((order) => { if (!isWithinDateRange(order, dateFrom, dateTo)) { return false; } if (city !== "all" && getDeliveryCity(order) !== city) { return false; } if (timeSlot !== "all" && getDeliveryHalfDay(order) !== timeSlot) { return false; } return isIncludedByView(order, viewMode, showCompleted); }); }; const compareByRouteOrder = (left, right) => { const leftOrder = left.driverRouteOrder ?? Number.MAX_SAFE_INTEGER; const rightOrder = right.driverRouteOrder ?? Number.MAX_SAFE_INTEGER; if (leftOrder !== rightOrder) { return leftOrder - rightOrder; } return new Date(left.scheduledDelivery) - new Date(right.scheduledDelivery); }; export const groupDriverDeliveriesByDate = (orders) => { const grouped = orders.reduce((accumulator, order) => { const date = getDeliveryDay(order); accumulator[date] = accumulator[date] || []; accumulator[date].push(order); return accumulator; }, {}); return Object.entries(grouped) .sort(([leftDate], [rightDate]) => leftDate.localeCompare(rightDate)) .map(([date, items]) => ({ date, items: [...items].sort(compareByRouteOrder), })); }; export const reorderDriverDeliveries = (orders, orderedIds) => { const routeIndexMap = new Map(orderedIds.map((id, index) => [id, index + 1])); return orders.map((order) => routeIndexMap.has(order.id) ? { ...order, driverRouteOrder: routeIndexMap.get(order.id), } : order, ); }; export const getDriverCities = (orders) => [...new Set(orders.map((order) => getDeliveryCity(order)).filter(Boolean))].sort((left, right) => left.localeCompare(right), ); export const buildDriverKanbanColumns = (orders) => DRIVER_KANBAN_COLUMNS.map((column) => ({ ...column, items: orders.filter((order) => column.statuses.includes(order.status)).sort(compareByRouteOrder), }));