Создано из обмена
diff --git a/src/services/orderGroupViews.js b/src/services/orderGroupViews.js
index e00acb4..65d7a39 100644
--- a/src/services/orderGroupViews.js
+++ b/src/services/orderGroupViews.js
@@ -11,6 +11,7 @@ export const DELIVERY_GROUP_STATUS_LABELS = {
on_route: "В пути",
delivered: "Доставлено",
problem: "Проблема",
+ paid_storage: "Платное хранение",
cancelled: "Отменено",
};
@@ -168,7 +169,7 @@ export const isOrderGroupVisibleToDriver = (group) => {
return DRIVER_VISIBLE_DELIVERY_STATUSES.includes(deliveryStatus);
};
-const parseGroupDate = (value) => {
+export const parseGroupDate = (value) => {
const normalized = normalizeDate(value);
if (!normalized) {
@@ -299,6 +300,7 @@ export const ORDER_GROUP_DISPLAY_STATUS_OPTIONS = [
{ value: "delivery:on_route", label: DELIVERY_GROUP_STATUS_LABELS.on_route },
{ value: "delivery:delivered", label: DELIVERY_GROUP_STATUS_LABELS.delivered },
{ value: "delivery:problem", label: DELIVERY_GROUP_STATUS_LABELS.problem },
+ { value: "delivery:paid_storage", label: DELIVERY_GROUP_STATUS_LABELS.paid_storage },
{ value: "delivery:cancelled", label: DELIVERY_GROUP_STATUS_LABELS.cancelled },
];
@@ -321,6 +323,8 @@ export const getOrderGroupDeliveryStatusTone = (status) => {
return "accent";
case "delivered":
return "accent";
+ case "paid_storage":
+ return "warning";
case "problem":
return "danger";
case "cancelled":
diff --git a/src/services/supabase/orderGroupRepository.js b/src/services/supabase/orderGroupRepository.js
index e1268c2..847a2a3 100644
--- a/src/services/supabase/orderGroupRepository.js
+++ b/src/services/supabase/orderGroupRepository.js
@@ -117,6 +117,7 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
firstSmsSentAt: row.first_sms_sent_at || null,
secondSmsSentAt: row.second_sms_sent_at || null,
manualConfirmationAt: row.manual_confirmation_at || null,
+ paidStorageAt: row.paid_storage_at || null,
notificationStatus: normalizeText(row.notification_status),
createdFromExchangeAt: row.created_from_exchange_at || null,
sourceKey: row.source_key || null,
@@ -199,7 +200,7 @@ export const updateOrderGroupDeliveryChoice = async ({
const { data, error } = await client
.from("order_groups")
- .select("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, assigned_driver_id, assigned_driver:users!order_groups_assigned_driver_id_fkey(id, name)")
+ .select("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)")
.eq("id", orderGroupId)
.single();
@@ -282,7 +283,7 @@ export const fetchOrderGroups = async () => {
const client = requireSupabase();
const { data, error } = await client
.from("order_groups")
- .select("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, assigned_driver_id, assigned_driver:users!order_groups_assigned_driver_id_fkey(id, name)")
+ .select("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)")
.order("updated_at", { ascending: false });
if (error) {
diff --git a/src/services/supabase/orderGroupRepository.test.js b/src/services/supabase/orderGroupRepository.test.js
index 6e83e24..a2d796a 100644
--- a/src/services/supabase/orderGroupRepository.test.js
+++ b/src/services/supabase/orderGroupRepository.test.js
@@ -166,7 +166,7 @@ describe("updateOrderGroupDeliveryChoice", () => {
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, assigned_driver_id, assigned_driver:users!order_groups_assigned_driver_id_fkey(id, name)");
+ 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(singleMock).toHaveBeenCalledTimes(1);
});
});
diff --git a/supabase/paid-storage-status.sql b/supabase/paid-storage-status.sql
new file mode 100644
index 0000000..302dfd6
--- /dev/null
+++ b/supabase/paid-storage-status.sql
@@ -0,0 +1,56 @@
+-- Patch: Add paid_storage status support for order_groups
+
+-- 1. Add paid_storage_at column to order_groups if not exists
+alter table public.order_groups add column if not exists paid_storage_at timestamptz;
+
+-- 2. Update update_delivery_status to allow paid_storage without assigned driver
+create or replace function public.update_delivery_status(
+ p_order_group_id uuid,
+ p_status text
+)
+returns boolean
+language plpgsql
+security definer
+set search_path = public
+as $$
+declare
+ v_assigned_driver_id uuid;
+ v_current_status text;
+begin
+ select assigned_driver_id, delivery_status
+ into v_assigned_driver_id, v_current_status
+ from public.order_groups
+ where id = p_order_group_id;
+
+ -- Allow paid_storage status for any authenticated user with proper role
+ -- (checked by RLS policy)
+ if p_status = 'paid_storage' then
+ update public.order_groups
+ set delivery_status = p_status,
+ paid_storage_at = timezone('utc', now()),
+ updated_at = timezone('utc', now())
+ where id = p_order_group_id;
+ return true;
+ end if;
+
+ if v_assigned_driver_id is null then
+ raise exception 'Группа не назначена водителю';
+ end if;
+
+ if v_assigned_driver_id != auth.uid() then
+ raise exception 'Вы не назначены на эту доставку';
+ end if;
+
+ update public.order_groups
+ set delivery_status = p_status,
+ updated_at = timezone('utc', now())
+ where id = p_order_group_id;
+
+ return true;
+end;
+$$;
+
+-- 3. Ensure proper grants
+revoke execute on function public.update_delivery_status(uuid, text) from anon;
+grant execute on function public.update_delivery_status(uuid, text) to authenticated;
+