fix: аудит доставки — критические и средние баги
Edge function confirm-delivery-choice: - currentGroup использовался до объявления — перемещён вверх - pickup не очищал assigned_driver_id — добавлена очистка - выборка currentGroup теперь включает delivery_address, customer_address Edge function update-order-group-delivery-choice: - добавлена поддержка deliveryType=pickup (ранее всегда ставил 'agreed') - pickup очищает assigned_driver_id, устанавливает pickup_date/time_slot - дата доставки не обязательна для pickup Фронтенд: - assignDriverToOrderGroup: null → 'agreed' (NOT NULL constraint) - isDeliveryAgreed включает статус 'pickup' - orderGroupViews: warning-тон для групп с проблемами отгрузки - OrdersTable: колонка Отгрузка с визуализацией проблем
This commit is contained in:
parent
3847625005
commit
41272bdbbf
|
|
@ -635,7 +635,7 @@ export const OrderDetailPanel = ({
|
|||
);
|
||||
}
|
||||
|
||||
const isDeliveryAgreed = ["agreed", "driver_assigned", "loaded", "on_route", "delivered", "picked_up"].includes(order.deliveryStatus || order.delivery_status);
|
||||
const isDeliveryAgreed = ["agreed", "driver_assigned", "loaded", "on_route", "delivered", "picked_up", "pickup"].includes(order.deliveryStatus || order.delivery_status);
|
||||
const isPickupOrder = order.deliveryType === "pickup" || order.deliveryStatus === "pickup" || order.delivery_status === "pickup";
|
||||
// Show "agreed" banner only when selected tab matches the already-agreed type
|
||||
const agreedTypeMatchesTab = isDeliveryAgreed && !isEditingDate && (
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ export const assignDriverToOrderGroup = async ({
|
|||
const ADVANCED_STATUSES = ["loaded", "on_route", "delivered", "picked_up"];
|
||||
const newStatus = driverId
|
||||
? (ADVANCED_STATUSES.includes(currentStatus) ? undefined : "driver_assigned")
|
||||
: null; // removing driver → reset to pending
|
||||
: "agreed"; // removing driver → revert to agreed (NOT null — would violate NOT NULL constraint)
|
||||
const updates = {
|
||||
assigned_driver_id: driverId || null,
|
||||
...(newStatus !== undefined && { delivery_status: newStatus }),
|
||||
|
|
|
|||
|
|
@ -138,6 +138,17 @@ Deno.serve(async (request) => {
|
|||
|
||||
const deliveryType = body.deliveryType || "delivery";
|
||||
|
||||
if (invitation.order_group_id) {
|
||||
const { data: currentGroup, error: groupError } = await supabase
|
||||
.from("order_groups")
|
||||
.select("id, delivery_status, delivery_address, customer_address")
|
||||
.eq("id", invitation.order_group_id)
|
||||
.single();
|
||||
|
||||
if (groupError) {
|
||||
throw groupError;
|
||||
}
|
||||
|
||||
// When user switches from pickup to delivery but has no address → requires_address
|
||||
const hasAddress = invitation.delivery_address?.trim() || currentGroup?.delivery_address?.trim() || currentGroup?.customer_address?.trim();
|
||||
const effectiveDeliveryStatus = deliveryType === "pickup"
|
||||
|
|
@ -146,17 +157,6 @@ Deno.serve(async (request) => {
|
|||
? "agreed"
|
||||
: "requires_address";
|
||||
|
||||
if (invitation.order_group_id) {
|
||||
const { data: currentGroup, error: groupError } = await supabase
|
||||
.from("order_groups")
|
||||
.select("id, delivery_status")
|
||||
.eq("id", invitation.order_group_id)
|
||||
.single();
|
||||
|
||||
if (groupError) {
|
||||
throw groupError;
|
||||
}
|
||||
|
||||
if (!isActiveInvitationState(invitation.state) || currentGroup.delivery_status !== "pending_confirmation") {
|
||||
return jsonResponse(
|
||||
{
|
||||
|
|
@ -208,6 +208,8 @@ Deno.serve(async (request) => {
|
|||
if (deliveryType === "pickup") {
|
||||
groupUpdateData.pickup_date = body.pickupDate || requestedSlot.deliveryDate || null;
|
||||
groupUpdateData.pickup_time_slot = body.pickupTimeSlot || requestedSlot.deliveryTime || null;
|
||||
// Pickup orders don't need a driver — clear assignment
|
||||
groupUpdateData.assigned_driver_id = null;
|
||||
}
|
||||
|
||||
const { error: groupUpdateError } = await supabase
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ type UpdateDeliveryChoiceBody = {
|
|||
orderGroupId?: string;
|
||||
deliveryDate?: string;
|
||||
deliveryTime?: string;
|
||||
deliveryType?: string;
|
||||
pickupDate?: string;
|
||||
pickupTimeSlot?: string;
|
||||
};
|
||||
|
||||
const isValidDate = (value: string) => /^\d{4}-\d{2}-\d{2}$/.test(value);
|
||||
|
|
@ -111,12 +114,14 @@ Deno.serve(async (request) => {
|
|||
const orderGroupId = String(body.orderGroupId || "").trim();
|
||||
const deliveryDate = String(body.deliveryDate || "").trim();
|
||||
const deliveryTime = normalizeDeliveryTime(String(body.deliveryTime || "").trim());
|
||||
const deliveryType = String(body.deliveryType || "delivery").trim();
|
||||
|
||||
if (!orderGroupId) {
|
||||
return jsonResponse({ ok: false, error: "orderGroupId is required" }, 400, corsHeaders);
|
||||
}
|
||||
|
||||
if (!isAllowedDeliveryDate(deliveryDate)) {
|
||||
// Pickup orders don't require a delivery date — allow skipping date validation
|
||||
if (deliveryType !== "pickup" && !isAllowedDeliveryDate(deliveryDate)) {
|
||||
return jsonResponse({ ok: false, error: "Выберите будущий будний день доставки" }, 400, corsHeaders);
|
||||
}
|
||||
|
||||
|
|
@ -155,15 +160,29 @@ Deno.serve(async (request) => {
|
|||
throw currentGroupError;
|
||||
}
|
||||
|
||||
const effectiveDeliveryStatus = deliveryType === "pickup" ? "pickup" : "agreed";
|
||||
|
||||
const updateData: Record<string, unknown> = {
|
||||
delivery_status: effectiveDeliveryStatus,
|
||||
delivery_date: deliveryDate || null,
|
||||
delivery_time: deliveryTime || null,
|
||||
delivery_type: deliveryType,
|
||||
notification_status: "confirmed",
|
||||
updated_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
if (deliveryType === "pickup") {
|
||||
updateData.pickup_date = body.pickupDate || deliveryDate || null;
|
||||
updateData.pickup_time_slot = body.pickupTimeSlot || deliveryTime || null;
|
||||
updateData.assigned_driver_id = null;
|
||||
} else {
|
||||
updateData.pickup_date = null;
|
||||
updateData.pickup_time_slot = null;
|
||||
}
|
||||
|
||||
const { data: group, error: groupUpdateError } = await supabase
|
||||
.from("order_groups")
|
||||
.update({
|
||||
delivery_status: "agreed",
|
||||
delivery_date: deliveryDate,
|
||||
delivery_time: deliveryTime,
|
||||
notification_status: "confirmed",
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.update(updateData)
|
||||
.eq("id", orderGroupId)
|
||||
.select("*")
|
||||
.single();
|
||||
|
|
@ -198,7 +217,8 @@ Deno.serve(async (request) => {
|
|||
actor_user_id: actor.userId,
|
||||
actor_role: actor.role,
|
||||
old_delivery_status: currentGroup.delivery_status || null,
|
||||
new_delivery_status: "agreed",
|
||||
new_delivery_status: effectiveDeliveryStatus,
|
||||
delivery_type: deliveryType,
|
||||
delivery_date: deliveryDate,
|
||||
delivery_time: deliveryTime,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue