fix: block Доставлено/Вывезено without delivery date+half-day, remove Загружено from logistic panel

- StatusActionPanel: removed Загружено button
- StatusActionPanel: Доставлено/Вывезено require deliveryDate + half-day
- StatusActionPanel: warning banner when schedule missing
- Driver status panel in OrderDetailPanel: same schedule check
- Blocked buttons shown dimmed (opacity-40)
This commit is contained in:
root 2026-07-13 12:02:25 +00:00
parent fbfcb71d61
commit 1ffd8bacc5
2 changed files with 26 additions and 8 deletions

View File

@ -1167,6 +1167,7 @@ export const OrderDetailPanel = ({
return statusOptions.map((statusOption) => { return statusOptions.map((statusOption) => {
const isSelected = pendingStatus?.value === statusOption.value; const isSelected = pendingStatus?.value === statusOption.value;
const isMismatch = statusOption.mismatch; const isMismatch = statusOption.mismatch;
const blockedBySchedule = statusOption.requiresSchedule && !hasDeliverySchedule;
return ( return (
<Button <Button
key={statusOption.value} key={statusOption.value}

View File

@ -20,15 +20,19 @@ const StatusActionPanel = ({
const currentStatus = order.deliveryStatus || order.delivery_status; const currentStatus = order.deliveryStatus || order.delivery_status;
const isPickup = (order.deliveryType || order.delivery_type) === "pickup" || currentStatus === "pickup"; const isPickup = (order.deliveryType || order.delivery_type) === "pickup" || currentStatus === "pickup";
// Build status options primary matches delivery type, secondary is mismatch // Check if delivery date and half-day are set
const hasDeliveryDate = !!(order.deliveryDate || order.customerDate);
const hasDeliveryHalfDay = !!(order.deliveryTime || order.deliveryHalfDay || order.delivery_time || order.delivery_half_day);
const hasDeliverySchedule = hasDeliveryDate && hasDeliveryHalfDay;
// Build status options no "Загружено", "Доставлено"/"Вывезено" require date+half-day
const allStatuses = isPickup const allStatuses = isPickup
? [ ? [
{ value: "pending_confirmation", label: "Ожидает согласования", manual: true }, { value: "pending_confirmation", label: "Ожидает согласования", manual: true },
{ value: "agreed", label: "Согласовано", manual: false, hint: "Согласуйте дату доставки выше" }, { value: "agreed", label: "Согласовано", manual: false, hint: "Согласуйте дату доставки выше" },
{ value: "driver_assigned", label: "Назначен водитель", manual: false, hint: "Назначьте водителя из списка" }, { value: "driver_assigned", label: "Назначен водитель", manual: false, hint: "Назначьте водителя из списка" },
{ value: "loaded", label: "Загружено", manual: true }, { value: "picked_up", label: "Вывезено", manual: true, primary: true, requiresSchedule: true },
{ value: "picked_up", label: "Вывезено", manual: true, primary: true }, { value: "delivered", label: "Доставлено", manual: true, mismatch: true, requiresSchedule: true },
{ value: "delivered", label: "Доставлено", manual: true, mismatch: true },
{ value: "requires_address", label: "Требуется адрес", manual: true }, { value: "requires_address", label: "Требуется адрес", manual: true },
{ value: "problem", label: "Проблема", manual: true }, { value: "problem", label: "Проблема", manual: true },
{ value: "cancelled", label: "Отменено", manual: true }, { value: "cancelled", label: "Отменено", manual: true },
@ -37,9 +41,8 @@ const StatusActionPanel = ({
{ value: "pending_confirmation", label: "Ожидает согласования", manual: true }, { value: "pending_confirmation", label: "Ожидает согласования", manual: true },
{ value: "agreed", label: "Согласовано", manual: false, hint: "Согласуйте дату доставки выше" }, { value: "agreed", label: "Согласовано", manual: false, hint: "Согласуйте дату доставки выше" },
{ value: "driver_assigned", label: "Назначен водитель", manual: false, hint: "Назначьте водителя из списка" }, { value: "driver_assigned", label: "Назначен водитель", manual: false, hint: "Назначьте водителя из списка" },
{ value: "loaded", label: "Загружено", manual: true }, { value: "delivered", label: "Доставлено", manual: true, primary: true, requiresSchedule: true },
{ value: "delivered", label: "Доставлено", manual: true, primary: true }, { value: "picked_up", label: "Вывезено", manual: true, mismatch: true, requiresSchedule: true },
{ value: "picked_up", label: "Вывезено", manual: true, mismatch: true },
{ value: "requires_address", label: "Требуется адрес", manual: true }, { value: "requires_address", label: "Требуется адрес", manual: true },
{ value: "problem", label: "Проблема", manual: true }, { value: "problem", label: "Проблема", manual: true },
{ value: "cancelled", label: "Отменено", manual: true }, { value: "cancelled", label: "Отменено", manual: true },
@ -57,6 +60,7 @@ const StatusActionPanel = ({
{allStatuses.map((statusOption) => { {allStatuses.map((statusOption) => {
const isCurrent = currentStatus === statusOption.value; const isCurrent = currentStatus === statusOption.value;
const isClickable = statusOption.manual !== false && !isCurrent; const isClickable = statusOption.manual !== false && !isCurrent;
const blockedBySchedule = statusOption.requiresSchedule && !hasDeliverySchedule;
return ( return (
<div key={statusOption.value} className="relative group"> <div key={statusOption.value} className="relative group">
<Button <Button
@ -66,6 +70,13 @@ const StatusActionPanel = ({
onConfirmStatus?.({ type: "hint", hint: statusOption.hint || "" }); onConfirmStatus?.({ type: "hint", hint: statusOption.hint || "" });
return; return;
} }
if (blockedBySchedule) {
onConfirmStatus?.({
type: "hint",
hint: "⚠ Нельзя поставить «" + statusOption.label + "» без даты и времени доставки. Сначала согласуйте дату выше.",
});
return;
}
onConfirmStatus?.({ onConfirmStatus?.({
type: "status", type: "status",
status: statusOption.value, status: statusOption.value,
@ -75,6 +86,7 @@ const StatusActionPanel = ({
}); });
}} }}
disabled={isSavingStatusChange} disabled={isSavingStatusChange}
className={blockedBySchedule ? "opacity-40 cursor-not-allowed" : ""}
> >
{statusOption.label} {statusOption.label}
</Button> </Button>
@ -82,8 +94,13 @@ const StatusActionPanel = ({
); );
})} })}
</div> </div>
{!hasDeliverySchedule && (
<div className="rounded-xl border border-[var(--color-warning)] bg-[var(--color-warning-soft)] px-3 py-2 text-xs text-[var(--color-warning)]">
Чтобы поставить «Доставлено» или «Вывезено», сначала укажите дату и половину дня доставки выше.
</div>
)}
</Panel> </Panel>
); );
}; };
export { StatusActionPanel }; export { StatusActionPanel };