diff --git a/src/components/orders/OrderDetailPanel.jsx b/src/components/orders/OrderDetailPanel.jsx
index 4aacb0b..bb2f6b2 100644
--- a/src/components/orders/OrderDetailPanel.jsx
+++ b/src/components/orders/OrderDetailPanel.jsx
@@ -863,6 +863,12 @@ export const OrderDetailPanel = ({
{isPickupOrder ? "Статус самовывоза" : "Статус доставки"}
{getOrderGroupDeliveryStatusLabel(order.deliveryStatus || order.delivery_status)}
+ {(order.pickupCode || order.pickup_code) ? (
+
+
Код выдачи
+
{order.pickupCode || order.pickup_code}
+
+ ) : null}
@@ -1087,14 +1093,11 @@ export const OrderDetailPanel = ({
return statusOptions.map((statusOption) => {
const isSelected = pendingStatus?.value === statusOption.value;
- const isDeliveredBtn = statusOption.value === "delivered";
- const deliveryBlocked = isDeliveredBtn && shipmentState && !shipmentState.canMarkDelivered;
return (
{
if (statusOption.value === "problem") {
setProblemReason("selecting");
@@ -1104,11 +1107,6 @@ export const OrderDetailPanel = ({
}}
>
{statusOption.label}
- {isDeliveredBtn && shipmentState && !shipmentState.canMarkDelivered ? (
-
- ({shipmentState.shipped}/{shipmentState.total})
-
- ) : null}
);
});
@@ -1120,7 +1118,6 @@ export const OrderDetailPanel = ({
variant="primary"
disabled={isSavingStatusChange}
onClick={() => {
- if (pendingStatus.value === "delivered" && shipmentState && !shipmentState.canMarkDelivered) return;
onChangeDeliveryStatus({
orderGroupId: order.id,
status: pendingStatus.value,
diff --git a/src/pages/ClientDeliveryPage.jsx b/src/pages/ClientDeliveryPage.jsx
index 8816c41..8974e4e 100644
--- a/src/pages/ClientDeliveryPage.jsx
+++ b/src/pages/ClientDeliveryPage.jsx
@@ -378,6 +378,13 @@ export const ClientDeliveryPage = () => {
Статус: {invitation?.deliveryType === "pickup" ? "самовывоз" : "доставка"} уже согласован. При повторном открытии этой ссылки будет показан тот же выбор.
+ {(invitation?.pickupCode || invitation?.pickup_code) ? (
+
+
Код выдачи
+
{invitation.pickupCode || invitation.pickup_code}
+
Покажите этот код при получении заказа
+
+ ) : null}
) : null}
diff --git a/src/services/supabase/orderGroupRepository.js b/src/services/supabase/orderGroupRepository.js
index bf5f36e..c929fb7 100644
--- a/src/services/supabase/orderGroupRepository.js
+++ b/src/services/supabase/orderGroupRepository.js
@@ -223,6 +223,7 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
driverShipmentData: row.driver_shipment_data || null,
hasDeliveryProblem: row.has_delivery_problem || false,
deliveryProblemNote: row.delivery_problem_note || null,
+ pickupCode: row.pickup_code || null,
syncedTo1cAt: row.synced_to_1c_at || null,
deliveryHalfDay: getOrderGroupDeliveryHalfDay({
deliveryHalfDay: rawDeliveryHalfDay,
@@ -264,7 +265,7 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
};
};
-const ORDER_GROUP_SELECT_FIELDS = `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, customer_address, delivery_date_source, manual_confirmation_at, paid_storage_at, assigned_driver_id, assigned_driver:users!order_groups_assigned_driver_id_fkey(id, name), driver_shipment_data, delivery_type, pickup_date, pickup_time_slot, has_delivery_problem, delivery_problem_note, synced_to_1c_at`;
+const ORDER_GROUP_SELECT_FIELDS = `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, customer_address, delivery_date_source, manual_confirmation_at, paid_storage_at, assigned_driver_id, assigned_driver:users!order_groups_assigned_driver_id_fkey(id, name), driver_shipment_data, delivery_type, pickup_date, pickup_time_slot, has_delivery_problem, delivery_problem_note, pickup_code, synced_to_1c_at`;
export const updateOrderGroupDeliveryChoice = async ({
orderGroupId,
@@ -292,6 +293,16 @@ export const updateOrderGroupDeliveryChoice = async ({
updatePayload.pickup_time_slot = pickupTimeSlot || null;
// Pickup orders don't need a driver — clear assignment
updatePayload.assigned_driver_id = null;
+ // Generate pickup code if not already set
+ const { data: existing } = await client
+ .from("order_groups")
+ .select("pickup_code")
+ .eq("id", orderGroupId)
+ .single();
+ if (!existing?.pickup_code) {
+ const code = Math.random().toString(36).substring(2, 8).toUpperCase();
+ updatePayload.pickup_code = code;
+ }
} else {
updatePayload.pickup_date = null;
updatePayload.pickup_time_slot = null;
@@ -393,22 +404,14 @@ export const assignDriverToOrderGroup = async ({
export const saveShipmentData = async ({ orderGroupId, shipmentData }) => {
return safeSupabaseCall(async () => {
const client = requireSupabase();
- const unshipped = shipmentData.filter((i) => !i.shipped);
- const allShipped = unshipped.length === 0 && shipmentData.length > 0;
- const unshippedWithoutComment = unshipped.filter((i) => !i.comment?.trim()).length;
- const canMarkDelivered = allShipped || unshippedWithoutComment === 0;
- const hasProblem = unshipped.length > 0;
+ const hasAnyShipped = shipmentData.some((i) => i.shipped);
+ const hasProblem = shipmentData.some((i) => !i.shipped);
const problemNote = hasProblem
- ? unshipped.map((i) => `${i.name}${i.quantity ? ` (${i.quantity}${i.unit ? ` ${i.unit}` : ""})` : ""}${i.comment ? ` — ${i.comment}` : ""}`).join("; ")
+ ? shipmentData.filter((i) => !i.shipped).map((i) => `${i.name}${i.quantity ? ` (${i.quantity}${i.unit ? ` ${i.unit}` : ""})` : ""}${i.comment ? ` — ${i.comment}` : ""}`).join("; ")
: null;
- // Auto-update delivery status based on shipment
- let newDeliveryStatus = undefined;
- if (canMarkDelivered) {
- newDeliveryStatus = "delivered";
- } else if (hasProblem) {
- newDeliveryStatus = "problem";
- }
+ // Any shipment data saved = delivered status. Problems go into has_delivery_problem/delivery_problem_note columns.
+ const newDeliveryStatus = hasAnyShipped ? "delivered" : undefined;
const updatePayload = {
driver_shipment_data: shipmentData,
diff --git a/supabase/functions/confirm-delivery-choice/index.ts b/supabase/functions/confirm-delivery-choice/index.ts
index a9d1945..9433766 100644
--- a/supabase/functions/confirm-delivery-choice/index.ts
+++ b/supabase/functions/confirm-delivery-choice/index.ts
@@ -210,6 +210,16 @@ Deno.serve(async (request) => {
groupUpdateData.pickup_time_slot = body.pickupTimeSlot || requestedSlot.deliveryTime || null;
// Pickup orders don't need a driver — clear assignment
groupUpdateData.assigned_driver_id = null;
+ // Generate pickup code if not already set
+ const { data: existingGroup } = await supabase
+ .from("order_groups")
+ .select("pickup_code")
+ .eq("id", invitation.order_group_id)
+ .single();
+ if (!existingGroup?.pickup_code) {
+ const code = Math.random().toString(36).substring(2, 8).toUpperCase();
+ groupUpdateData.pickup_code = code;
+ }
}
const { error: groupUpdateError } = await supabase
@@ -258,6 +268,7 @@ Deno.serve(async (request) => {
ok: true,
orderGroupId: invitation.order_group_id,
deliveryStatus: effectiveDeliveryStatus,
+ pickupCode: groupUpdateData.pickup_code || null,
},
200,
corsHeaders,
diff --git a/supabase/functions/update-order-group-delivery-choice/index.ts b/supabase/functions/update-order-group-delivery-choice/index.ts
index 4ace189..5671f38 100644
--- a/supabase/functions/update-order-group-delivery-choice/index.ts
+++ b/supabase/functions/update-order-group-delivery-choice/index.ts
@@ -152,7 +152,7 @@ Deno.serve(async (request) => {
const { data: currentGroup, error: currentGroupError } = await supabase
.from("order_groups")
- .select("id, delivery_status, delivery_invitation_id")
+ .select("id, delivery_status, delivery_invitation_id, pickup_code")
.eq("id", orderGroupId)
.single();
@@ -175,6 +175,11 @@ Deno.serve(async (request) => {
updateData.pickup_date = body.pickupDate || deliveryDate || null;
updateData.pickup_time_slot = body.pickupTimeSlot || deliveryTime || null;
updateData.assigned_driver_id = null;
+ // Generate pickup code if not already set
+ if (!currentGroup.pickup_code) {
+ const code = Math.random().toString(36).substring(2, 8).toUpperCase();
+ updateData.pickup_code = code;
+ }
} else {
updateData.pickup_date = null;
updateData.pickup_time_slot = null;