From 3651dbb4840759681ab3aaedfd6e0ca0ea8bf39f Mon Sep 17 00:00:00 2001 From: root Date: Wed, 10 Jun 2026 12:12:10 +0000 Subject: [PATCH] chore: cleanup --- .../orders/OrderDetailPanel.jsx.bak | 1333 ----------------- 1 file changed, 1333 deletions(-) delete mode 100644 src/components/orders/OrderDetailPanel.jsx.bak diff --git a/src/components/orders/OrderDetailPanel.jsx.bak b/src/components/orders/OrderDetailPanel.jsx.bak deleted file mode 100644 index 6f8bd5d..0000000 --- a/src/components/orders/OrderDetailPanel.jsx.bak +++ /dev/null @@ -1,1333 +0,0 @@ - -const DriverShipmentReport = ({ shipmentData }) => { - if (!Array.isArray(shipmentData) || shipmentData.length === 0) return null; - - return ( - -
- - - - Проблемы с доставкой позиций -
-

- Не доставлено {shipmentData.length} {shipmentData.length === 1 ? "позиция" : shipmentData.length < 5 ? "позиции" : "позиций"}. Остальное — доставлено. -

-
- {shipmentData.map((item) => ( -
-
- {item.name} - {item.quantity || item.unit ? ( - {[item.quantity, item.unit].filter(Boolean).join(" ")} - ) : null} -
- {item.comment ? ( -

Причина: {item.comment}

- ) : ( -

Причина не указана

- )} -
- ))} -
- -
- ); -}; - -import React from "react"; -import { formatDateTime } from "../../utils/formatters"; -import { Badge } from "../UI/Badge"; -import { Button } from "../UI/Button"; -import { Select } from "../UI/Select"; -import { Panel } from "../UI/Panel"; -import { DriverShipmentPanel } from "../driver/DriverShipmentPanel"; -import { supabase } from "../../supabaseClient"; -import { - getOrderGroupDeliveryStatusLabel, - getOrderGroupDisplayStatusLabel, - getOrderGroupStatusTone, -} from "../../services/orderGroupViews"; - -const DELIVERY_TIME_OPTIONS = ["Первая половина дня", "Вторая половина дня"]; -const WEEK_DAY_LABELS = ["ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ", "ВС"]; -const DELIVERY_TIME_ALIASES = { - "До обеда": "Первая половина дня", - "После обеда": "Вторая половина дня", -}; - -const renderList = (values) => { - if (!Array.isArray(values) || !values.length) { - return

Нет данных

; - } - - return ( -
- {values.map((value, index) => ( - - {value} - - ))} -
- ); -}; - -const renderValue = (value) => value || "Нет данных"; - -const normalizeNom = (nom) => { - if (!nom) return ''; - // 1C escapes backslashes: "СФ Т\\ЕА-33584" → normalize for comparison - return String(nom).replace(/\\\\/g, '\\').trim(); -}; - -const getAllBillNumbers = (order) => { - const orders = parseOrderList(order); - if (!orders.length) return order.orderNumbers || []; - return orders.map((o) => o.nom || o.name || '').filter(Boolean); -}; - -const parseOrderList = (order) => { - if (!order) return []; - - // Try orderList first (Supabase JSONB array of positions) - if (order.orderList) { - let parsed = order.orderList; - if (typeof parsed === 'string') { - try { parsed = JSON.parse(parsed); } catch { /* ignore */ } - } - if (Array.isArray(parsed)) return parsed; - } - - // Fallback: orderListStructured (JSONB with { orders: [...] }) - if (order.orderListStructured) { - let parsed = order.orderListStructured; - if (typeof parsed === 'string') { - try { parsed = JSON.parse(parsed); } catch { /* ignore */ } - } - if (parsed && Array.isArray(parsed.orders)) return parsed.orders; - } - - // Fallback: sourceOrders (1C exchange data) - // 1C sends the FULL order composition (main + associated bills) in EVERY source order's orderList. - // We must deduplicate by nom to avoid showing the same items multiple times. - if (order.sourceOrders) { - let parsed = order.sourceOrders; - if (typeof parsed === 'string') { - try { parsed = JSON.parse(parsed); } catch { /* ignore */ } - } - if (Array.isArray(parsed) && parsed.length > 0) { - const seen = new Set(); - const allItems = []; - for (const src of parsed) { - if (src && Array.isArray(src.orderList)) { - for (const ol of src.orderList) { - if (ol && (ol.items || ol.nom || ol.name)) { - const normalizedNom = normalizeNom(ol.nom || ol.name || ''); - // Deduplicate by nom — 1C repeats same orderList in every source order - if (seen.has(normalizedNom)) continue; - seen.add(normalizedNom); - allItems.push(ol); - } - } - } - } - if (allItems.length > 0) return allItems; - // Legacy: return whole array if no orderList structure - if (parsed[0].orderList && Array.isArray(parsed[0].orderList)) { - return parsed[0].orderList; - } - return parsed; - } - } - - return []; -}; - -const getErrorMessage = (error, fallbackMessage) => { - if (!error) { - return fallbackMessage; - } - - if (error instanceof Error) { - return error.message || fallbackMessage; - } - - if (typeof error === "string") { - return error || fallbackMessage; - } - - return error?.message || fallbackMessage; -}; - -const normalizeDeliveryTimeChoice = (value) => { - const normalized = value ? String(value).trim() : ""; - const deliveryTime = DELIVERY_TIME_ALIASES[normalized] || normalized; - return DELIVERY_TIME_OPTIONS.includes(deliveryTime) ? deliveryTime : DELIVERY_TIME_OPTIONS[0]; -}; - -const toDateKey = (date) => { - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, "0"); - const day = String(date.getDate()).padStart(2, "0"); - return `${year}-${month}-${day}`; -}; - -const fromDateKey = (value) => { - const normalized = normalizeDateForInput(value); - - if (!normalized) { - return null; - } - - const [year, month, day] = normalized.split("-").map(Number); - return new Date(year, month - 1, day); -}; - -const addDays = (date, amount) => { - const nextDate = new Date(date); - nextDate.setDate(nextDate.getDate() + amount); - return nextDate; -}; - -const isWeekendDate = (date) => { - const day = date.getDay(); - return day === 0 || day === 6; -}; - -export const getNextSelectableDateKey = (referenceDate = new Date()) => { - let current = addDays(referenceDate, 1); - - while (isWeekendDate(current)) { - current = addDays(current, 1); - } - - return toDateKey(current); -}; - -const normalizePhoneForTel = (phone) => { - const cleaned = String(phone || "").trim(); - if (!cleaned) return ""; - if (cleaned.startsWith("+7")) return cleaned; - if (cleaned.startsWith("8")) return "+7" + cleaned.slice(1); - return "+7" + cleaned; -}; - -const isFutureDeliveryDate = (value) => { - const parsedDate = fromDateKey(value); - - if (!parsedDate) { - return false; - } - - return !isWeekendDate(parsedDate) && toDateKey(parsedDate) >= getNextSelectableDateKey(); -}; - -const isSelectableCalendarDate = (date, minDateKey) => { - const dateKey = toDateKey(date); - return dateKey >= minDateKey && !isWeekendDate(date); -}; - -const formatDateForDisplay = (value) => { - if (!value) { - return "Выберите дату"; - } - - const [year, month, day] = value.split("-").map(Number); - if (!year || !month || !day) { - return value; - } - - return new Date(year, month - 1, day).toLocaleDateString("ru-RU", { - day: "2-digit", - month: "2-digit", - year: "numeric", - }); -}; - -const formatDeliveryDateDisplay = (value) => { - const normalized = normalizeDateForInput(value); - - if (!normalized) { - return renderValue(value); - } - - return formatDateForDisplay(normalized); -}; - -const startOfMonth = (date) => new Date(date.getFullYear(), date.getMonth(), 1); - -const addMonths = (date, amount) => new Date(date.getFullYear(), date.getMonth() + amount, 1); - -const buildCalendarDays = (currentMonth) => { - const firstDay = startOfMonth(currentMonth); - const lastDay = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 0); - const firstWeekDay = (firstDay.getDay() + 6) % 7; - const totalDays = lastDay.getDate(); - const cells = []; - - for (let index = 0; index < firstWeekDay; index += 1) { - cells.push(null); - } - - for (let day = 1; day <= totalDays; day += 1) { - cells.push(new Date(currentMonth.getFullYear(), currentMonth.getMonth(), day)); - } - - while (cells.length % 7 !== 0) { - cells.push(null); - } - - return cells; -}; - -const normalizeDateForInput = (value) => { - if (!value) { - return ""; - } - - const normalized = String(value).trim(); - if (/^\d{4}-\d{2}-\d{2}$/.test(normalized)) { - return normalized; - } - - const shortDateMatch = normalized.match(/^(\d{2})\.(\d{2})\.(\d{2})$/); - if (shortDateMatch) { - const [, day, month, year] = shortDateMatch; - return `20${year}-${month}-${day}`; - } - - return ""; -}; - -const matchesStopWord = (name, stopWords) => { - if (!stopWords || !stopWords.length) return false; - const lower = name.toLowerCase(); - return stopWords.some((sw) => lower.includes(sw.toLowerCase())); -}; - -const useStopWords = () => { - const [stopWords, setStopWords] = React.useState([]); - const [active, setActive] = React.useState(true); - React.useEffect(() => { - if (!supabase) return; - Promise.all([ - supabase.from("stop_words").select("word").then(r => r.data || []), - supabase.from("stop_words_scope").select("scope").eq("id", 1).single().then(r => r.data), - ]).then(([words, scopeRow]) => { - setStopWords(words.map((d) => d.word)); - setActive(scopeRow?.scope !== "client_only"); - }); - }, []); - return { stopWords, active }; -}; - -const CollapsibleOrderComposition = ({ order }) => { - const [isExpanded, setIsExpanded] = React.useState(false); - const { stopWords, active } = useStopWords(); - - const orders = parseOrderList(order); - const allPositions = orders.reduce((sum, o) => sum + (o.items?.length || 0), 0); - const filteredPositions = active ? orders.reduce((sum, o) => { - if (!o.items) return sum; - return sum + o.items.filter((item) => { - const name = String(item.product_name || item.name || item.title || ""); - return !matchesStopWord(name, stopWords); - }).length; - }, 0) : allPositions; - - return ( -
- - {isExpanded && ( -
- {!orders.length ? ( -

Позиции не указаны

- ) : ( - orders.map((orderItem, idx) => ( -
-
-

{orderItem.nom || orderItem.name || `Заказ ${idx + 1}`}

-
- {(() => { - const filtered = (orderItem.items || []).filter((item) => { - const name = String(item.product_name || item.name || item.title || ""); - return active ? !matchesStopWord(name, stopWords) : true; - }); - if (filtered.length === 0 && active && (orderItem.items || []).length > 0) { - return

Только услуги — скрыты стоп-словами

; - } - if (filtered.length === 0) { - return

Позиции не указаны

; - } - return ( -
- {filtered.map((item, itemIdx) => ( -
- {item.product_name || item.name || item.title || ''} - - {item.product_quantity || item.quantity || item.count || item.amount || ""} {item.product_ed || item.unit || ""} - -
- ))} -
- ); - })()} -
- )) - )} -
- )} -
- ); -}; - -const PaidStoragePanel = ({ order, onChangeDeliveryStatus, isSavingDeliveryChoice, setFormMessage }) => { - const [showConfirm, setShowConfirm] = React.useState(false); - const isPaidStorage = (order.deliveryStatus || order.delivery_status) === "paid_storage"; - - if (isPaidStorage) { - return ( - -
- - Платное хранение -
- {order.paidStorageAt && ( -

- Переведено: {formatDateTime(order.paidStorageAt)} -

- )} - -
- ); - } - - return ( - -
- Платное хранение -

- Переведите заказ в статус платного хранения, если клиент не забрал товар в срок. -

-
- - {showConfirm ? ( -
-

Перевести заказ в платное хранение? Клиент получит уведомление.

-
- - -
-
- ) : ( - - )} -
- ); -}; - - -const PROBLEM_REASONS = [ - { value: "client_absent", label: "Клиент не принял", description: "Клиент отказался или не вышел на связь" }, - { value: "damage", label: "Повреждение заказа", description: "Товар повреждён при транспортировке" }, - { value: "wrong_address", label: "Неверный адрес", description: "Адрес доставки указан неверно" }, - { value: "other", label: "Другое", description: "Иная причина проблемы доставки" }, -]; - -const ProblemReasonModal = ({ onSelect, onCancel }) => ( -
- e.stopPropagation()}> -

