From d65a69e2bb0de36bc5212936e0f7308796e8fa87 Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Mon, 5 Jan 2026 09:45:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=20=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=80=D0=B8=D0=BD=D0=BD=D1=8B=D1=85=20=D1=80=D0=B5=D0=B7?= =?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=BE=D0=B2=20=D0=BF=D1=80=D0=B8=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8=20Sale=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D0=BE=D1=82=D0=BC=D0=B5=D0=BD=D1=91=D0=BD=D0=BD=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проблема: - При переходе cancelled → completed резервы витринных букетов отвязаны от order_item (order_item=None) - В create_sale_on_order_completion поиск резервов по order_item не находит их - Sale не создаются → букет освобождается вместо продажи Решение: - inventory/signals.py: в create_sale_on_order_completion добавлена fallback-логика для витринных комплектов - Если резервы не найдены по order_item=item, проверяем: витринный комплект? - Для витринных: ищем резервы через product_kit + showcase__isnull=False + status='reserved' - Найденные резервы привязываем к order_item перед созданием Sale - Затем создаются Sale и ShowcaseItem корректно переходит в sold Flow теперь работает полностью: 1. cancelled: ShowcaseItem → available, Reservation order_item=None 2. cancelled → completed: - create_sale_on_order_completion находит резервы через product_kit ✅ - Привязывает их к order_item ✅ - Создаёт Sale для компонентов ✅ - Финализирует ShowcaseItem: available → sold ✅ Гарантирует создание Sale даже если порядок срабатывания сигналов не предсказуем. --- myproject/inventory/signals.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/myproject/inventory/signals.py b/myproject/inventory/signals.py index a309016..b729bb9 100644 --- a/myproject/inventory/signals.py +++ b/myproject/inventory/signals.py @@ -365,6 +365,28 @@ def create_sale_on_order_completion(sender, instance, created, **kwargs): product_kit=kit ).exclude(status='converted_to_sale') + # Если резервы не найдены по order_item (например, при переходе из cancelled), + # ищем витринные резервы через product_kit + if not kit_reservations.exists() and kit.is_temporary and kit.showcase: + logger.info( + f"🔄 Витринный комплект '{kit.name}': резервы не найдены по order_item. " + f"Ищем через product_kit..." + ) + + # Ищем резервы для этого комплекта (могут быть без order_item при переходе из cancelled) + kit_reservations = Reservation.objects.filter( + product_kit=kit, + showcase__isnull=False, + status='reserved' + ) + + # Привязываем резервы к order_item перед созданием Sale + if kit_reservations.exists(): + updated_count = kit_reservations.update(order_item=item) + logger.info( + f" ✅ Привязано {updated_count} резервов к OrderItem #{item.id}" + ) + if not kit_reservations.exists(): # Проверяем, может быть витринный комплект уже продан через ShowcaseManager? already_sold = Reservation.objects.filter(