Добавлен автоматический возврат витринных экземпляров на витрину при откате заказа
Проблема: При отмене заказа (completed → cancelled) резервы корректно возвращались в статус 'reserved', но ShowcaseItem оставались в статусе 'sold'. Из-за этого витринные букеты не отображались в POS после отмены заказа, хотя физически должны были вернуться на витрину. Решение: В существующий сигнал rollback_sale_on_status_change добавлена логика возврата витринных экземпляров на витрину: 1. После отката Sale и Reservation находим все ShowcaseItem, проданные в рамках отменяемого заказа (sold_order_item__order=instance) 2. Для каждого экземпляра: - Меняем status: sold → available - Очищаем sold_order_item = None - Очищаем sold_at = None - НЕ трогаем showcase и product_kit (букет остаётся на той же витрине) 3. Логируем количество возвращённых экземпляров Преимущества: - Элегантно: вся логика отката в одном месте (сигнал) - Транзакционно: откат Sale, Reservation и ShowcaseItem в одной транзакции - Универсально: работает для POS и обычных заказов - Без костылей: используем существующую архитектуру сигналов Теперь при отмене заказа витринный букет автоматически возвращается на витрину и снова виден в POS - как в реальной жизни.
This commit is contained in:
@@ -474,6 +474,34 @@ def rollback_sale_on_status_change(sender, instance, created, **kwargs):
|
|||||||
f"⚠ Для заказа {instance.order_number} нет резервов в статусе 'converted_to_sale'"
|
f"⚠ Для заказа {instance.order_number} нет резервов в статусе 'converted_to_sale'"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# === Возвращаем витринные экземпляры обратно на витрину ===
|
||||||
|
from inventory.models import ShowcaseItem
|
||||||
|
|
||||||
|
# Находим все ShowcaseItem, проданные в рамках этого заказа
|
||||||
|
showcase_items = ShowcaseItem.objects.filter(
|
||||||
|
sold_order_item__order=instance,
|
||||||
|
status='sold'
|
||||||
|
)
|
||||||
|
|
||||||
|
showcase_items_count = showcase_items.count()
|
||||||
|
|
||||||
|
if showcase_items_count > 0:
|
||||||
|
logger.info(
|
||||||
|
f"🔄 Возвращаем {showcase_items_count} витринных экземпляров обратно на витрину..."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Возвращаем каждый экземпляр на витрину
|
||||||
|
for item in showcase_items:
|
||||||
|
item.status = 'available'
|
||||||
|
item.sold_order_item = None
|
||||||
|
item.sold_at = None
|
||||||
|
# showcase и product_kit не трогаем - букет остаётся на той же витрине
|
||||||
|
item.save(update_fields=['status', 'sold_order_item', 'sold_at', 'updated_at'])
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"✓ {showcase_items_count} витринных экземпляров вернулись на витрину: sold → available"
|
||||||
|
)
|
||||||
|
|
||||||
# === Обновляем is_returned ===
|
# === Обновляем is_returned ===
|
||||||
if is_cancellation:
|
if is_cancellation:
|
||||||
# Сценарий Б: устанавливаем is_returned = True
|
# Сценарий Б: устанавливаем is_returned = True
|
||||||
|
|||||||
Reference in New Issue
Block a user