export const WORKFLOW_STAGES = [ { key: "manager", label: "Менеджер" }, { key: "production", label: "Производство" }, { key: "logistics", label: "Логистика" }, { key: "delivery", label: "Доставка" }, { key: "completed", label: "Завершено" }, ]; const getStageLabel = (stageKey) => WORKFLOW_STAGES.find((stage) => stage.key === stageKey)?.label || "Без этапа"; export const ORDER_STATUS_META = { "Новый": { comment: "Заказ создан и ожидает проверки менеджером.", ownerRole: "manager", stageKey: "manager", stageLabel: getStageLabel("manager"), warningAfterHours: 24, criticalAfterHours: 48, tone: "neutral", }, "Требует уточнения": { comment: "В заказе не хватает данных, их должен уточнить менеджер.", ownerRole: "manager", stageKey: "manager", stageLabel: getStageLabel("manager"), warningAfterHours: 12, criticalAfterHours: 24, tone: "warning", }, "Подтверждён менеджером": { comment: "Менеджер проверил заказ и передал его дальше в работу.", ownerRole: "manager", stageKey: "manager", stageLabel: getStageLabel("manager"), warningAfterHours: 12, criticalAfterHours: 24, tone: "accent", }, "В очереди производства": { comment: "Заказ передан на производство и ожидает запуска.", ownerRole: "production_lead", stageKey: "production", stageLabel: getStageLabel("production"), warningAfterHours: 24, criticalAfterHours: 48, tone: "neutral", }, "В производстве": { comment: "Заказ находится в изготовлении.", ownerRole: "production_lead", stageKey: "production", stageLabel: getStageLabel("production"), warningAfterHours: 48, criticalAfterHours: 96, tone: "accent", }, "Готов к отгрузке": { comment: "Производство завершено, можно запускать согласование доставки.", ownerRole: "production_lead", stageKey: "production", stageLabel: getStageLabel("production"), warningAfterHours: 8, criticalAfterHours: 24, tone: "accent", }, "Ожидает ответа клиента": { comment: "Клиенту отправлена ссылка, система ждёт подтверждения времени доставки.", ownerRole: "logistician", stageKey: "logistics", stageLabel: getStageLabel("logistics"), warningAfterHours: 1, criticalAfterHours: 3, tone: "warning", }, "Ожидает согласования доставки": { comment: "Клиенту отправлено предложение выбрать дату и половину дня доставки.", ownerRole: "logistician", stageKey: "logistics", stageLabel: getStageLabel("logistics"), warningAfterHours: 24, criticalAfterHours: 96, tone: "warning", }, "Доставка согласована": { comment: "Клиент подтвердил доставку, логист может назначать рейс.", ownerRole: "logistician", stageKey: "logistics", stageLabel: getStageLabel("logistics"), warningAfterHours: 12, criticalAfterHours: 24, tone: "accent", }, "Передан логисту": { comment: "Согласование не завершилось автоматически, заказ передан логисту для ручной работы.", ownerRole: "logistician", stageKey: "logistics", stageLabel: getStageLabel("logistics"), warningAfterHours: 4, criticalAfterHours: 12, tone: "warning", }, "Назначен водитель": { comment: "Логист распределил заказ на конкретного водителя.", ownerRole: "logistician", stageKey: "delivery", stageLabel: getStageLabel("delivery"), warningAfterHours: 12, criticalAfterHours: 24, tone: "accent", }, Загружен: { comment: "Заказ физически загружен в транспорт.", ownerRole: "driver", stageKey: "delivery", stageLabel: getStageLabel("delivery"), warningAfterHours: 8, criticalAfterHours: 24, tone: "neutral", }, "В пути": { comment: "Водитель выехал и выполняет доставку.", ownerRole: "driver", stageKey: "delivery", stageLabel: getStageLabel("delivery"), warningAfterHours: 12, criticalAfterHours: 24, tone: "accent", }, Доставлен: { comment: "Заказ успешно передан клиенту.", ownerRole: "driver", stageKey: "completed", stageLabel: getStageLabel("completed"), warningAfterHours: null, criticalAfterHours: null, tone: "accent", }, Закрыт: { comment: "Цикл заказа завершён и больше не требует действий.", ownerRole: "logistician", stageKey: "completed", stageLabel: getStageLabel("completed"), warningAfterHours: null, criticalAfterHours: null, tone: "neutral", }, Отменён: { comment: "Заказ отменён и выведен из процесса.", ownerRole: "manager", stageKey: "completed", stageLabel: getStageLabel("completed"), warningAfterHours: null, criticalAfterHours: null, tone: "danger", }, "Проблема доставки": { comment: "На этапе доставки возникла проблема и нужен ручной разбор.", ownerRole: "logistician", stageKey: "logistics", stageLabel: getStageLabel("logistics"), warningAfterHours: 12, criticalAfterHours: 48, tone: "danger", }, "Платное хранение": { comment: "Согласование доставки не достигнуто, заказ переведен на платное хранение.", ownerRole: "logistician", stageKey: "logistics", stageLabel: getStageLabel("logistics"), warningAfterHours: 24, criticalAfterHours: 72, tone: "danger", }, }; export const ORDER_STATUSES = Object.keys(ORDER_STATUS_META); export const DELIVERY_AGREEMENT_STATUS_META = { "Не начато": { comment: "Процесс согласования доставки ещё не запускался.", }, "Отправлено клиенту": { comment: "Клиенту отправлено предложение согласовать доставку.", }, "Ожидание ответа": { comment: "Система ждёт ответ клиента по предложенному слоту.", }, "Подтверждено клиентом": { comment: "Клиент подтвердил дату и половину дня доставки.", }, "Перенос запрошен": { comment: "Клиент просит изменить дату или временной интервал.", }, "Нет ответа": { comment: "Клиент не ответил в пределах SLA.", }, "Ошибка отправки": { comment: "Сообщение не удалось отправить, требуется повторная попытка.", }, }; export const DELIVERY_AGREEMENT_STATUSES = Object.keys(DELIVERY_AGREEMENT_STATUS_META); export const ORDER_STATUS_TRANSITIONS = { "Новый": ["Требует уточнения", "Подтверждён менеджером", "Отменён"], "Требует уточнения": ["Новый", "Подтверждён менеджером", "Отменён"], "Подтверждён менеджером": ["В очереди производства", "Требует уточнения", "Отменён"], "В очереди производства": ["В производстве", "Требует уточнения", "Отменён"], "В производстве": ["Готов к отгрузке", "Требует уточнения", "Отменён"], "Готов к отгрузке": ["Ожидает согласования доставки", "Ожидает ответа клиента", "Проблема доставки", "Отменён"], "Ожидает ответа клиента": ["Доставка согласована", "Передан логисту", "Платное хранение", "Проблема доставки", "Отменён"], "Ожидает согласования доставки": ["Доставка согласована", "Проблема доставки", "Отменён"], "Доставка согласована": ["Назначен водитель", "Ожидает согласования доставки", "Проблема доставки"], "Передан логисту": ["Доставка согласована", "Платное хранение", "Проблема доставки", "Отменён"], "Назначен водитель": ["Загружен", "Проблема доставки"], Загружен: ["В пути", "Проблема доставки"], "В пути": ["Доставлен", "Проблема доставки"], Доставлен: ["Закрыт"], "Проблема доставки": ["Ожидает согласования доставки", "Назначен водитель", "Отменён", "Закрыт"], "Платное хранение": ["Доставка согласована", "Отменён", "Закрыт"], Закрыт: [], Отменён: [], }; export const ROLE_TRANSITION_TARGETS = { manager: ORDER_STATUSES, production_lead: ["В очереди производства", "В производстве", "Готов к отгрузке", "Требует уточнения", "Отменён"], logistician: [ "Ожидает ответа клиента", "Ожидает согласования доставки", "Доставка согласована", "Передан логисту", "Назначен водитель", "Проблема доставки", "Платное хранение", "Закрыт", "Отменён", ], driver: ["Загружен", "В пути", "Доставлен", "Проблема доставки"], admin: ORDER_STATUSES, }; export const PRODUCTION_STATUSES = [ "В очереди производства", "В производстве", "Готов к отгрузке", ]; export const LOGISTICS_STATUSES = [ "Готов к отгрузке", "Ожидает согласования доставки", "Доставка согласована", "Назначен водитель", "Проблема доставки", ]; export const DRIVER_STATUSES = ["Назначен водитель", "Загружен", "В пути", "Доставлен"]; export const getOrderStatusComment = (status) => ORDER_STATUS_META[status]?.comment || "Комментарий не задан."; export const getDeliveryAgreementComment = (status) => DELIVERY_AGREEMENT_STATUS_META[status]?.comment || "Комментарий не задан."; export const getStatusTone = (status) => ORDER_STATUS_META[status]?.tone || "neutral"; export const getStatusOwnerRole = (status) => ORDER_STATUS_META[status]?.ownerRole || null; export const getStatusStageKey = (status) => ORDER_STATUS_META[status]?.stageKey || null; export const getStatusStageLabel = (status) => ORDER_STATUS_META[status]?.stageLabel || "Без этапа"; export const getStatusSla = (status) => ({ warningAfterHours: ORDER_STATUS_META[status]?.warningAfterHours ?? null, criticalAfterHours: ORDER_STATUS_META[status]?.criticalAfterHours ?? null, }); export const getAvailableTransitionsByRole = ({ status, role }) => { const nextStatuses = ORDER_STATUS_TRANSITIONS[status] || []; const allowedTargets = ROLE_TRANSITION_TARGETS[role] || []; return nextStatuses.filter((nextStatus) => allowedTargets.includes(nextStatus)); };