supersam/src/constants/deliveryWorkflow.js

319 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const WORKFLOW_STAGES = [
{ key: "import", label: "Импорт из 1С" },
{ key: "production", label: "Производство" },
{ key: "logistics", label: "Логистика" },
{ key: "delivery", label: "Доставка" },
{ key: "completed", label: "Завершено" },
];
export const DELIVERY_SET_STATUSES = [
"approaching",
"ready_to_launch",
"awaiting_client",
"manual_work",
"agreed",
"completed",
];
const getStageLabel = (stageKey) =>
WORKFLOW_STAGES.find((stage) => stage.key === stageKey)?.label || "Без этапа";
export const ORDER_STATUS_META = {
"Новый": {
comment: "Заказ импортирован из 1С и ожидает проверки логистом.",
ownerRole: "logistician",
stageKey: "import",
stageLabel: getStageLabel("import"),
warningAfterHours: 24,
criticalAfterHours: 48,
tone: "neutral",
},
"Требует уточнения": {
comment: "В заказе не хватает данных, логисту нужно уточнить информацию.",
ownerRole: "logistician",
stageKey: "import",
stageLabel: getStageLabel("import"),
warningAfterHours: 12,
criticalAfterHours: 24,
tone: "warning",
},
"Подтверждён менеджером": {
comment: "Заказ проверен и подтверждён, готов к передаче в работу.",
ownerRole: "logistician",
stageKey: "import",
stageLabel: getStageLabel("import"),
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: "logistician",
stageKey: "logistics",
stageLabel: getStageLabel("logistics"),
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: 24,
criticalAfterHours: 48,
tone: "accent",
},
"Требуется адрес": {
comment: "Клиент выбрал доставку, но адрес доставки отсутствует. Менеджеру нужно уточнить адрес.",
ownerRole: "logistician",
stageKey: "logistics",
stageLabel: getStageLabel("logistics"),
warningAfterHours: 4,
criticalAfterHours: 12,
tone: "warning",
},
"Передан логисту": {
comment: "Автоматическое согласование не завершилось, заказ передан логисту на ручную обработку.",
ownerRole: "logistician",
stageKey: "logistics",
stageLabel: getStageLabel("logistics"),
warningAfterHours: 4,
criticalAfterHours: 12,
tone: "warning",
},
"Назначен водитель": {
comment: "Логист назначил водителя на доставку.",
ownerRole: "driver",
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: "logistician",
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));
};