refactor(orders): relax delivery address and date requirements for non-draft orders

- Updated order creation and update logic to allow saving orders without a delivery address or date, regardless of order status.
- Removed strict validation for delivery fields in the Delivery model, enabling more flexible order handling.
- Adjusted order form to reflect changes in required fields for delivery information.
This commit is contained in:
2026-01-27 14:19:33 +03:00
parent 2aed6f60e5
commit c80e2a5eca
3 changed files with 47 additions and 91 deletions

View File

@@ -232,7 +232,8 @@ def order_create(request):
address.save()
# Создаем или обновляем Delivery
# Для черновиков создаем Delivery без обязательных проверок, чтобы сохранить адрес
# Ранее для не-черновиков адрес курьерской доставки был обязателен.
# Теперь разрешаем сохранять заказ в любом статусе без адреса.
if is_draft:
# Для черновиков создаем Delivery, если есть хотя бы адрес или данные доставки
if address or delivery_type or pickup_warehouse or delivery_date:
@@ -249,34 +250,23 @@ def order_create(request):
}
)
else:
# Для не-черновиков проверяем обязательные поля
if not delivery_type or not delivery_date:
raise ValidationError('Необходимо указать способ доставки и дату доставки')
if delivery_type == Delivery.DELIVERY_TYPE_COURIER:
# Для курьерской доставки нужен адрес
if not address:
raise ValidationError('Для курьерской доставки необходимо указать адрес')
elif delivery_type == Delivery.DELIVERY_TYPE_PICKUP:
# Для самовывоза нужен склад
if not pickup_warehouse:
raise ValidationError('Для самовывоза необходимо выбрать склад')
# Создаем Delivery
delivery = Delivery.objects.create(
order=order,
delivery_type=delivery_type,
delivery_date=delivery_date,
time_from=time_from,
time_to=time_to,
address=address,
pickup_warehouse=pickup_warehouse,
cost=delivery_cost if delivery_cost else Decimal('0')
)
# Пересчитываем стоимость доставки если она не установлена вручную
if not delivery.cost or delivery.cost <= 0:
order.reset_delivery_cost()
# Для не-черновиков больше не требуем обязательного адреса.
# Если пользователь вообще не указал тип доставки и дату, просто не создаём Delivery.
if address or delivery_type or pickup_warehouse or delivery_date:
delivery = Delivery.objects.create(
order=order,
delivery_type=delivery_type or Delivery.DELIVERY_TYPE_COURIER,
delivery_date=delivery_date,
time_from=time_from,
time_to=time_to,
address=address,
pickup_warehouse=pickup_warehouse,
cost=delivery_cost if delivery_cost else Decimal('0')
)
# Пересчитываем стоимость доставки если она не установлена вручную
if not delivery.cost or delivery.cost <= 0:
order.reset_delivery_cost()
# Пересчитываем итоговую стоимость
order.calculate_total()
@@ -465,7 +455,8 @@ def order_update(request, order_number):
address.save()
# Создаем или обновляем Delivery
# Для черновиков создаем Delivery без обязательных проверок, чтобы сохранить адрес
# Ранее для не-черновиков адрес курьерской доставки был обязателен.
# Теперь разрешаем сохранять заказ в любом статусе без адреса.
if is_draft:
# Для черновиков создаем Delivery, если есть хотя бы адрес или данные доставки
if address or delivery_type or pickup_warehouse or delivery_date:
@@ -481,39 +472,29 @@ def order_update(request, order_number):
'cost': delivery_cost if delivery_cost else Decimal('0')
}
)
elif hasattr(order, 'delivery'):
# Если все данные доставки очищены, удаляем существующую Delivery
order.delivery.delete()
else:
# Для не-черновиков проверяем обязательные поля
if not delivery_type or not delivery_date:
raise ValidationError('Необходимо указать способ доставки и дату доставки')
if delivery_type == Delivery.DELIVERY_TYPE_COURIER:
# Для курьерской доставки нужен адрес
if not address:
raise ValidationError('Для курьерской доставки необходимо указать адрес')
elif delivery_type == Delivery.DELIVERY_TYPE_PICKUP:
# Для самовывоза нужен склад
if not pickup_warehouse:
raise ValidationError('Для самовывоза необходимо выбрать склад')
# Создаем или обновляем Delivery
delivery, created = Delivery.objects.update_or_create(
order=order,
defaults={
'delivery_type': delivery_type,
'delivery_date': delivery_date,
'time_from': time_from,
'time_to': time_to,
'address': address,
'pickup_warehouse': pickup_warehouse,
'cost': delivery_cost if delivery_cost else Decimal('0')
}
)
# Для не-черновиков больше не требуем обязательного адреса.
# Если пользователь вообще не указал данные доставки, удаляем Delivery (если она была).
if not (address or delivery_type or pickup_warehouse or delivery_date):
if hasattr(order, 'delivery'):
order.delivery.delete()
else:
# Создаем или обновляем Delivery с теми данными, что есть.
delivery, created = Delivery.objects.update_or_create(
order=order,
defaults={
'delivery_type': delivery_type or Delivery.DELIVERY_TYPE_COURIER,
'delivery_date': delivery_date,
'time_from': time_from,
'time_to': time_to,
'address': address,
'pickup_warehouse': pickup_warehouse,
'cost': delivery_cost if delivery_cost else Decimal('0')
}
)
# Пересчитываем итоговую стоимость
order.calculate_total()
order.update_payment_status()