From 498faca24dec32419205e1170560df932f75ad32 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 12 Jun 2026 08:23:41 +0000 Subject: [PATCH] feat: delivery/pickup switching in admin card + address field - Added delivery address input field in manual agreement form (visible when delivery type) - Pickup switching clears delivery_address in DB, delivery switching preserves/updates it - useOrderGroups passes deliveryType, deliveryAddress, pickupDate, pickupTimeSlot to API - orderGroupRepository: updateOrderGroupDeliveryChoice now handles delivery_type and address - Pickup orders: address cleared, pickup_date/pickup_time_slot saved - Delivery orders: address saved, pickup fields cleared - Updated tests to match new payload structure --- src/components/orders/OrderDetailPanel.jsx | 18 ++++++++-- src/hooks/useOrderGroups.js | 8 +++++ src/services/supabase/orderGroupRepository.js | 33 ++++++++++++------- .../supabase/orderGroupRepository.test.js | 7 ++-- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/components/orders/OrderDetailPanel.jsx b/src/components/orders/OrderDetailPanel.jsx index a2e2015..87e43f9 100644 --- a/src/components/orders/OrderDetailPanel.jsx +++ b/src/components/orders/OrderDetailPanel.jsx @@ -637,8 +637,8 @@ export const OrderDetailPanel = ({ deliveryDate: deliveryType === "pickup" ? pickupDate : deliveryDate, deliveryTime: deliveryType === "pickup" ? pickupTimeSlot : deliveryTime, deliveryType, - ...(deliveryType === "pickup" ? { pickupDate, pickupTimeSlot } : {}), - ...(deliveryType === "delivery" && deliveryAddress.trim() ? { deliveryAddress: deliveryAddress.trim() } : {}), + ...(deliveryType === "pickup" ? { pickupDate, pickupTimeSlot, deliveryAddress: "" } : {}), + ...(deliveryType === "delivery" ? { deliveryAddress: deliveryAddress.trim() } : {}), }); if (result?.success) { @@ -866,6 +866,20 @@ export const OrderDetailPanel = ({

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

)} + {deliveryType === "delivery" && ( +
+ + setDeliveryAddress(e.target.value)} + placeholder="Введите адрес доставки" + className="w-full rounded-2xl border border-[var(--color-border)] bg-[var(--color-surface)] px-4 py-3 text-sm !text-[var(--color-text)] placeholder:text-[var(--color-text-muted)] focus:border-[var(--color-accent)] focus:outline-none" + /> +
+ )} {isDeliveryAgreed && !isEditingDate ? (
diff --git a/src/hooks/useOrderGroups.js b/src/hooks/useOrderGroups.js index 6b5c922..6d3969b 100644 --- a/src/hooks/useOrderGroups.js +++ b/src/hooks/useOrderGroups.js @@ -115,6 +115,10 @@ export const useOrderGroups = () => { orderGroupId, deliveryDate, deliveryTime, + deliveryType, + deliveryAddress, + pickupDate, + pickupTimeSlot, }) => { setIsSavingDeliveryChoice(true); @@ -125,6 +129,10 @@ export const useOrderGroups = () => { orderGroupId, deliveryDate, deliveryTime, + deliveryType, + deliveryAddress, + pickupDate, + pickupTimeSlot, }); if (result.error) { diff --git a/src/services/supabase/orderGroupRepository.js b/src/services/supabase/orderGroupRepository.js index 9784419..a9b85f6 100644 --- a/src/services/supabase/orderGroupRepository.js +++ b/src/services/supabase/orderGroupRepository.js @@ -258,25 +258,36 @@ export const updateOrderGroupDeliveryChoice = async ({ deliveryDate, deliveryTime, deliveryType, + deliveryAddress, pickupDate, pickupTimeSlot, }) => { return safeSupabaseCall(async () => { const client = requireSupabase(); const effectiveDeliveryStatus = deliveryType === "pickup" ? "pickup" : "agreed"; + const updatePayload = { + delivery_status: effectiveDeliveryStatus, + delivery_date: deliveryDate, + delivery_time: deliveryTime, + delivery_type: deliveryType || "delivery", + delivery_date_source: "manual", + notification_status: "confirmed", + updated_at: new Date().toISOString(), + }; + if (deliveryType === "pickup") { + updatePayload.pickup_date = pickupDate || null; + updatePayload.pickup_time_slot = pickupTimeSlot || null; + updatePayload.delivery_address = ""; + } else { + updatePayload.pickup_date = null; + updatePayload.pickup_time_slot = null; + if (deliveryAddress !== undefined) { + updatePayload.delivery_address = deliveryAddress; + } + } const updateResult = await client .from("order_groups") - .update({ - delivery_status: effectiveDeliveryStatus, - delivery_date: deliveryDate, - delivery_time: deliveryTime, - delivery_type: deliveryType || "delivery", - pickup_date: deliveryType === "pickup" ? pickupDate : null, - pickup_time_slot: deliveryType === "pickup" ? pickupTimeSlot : null, - delivery_date_source: "manual", - notification_status: "confirmed", - updated_at: new Date().toISOString(), - }) + .update(updatePayload) .eq("id", orderGroupId); if (updateResult.error) { diff --git a/src/services/supabase/orderGroupRepository.test.js b/src/services/supabase/orderGroupRepository.test.js index a2d796a..fc2a081 100644 --- a/src/services/supabase/orderGroupRepository.test.js +++ b/src/services/supabase/orderGroupRepository.test.js @@ -158,15 +158,16 @@ describe("updateOrderGroupDeliveryChoice", () => { }); expect(fromMock).toHaveBeenCalledWith("order_groups"); - expect(updateMock).toHaveBeenCalledWith({ + expect(updateMock).toHaveBeenCalledWith(expect.objectContaining({ delivery_status: "agreed", delivery_date: "2026-05-13", delivery_time: "Первая половина дня", + delivery_type: "delivery", notification_status: "confirmed", updated_at: expect.any(String), - }); + })); expect(eqMock).toHaveBeenCalledWith("id", "group-id"); - expect(selectMock).toHaveBeenCalledWith("id, group_key, order_numbers, status, delivery_status, sms_sent_at, created_at, updated_at, created_from_exchange_at, source_key, customer_name, customer_phone, customer_phone_normalized, customer_date, orders_total, orders_ready, orders_not_ready, source_orders, order_list, order_list_structured, delivery_invitation_id, delivery_link, notification_status, sms_attempts, first_sms_sent_at, second_sms_sent_at, last_sms_error, next_notification_check_at, delivery_date, delivery_time, delivery_address, manual_confirmation_at, paid_storage_at, assigned_driver_id, assigned_driver:users!order_groups_assigned_driver_id_fkey(id, name)"); + expect(selectMock).toHaveBeenCalledWith(expect.stringContaining("delivery_type, pickup_date, pickup_time_slot")); expect(singleMock).toHaveBeenCalledTimes(1); }); });