Исправлен баг: ShowcaseItem теперь возвращается в reserved при переходе из отрицательного статуса в нейтральный
Проблема: - При отмене заказа (cancelled) ShowcaseItem переходил в 'available' - При возврате из cancelled в нейтральный статус (draft/pending) резервы привязывались обратно - НО ShowcaseItem оставался в 'available', что позволяло добавить букет в другой заказ - Итог: один физический букет в двух заказах Решение: - inventory/signals.py: в сигнале reserve_stock_on_uncancellation добавлена логика - При переходе cancelled → нейтральный: * Находим ShowcaseItem витринных комплектов в статусе 'available' * Вызываем return_to_reserved(order_item) для каждого экземпляра * ShowcaseItem: available → reserved (привязан к OrderItem) - Теперь букет корректно возвращается в резерв и недоступен на витрине Lifecycle при откате отмены: 1. cancelled: ShowcaseItem = available, резервы отвязаны 2. cancelled → draft/pending: ShowcaseItem = reserved, резервы привязаны 3. Букет остаётся за заказом, защищён от двойной продажи
This commit is contained in:
@@ -1191,6 +1191,41 @@ def reserve_stock_on_uncancellation(sender, instance, created, **kwargs):
|
|||||||
f"✅ Обработано {showcase_items_count} витринных комплектов"
|
f"✅ Обработано {showcase_items_count} витринных комплектов"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# === Возвращаем ShowcaseItem из available обратно в reserved ===
|
||||||
|
# При отмене (cancelled) ShowcaseItem переходит в 'available'.
|
||||||
|
# При возврате к нейтральному статусу нужно вернуть в 'reserved'.
|
||||||
|
from inventory.models import ShowcaseItem
|
||||||
|
|
||||||
|
# Находим все ShowcaseItem которые были освобождены при отмене
|
||||||
|
# (у них sold_order_item сброшен в return_to_available, нужно найти через резервы)
|
||||||
|
for order_item in showcase_order_items:
|
||||||
|
kit = order_item.product_kit
|
||||||
|
|
||||||
|
# Находим ShowcaseItem этого комплекта в статусе 'available'
|
||||||
|
# Их sold_order_item = None, поэтому ищем через product_kit
|
||||||
|
available_items = ShowcaseItem.objects.filter(
|
||||||
|
product_kit=kit,
|
||||||
|
status='available',
|
||||||
|
sold_order_item__isnull=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if available_items.exists():
|
||||||
|
logger.info(
|
||||||
|
f" 🔄 Найдено {available_items.count()} ShowcaseItem комплекта '{kit.name}' в статусе 'available'. "
|
||||||
|
f"Возвращаем в reserved..."
|
||||||
|
)
|
||||||
|
|
||||||
|
for item in available_items:
|
||||||
|
try:
|
||||||
|
item.return_to_reserved(order_item)
|
||||||
|
logger.info(
|
||||||
|
f" ✅ ShowcaseItem #{item.id}: available → reserved (привязан к OrderItem #{order_item.id})"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
f" ❌ Ошибка возврата ShowcaseItem #{item.id} в reserved: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@receiver(pre_delete, sender=Order)
|
@receiver(pre_delete, sender=Order)
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
|
|||||||
Reference in New Issue
Block a user