Расширена валидация для возвращённых заказов: запрет любых статусов кроме отрицательных
Проблема: Для заказа с is_returned=True без резервов (товар продан в другом заказе) можно было установить промежуточные статусы (В доставке, Черновик и т.п.), что не имеет смысла, т.к. физически продавать уже нечего. Решение: Валидация теперь проверяет ДО проверки is_positive_end: - Если is_returned=True И резервов нет И статус НЕ отрицательный → запрещаем ЛЮБОЕ изменение статуса - Разрешены только статусы с is_negative_end=True (отменён и т.п.) Улучшено сообщение об ошибке: - Убраны длинные объяснения - Короткая структура с переносами строк - Чёткое указание: «товары проданы в другом заказе» - Действие: «создайте новый заказ» Теперь возвращённый заказ без резервов навсегда остаётся в статусе отрицательного исхода — как и должно быть в реальности.
This commit is contained in:
@@ -133,32 +133,34 @@ def create_sale_on_order_completion(sender, instance, created, **kwargs):
|
|||||||
if not instance.status:
|
if not instance.status:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Проверяем: это положительный финальный статус?
|
# === ВАЛИДАЦИЯ: Запрет изменения статуса для возвращённых заказов без резервов ===
|
||||||
is_positive_end = instance.status.is_positive_end
|
# Если заказ был возвращён (is_returned=True) и резервов нет, можно использовать
|
||||||
|
# только статусы отрицательного исхода (отменён и т.п.)
|
||||||
if not is_positive_end:
|
|
||||||
return # Только для положительных финальных статусов (completed и т.п.)
|
|
||||||
|
|
||||||
# === ВАЛИДАЦИЯ: Запрет повторного completed для возвращённых заказов без резервов ===
|
|
||||||
if instance.is_returned:
|
if instance.is_returned:
|
||||||
# Заказ уже был продан и возвращён — проверяем наличие резервов
|
|
||||||
has_reservations = Reservation.objects.filter(
|
has_reservations = Reservation.objects.filter(
|
||||||
order_item__order=instance
|
order_item__order=instance
|
||||||
).exists()
|
).exists()
|
||||||
|
|
||||||
if not has_reservations:
|
if not has_reservations:
|
||||||
# Резервов нет — товар уже ушёл в другой заказ или был освобождён
|
# Резервов нет — разрешены только отрицательные статусы
|
||||||
|
if not instance.status.is_negative_end:
|
||||||
logger.error(
|
logger.error(
|
||||||
f"❌ Заказ {instance.order_number} имеет флаг is_returned=True и не имеет резервов. "
|
f"❌ Заказ {instance.order_number}: is_returned=True, резервов нет. "
|
||||||
f"Невозможно перевести в статус '{instance.status.name}'."
|
f"Попытка установить '{instance.status.name}' запрещена."
|
||||||
)
|
)
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
f"Невозможно установить статус '{instance.status.name}' для заказа {instance.order_number}. "
|
f"Невозможно изменить статус заказа {instance.order_number}.\n\n"
|
||||||
f"Этот заказ уже был отменён после продажи, резервы отсутствуют. "
|
f"Этот заказ был отменён после продажи, товары проданы в другом заказе.\n"
|
||||||
f"Товары могли быть проданы в другом заказе. "
|
f"Разрешены только статусы отрицательного исхода (отменён).\n\n"
|
||||||
f"Пожалуйста, оставьте статус отрицательного исхода (отменён) или создайте новый заказ."
|
f"Для новой продажи создайте новый заказ."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Проверяем: это положительный финальный статус?
|
||||||
|
is_positive_end = instance.status.is_positive_end
|
||||||
|
|
||||||
|
if not is_positive_end:
|
||||||
|
return # Только для положительных финальных статусов (completed и т.п.)
|
||||||
|
|
||||||
# Защита от повторного списания: проверяем, не созданы ли уже Sale для этого заказа
|
# Защита от повторного списания: проверяем, не созданы ли уже Sale для этого заказа
|
||||||
if Sale.objects.filter(order=instance).exists():
|
if Sale.objects.filter(order=instance).exists():
|
||||||
# Продажи уже созданы — просто обновляем флаг is_returned и выходим
|
# Продажи уже созданы — просто обновляем флаг is_returned и выходим
|
||||||
|
|||||||
Reference in New Issue
Block a user