Исправление проблем с сохранением адреса, получателя и даты доставки

- Исправлено: адрес теперь сохраняется для черновиков заказов
- Исправлено: получатель корректно предзаполняется при редактировании заказа
- Исправлено: адрес при редактировании отображается в режиме 'новый' для возможности редактирования
- Исправлено: дата доставки корректно предзаполняется при редактировании заказа
- Исправлено: при редактировании получателя обновляется существующий объект вместо создания нового
- Улучшена логика обработки Delivery для черновиков (создание с опциональными полями)
- Улучшена логика обновления получателя через загрузку заказа из БД с select_related
This commit is contained in:
2025-12-25 00:30:27 +03:00
parent 98470c83af
commit 298d797286
5 changed files with 192 additions and 91 deletions

View File

@@ -303,6 +303,8 @@ class OrderForm(forms.ModelForm):
# Инициализируем поля доставки из существующей Delivery
if self.instance.pk and hasattr(self.instance, 'delivery'):
delivery = self.instance.delivery
# Устанавливаем значения через fields.initial для правильной работы виджетов
self.fields['delivery_type'].initial = delivery.delivery_type
self.fields['delivery_date'].initial = delivery.delivery_date
self.fields['time_from'].initial = delivery.time_from
@@ -310,6 +312,19 @@ class OrderForm(forms.ModelForm):
self.fields['pickup_warehouse'].initial = delivery.pickup_warehouse
self.fields['delivery_cost'].initial = delivery.cost
# Также устанавливаем через self.initial для совместимости
self.initial['delivery_type'] = delivery.delivery_type
self.initial['delivery_date'] = delivery.delivery_date
self.initial['time_from'] = delivery.time_from
self.initial['time_to'] = delivery.time_to
self.initial['pickup_warehouse'] = delivery.pickup_warehouse
self.initial['delivery_cost'] = delivery.cost
# Для DateInput с type='date' нужно установить значение в формате YYYY-MM-DD
if delivery.delivery_date:
# Устанавливаем значение напрямую в виджете
self.fields['delivery_date'].widget.attrs['value'] = delivery.delivery_date.strftime('%Y-%m-%d')
# Если выбран самовывоз, но склад не указан - выбираем склад по умолчанию
if delivery.delivery_type == Delivery.DELIVERY_TYPE_PICKUP and not delivery.pickup_warehouse:
default_warehouse = Warehouse.objects.filter(
@@ -322,38 +337,26 @@ class OrderForm(forms.ModelForm):
# Инициализируем поля адреса, если есть адрес доставки
if delivery.address:
# Проверяем, есть ли этот адрес в истории клиента
# При редактировании всегда используем режим "новый", чтобы можно было редактировать адрес
# Инициализируем queryset для истории адресов (для выбора из истории, если нужно)
if self.instance.customer:
customer_addresses = Address.objects.filter(
deliveries__order__customer=self.instance.customer
).exclude(
deliveries__order=self.instance # Исключаем адрес текущего заказа
).distinct()
if delivery.address in customer_addresses:
# Адрес есть в истории - используем режим "история"
self.fields['address_mode'].initial = 'history'
self.fields['address_from_history'].queryset = customer_addresses
self.fields['address_from_history'].initial = delivery.address.pk
else:
# Адреса нет в истории - используем режим "новый" и заполняем поля
self.fields['address_mode'].initial = 'new'
self.fields['address_street'].initial = delivery.address.street
self.fields['address_building_number'].initial = delivery.address.building_number
self.fields['address_apartment_number'].initial = delivery.address.apartment_number
self.fields['address_entrance'].initial = delivery.address.entrance
self.fields['address_floor'].initial = delivery.address.floor
self.fields['address_intercom_code'].initial = delivery.address.intercom_code
self.fields['address_delivery_instructions'].initial = delivery.address.delivery_instructions
self.fields['address_confirm_with_recipient'].initial = delivery.address.confirm_address_with_recipient
else:
# Нет клиента - просто заполняем поля
self.fields['address_mode'].initial = 'new'
self.fields['address_street'].initial = delivery.address.street
self.fields['address_building_number'].initial = delivery.address.building_number
self.fields['address_apartment_number'].initial = delivery.address.apartment_number
self.fields['address_entrance'].initial = delivery.address.entrance
self.fields['address_floor'].initial = delivery.address.floor
self.fields['address_intercom_code'].initial = delivery.address.intercom_code
self.fields['address_delivery_instructions'].initial = delivery.address.delivery_instructions
self.fields['address_confirm_with_recipient'].initial = delivery.address.confirm_address_with_recipient
self.fields['address_from_history'].queryset = customer_addresses
# Всегда используем режим "новый" для редактирования, чтобы можно было редактировать
self.initial['address_mode'] = 'new'
self.initial['address_street'] = delivery.address.street
self.initial['address_building_number'] = delivery.address.building_number
self.initial['address_apartment_number'] = delivery.address.apartment_number
self.initial['address_entrance'] = delivery.address.entrance
self.initial['address_floor'] = delivery.address.floor
self.initial['address_intercom_code'] = delivery.address.intercom_code
self.initial['address_delivery_instructions'] = delivery.address.delivery_instructions
self.initial['address_confirm_with_recipient'] = delivery.address.confirm_address_with_recipient
def clean(self):
"""Валидация формы заказа, включая обязательные поля доставки"""