supersam/src/constants/deliveryWorkflow.js

283 lines
12 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: "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));
};