Причина проблемы

-

Укажите причину возникшей проблемы с доставкой.

-
- {PROBLEM_REASONS.map((reason) => ( - - ))} -
-
- -
-
-
-); - -export const OrderDetailPanel = ({ - order, - canManageDelivery = false, - onSaveManualDeliveryChoice, - isSavingDeliveryChoice = false, - drivers = [], - onAssignDriver, - onChangeDeliveryStatus, - userRole, -}) => { - const [problemReason, setProblemReason] = React.useState(null); - const [pendingStatus, setPendingStatus] = React.useState(null); - const [deliveryDate, setDeliveryDate] = React.useState(""); - const [deliveryTime, setDeliveryTime] = React.useState(DELIVERY_TIME_OPTIONS[0]); - const [formMessage, setFormMessage] = React.useState(""); - const [shipmentState, setShipmentState] = React.useState(null); - const [isCalendarOpen, setIsCalendarOpen] = React.useState(false); - const [driverMessage, setDriverMessage] = React.useState(""); - const [selectedDriverId, setSelectedDriverId] = React.useState(order?.assignedDriverId || ""); - const [deliveryType, setDeliveryType] = React.useState(order?.deliveryType || "delivery"); - const [pickupDate, setPickupDate] = React.useState(order?.pickupDate || ""); - const [pickupTimeSlot, setPickupTimeSlot] = React.useState(DELIVERY_TIME_OPTIONS[0]); - const minSelectableDateKey = React.useMemo(() => getNextSelectableDateKey(), []); - const [currentMonth, setCurrentMonth] = React.useState(() => { - const existingDeliveryDate = fromDateKey(order?.deliveryDate); - const fallbackDate = fromDateKey(minSelectableDateKey) || new Date(); - const sourceDate = existingDeliveryDate && isFutureDeliveryDate(toDateKey(existingDeliveryDate)) - ? existingDeliveryDate - : fallbackDate; - - return startOfMonth(sourceDate); - }); - const calendarDays = React.useMemo(() => buildCalendarDays(currentMonth), [currentMonth]); - const monthLabel = React.useMemo( - () => - currentMonth.toLocaleDateString("ru-RU", { - month: "long", - year: "numeric", - }), - [currentMonth], - ); - const canGoBack = toDateKey(currentMonth) > toDateKey(startOfMonth(fromDateKey(minSelectableDateKey) || new Date())); - - React.useEffect(() => { - setSelectedDriverId(order?.assignedDriverId || ""); - setIsEditingDate(false); - }, [order?.id, order?.assignedDriverId]); - - React.useEffect(() => { - const normalizedDeliveryDate = normalizeDateForInput(order?.deliveryDate); - const nextSelectableDateKey = getNextSelectableDateKey(); - const selectedDateKey = isFutureDeliveryDate(normalizedDeliveryDate) ? normalizedDeliveryDate : nextSelectableDateKey; - setDeliveryDate(selectedDateKey); - const selectedDate = fromDateKey(selectedDateKey) || new Date(); - setCurrentMonth(startOfMonth(selectedDate)); - setDeliveryTime(normalizeDeliveryTimeChoice(order?.deliveryTime || order?.deliveryHalfDay)); - setDeliveryType(order?.deliveryType || "delivery"); - setPickupDate(order?.pickupDate || ""); - setPickupTimeSlot(normalizeDeliveryTimeChoice(order?.pickupTimeSlot || order?.deliveryTime || order?.deliveryHalfDay)); - setFormMessage(""); - }, [order?.id, order?.deliveryDate, order?.deliveryHalfDay, order?.deliveryTime, order?.deliveryType, order?.pickupDate, order?.pickupTimeSlot]); - - if (!order) { - return ( - -

Выберите группу для просмотра деталей.

-
- ); - } - - const isDeliveryAgreed = ["agreed", "driver_assigned", "loaded", "on_route", "delivered"].includes(order.deliveryStatus || order.delivery_status); - const canEditDelivery = canManageDelivery && ["admin", "mega_admin", "logistician"].includes(userRole); - const [isEditingDate, setIsEditingDate] = React.useState(false); - const agreedDeliveryLabel = [ - formatDeliveryDateDisplay(order.deliveryDate), - order.deliveryTime || order.deliveryHalfDay, - ].filter((value) => value && value !== "Нет данных").join(" · "); - - const handleShipmentChange = React.useCallback((state) => { - setShipmentState(state); - }, []); - - const handleSaveDeliveryChoice = async () => { - const effectiveDate = deliveryType === "pickup" ? pickupDate : deliveryDate; - const effectiveTime = deliveryType === "pickup" ? pickupTimeSlot : deliveryTime; - if (!effectiveDate || !effectiveTime) { - setFormMessage(deliveryType === "pickup" ? "Укажите дату и время самовывоза." : "Укажите дату и половину дня доставки."); - return; - } - - if (!isFutureDeliveryDate(effectiveDate)) { - setFormMessage(deliveryType === "pickup" ? "Выберите дату самовывоза позже сегодняшнего дня." : "Выберите дату доставки позже сегодняшнего дня."); - return; - } - - try { - const result = await onSaveManualDeliveryChoice?.({ - orderGroupId: order.id, - deliveryDate: deliveryType === "pickup" ? pickupDate : deliveryDate, - deliveryTime: deliveryType === "pickup" ? pickupTimeSlot : deliveryTime, - deliveryType, - ...(deliveryType === "pickup" ? { pickupDate, pickupTimeSlot } : {}), - }); - - if (result?.success) { - setFormMessage("Доставка согласована вручную."); - return; - } - - setFormMessage(getErrorMessage(result?.error, "Не удалось сохранить согласование доставки.")); - } catch (error) { - setFormMessage(getErrorMessage(error, "Не удалось сохранить согласование доставки.")); - } - }; - - const handleAssignDriver = async () => { - if (!selectedDriverId) { - setDriverMessage("Выберите водителя"); - return; - } - - if (!order.deliveryDate) { - setDriverMessage("Сначала укажите дату и время доставки."); - return; - } - - setDriverMessage(""); - const response = await onAssignDriver({ - orderGroupId: order.id, - driverId: selectedDriverId, - }); - - if (!response.success) { - setDriverMessage(response.error || "Не удалось назначить водителя"); - } else { - setDriverMessage("Водитель назначен"); - } - }; - - return ( -
- -
-
-

- Карточка группы доставки -

-

- {order.displayTitle || order.customerName || order.groupKey} -

-

- {order.displaySubtitle || [order.customerPhone, order.customerDate].filter(Boolean).join(" · ") || "Не указано"} -

-
- {getOrderGroupDisplayStatusLabel(order)} -
- -
-
-

- Дата доставки -

-

{formatDeliveryDateDisplay(order.deliveryDate)}

-
-
-

- Время доставки -

-

{renderValue(order.deliveryTime || order.deliveryHalfDay)}

-
-
-

- Тип доставки -

-

{order.deliveryType === "pickup" ? "Самовывоз" : "Доставка"}

-
-
-

- Водитель -

-

{order.assignedDriverId ? renderValue(order.assignedDriverName) : "Не назначен"}

-
-
-

- Телефон -

- - {renderValue(order.customerPhone)} - -
-
-

- Адрес доставки -

-

{renderValue(order.deliveryAddress)}

-
-
- -
-
-

Номер счёта

-

{renderValue(order.orderNumberSummary)}

-
-
-

Клиент

-

{renderValue(order.customerName)}

-
-
-

Дата счёта

-

{renderValue(order.customerDate)}

-
-
-

Всего заказов

-

{order.ordersCount ?? 0}

-
-
-

Готово

-

{order.readyCount ?? 0}

-
-
-

Не готово

-

{order.notReadyCount ?? 0}

-
-
-

Обновлена

-

{formatDateTime(order.updatedAt)}

-
-
-

Статус доставки

-

{getOrderGroupDeliveryStatusLabel(order.deliveryStatus || order.delivery_status)}

-
-
-
- - {canManageDelivery ? ( - -
- Ручное согласование доставки -

- {isDeliveryAgreed - ? "Дата и половина дня доставки уже зафиксированы." - : "Если клиент согласовал доставку по телефону, сохраните дату и половину дня здесь."} -

-
- {/* Delivery type tabs */} -
- - -
- {deliveryType === "pickup" && ( -
-

ℹ️ Условия хранения

-

Бесплатное хранение — 2 рабочих дня с даты готовности.

-

Начиная с 3-го рабочего дня — 300 ₽/день платного хранения.

-
- )} - {isDeliveryAgreed && !isEditingDate ? ( -
-
-
-
-

- Доставка согласована -

-

- {agreedDeliveryLabel || "Дата и время сохранены"} -

-
- Согласовано -
-
- {canEditDelivery ? ( - - ) : null} -
- ) : deliveryType === "delivery" ? ( -
-
- - {isCalendarOpen ? ( -
-
-
-

- Календарь доставки -

-

- {monthLabel} -

-
-
- - -
-
-
- {WEEK_DAY_LABELS.map((day) => ( -
- {day} -
- ))} -
-
- {calendarDays.map((day, index) => { - if (!day) { - return
; - } - - const dateKey = toDateKey(day); - const isWeekend = isWeekendDate(day); - const isSelectable = isSelectableCalendarDate(day, minSelectableDateKey); - const isSelected = dateKey === deliveryDate; - const isDisabled = !isSelectable; - const dayNumber = String(day.getDate()).padStart(2, "0"); - - return ( - - ); - })} -
-

- Выходные отмечены пунктиром и недоступны. -

-
- ) : null} -
-
- {DELIVERY_TIME_OPTIONS.map((option) => ( - - ))} -
- ) : ( -
- - {isCalendarOpen ? ( -
-
-
-

Календарь самовывоза

-

{monthLabel}

-
-
- - -
-
-
- {WEEK_DAY_LABELS.map((day) => (
{day}
))} -
-
- {calendarDays.map((day, index) => { - if (!day) return
; - const dateKey = toDateKey(day); - const isWeekend = isWeekendDate(day); - const isSelectable = isSelectableCalendarDate(day, minSelectableDateKey); - const isSelected = dateKey === pickupDate; - const isDisabled = !isSelectable; - const dayNumber = String(day.getDate()).padStart(2, "0"); - return ( - - ); - })} -
-

Выходные отмечены пунктиром и недоступны.

-
- ) : null} -
- {DELIVERY_TIME_OPTIONS.map((option) => ( - - ))} -
-
- )} - - )} - {formMessage ? ( -

{formMessage}

- ) : null} - - ) : null} - - - {canManageDelivery && ["manager", "logistician", "admin", "mega_admin"].includes(userRole) ? ( - -
- Назначение водителя -

- {(() => { - const ds = order.deliveryStatus || order.delivery_status; - if (["loaded", "on_route", "delivered"].includes(ds)) { - return "Доставка в процессе — сменить водителя нельзя."; - } - return order.assignedDriverId - ? "Назначен водитель. Вы можете изменить назначение." - : "Выберите водителя для доставки."; - })()} -

-
- {order.assignedDriverId ? ( -
-
-
-

- Водитель назначен -

-

- {order.assignedDriverName || "Неизвестно"} -

-
- Назначен -
-
- ) : null} - {(() => { - const ds = order.deliveryStatus || order.delivery_status; - const isDriverLocked = ["loaded", "on_route", "delivered"].includes(ds); - return !isDriverLocked ? ( -
- - -
- ) : null; - })()} - {driverMessage ? ( -

{driverMessage}

- ) : null} -
- ) : null} - - - {["manager", "logistician", "admin", "mega_admin"].includes(userRole) && order && onChangeDeliveryStatus ? ( - -
- Статус доставки -

- Измените статус, если водитель забыл обновить или нужна корректировка. -

-
-
- {[ - { value: "pending_confirmation", label: "Ожидает согласования", manual: true }, - { value: "agreed", label: "Согласовано", manual: false, hint: "Согласуйте дату доставки выше" }, - { value: "driver_assigned", label: "Назначен водитель", manual: false, hint: "Назначьте водителя из списка" }, - { value: "loaded", label: "Загружено", manual: true }, - { value: "on_route", label: "В пути", manual: true }, - { value: "delivered", label: "Доставлено", manual: true }, - { value: "pickup", label: "Самовывоз", manual: true }, - { value: "problem", label: "Проблема", manual: true }, - { value: "cancelled", label: "Отменено", manual: true }, - ].map((statusOption) => { - const isCurrent = (order.deliveryStatus || order.delivery_status) === statusOption.value; - const isClickable = statusOption.manual !== false && !isCurrent; - return ( -
- -
- ); - })} -
- {formMessage ? ( -

{formMessage}

- ) : null} -
- ) : null} - - - {["manager", "logistician", "admin", "mega_admin"].includes(userRole) && order && onChangeDeliveryStatus ? ( - - ) : null} - - {userRole === "driver" && order ? ( - - ) : null} - -{userRole === "driver" && order && onChangeDeliveryStatus ? ( - -
- Статус доставки -

- Выберите статус и нажмите «Сохранить». -

-
- {problemReason !== null ? ( - { - setPendingStatus({ value: "problem", reason: reasonValue, reasonLabel }); - setProblemReason(null); - }} - onCancel={() => setProblemReason(null)} - /> - ) : null} -
- {(() => { - const currentStatus = order.deliveryStatus || order.delivery_status; - const IN_TRANSIT_STATUSES = ["loaded", "on_route"]; - const isOnRoute = IN_TRANSIT_STATUSES.includes(currentStatus); - - let statusOptions = []; - if (currentStatus === "delivered" || currentStatus === "problem" || currentStatus === "cancelled" || currentStatus === "paid_storage") { - statusOptions = []; - } else { - statusOptions = [ - { value: "delivered", label: "Доставлено" }, - { value: "problem", label: "Проблема" }, - ]; - } - - if (statusOptions.length === 0) return null; - - return statusOptions.map((statusOption) => { - const isSelected = pendingStatus?.value === statusOption.value; - const isDeliveredBtn = statusOption.value === "delivered"; - const deliveryBlocked = isDeliveredBtn && shipmentState && !shipmentState.canMarkDelivered; - return ( - - ); - }); - })()} -
- {pendingStatus ? ( -
- - -
- ) : null} - {formMessage ? ( -

{formMessage}

- ) : null} -
- ) : null} - - - Счета - {renderList(getAllBillNumbers(order))} - - - - - - {userRole !== "driver" && (order?.driver_shipment_data || order?.driverShipmentData) ? ( - - ) : null} - {userRole !== "driver" ? ( - - Дополнительные данные -
- {order.firstSmsSentAt ? ( -
-

1-е SMS отправлено

-

{formatDateTime(order.firstSmsSentAt)}

-
- ) : null} - {order.secondSmsSentAt ? ( -
-

2-е SMS отправлено

-

{formatDateTime(order.secondSmsSentAt)}

-
- ) : null} - {!order.firstSmsSentAt && !order.secondSmsSentAt ? ( -
-

SMS отправлено

-

Нет

-
- ) : null} -
-

Ручное согласование выполнено

-

{order.manualConfirmationAt ? formatDateTime(order.manualConfirmationAt) : "Нет"}

-
-
-

Платное хранение

-

{order.paidStorageAt ? formatDateTime(order.paidStorageAt) : "Нет"}

-
- {order.createdFromExchangeAt ? ( -
-

Создано из обмена

-

{formatDateTime(order.createdFromExchangeAt)}

-
- ) : null} -
-
- ) : null} -
- ); -};