Fix: Restore delivery address and order items data on page reload

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

1. ПРОБЛЕМА: Адрес доставки не восстанавливался после перезагрузки
   РЕШЕНИЕ (forms.py):
   - Добавлена инициализация полей адреса в OrderForm.__init__()
   - Поля заполняются из order.delivery_address при редактировании
   - Инициализируются все поля: улица, дом, квартира, подъезд, этаж, домофон, инструкции

2. ПРОБЛЕМА: Цены и количество товаров не сохранялись через автосохранение
   РЕШЕНИЕ (draft_service.py):
   - Добавлена обработка items в DraftOrderService.update_draft()
   - Автосохранение теперь обновляет/создаёт/удаляет позиции заказа
   - Сохраняются: product/product_kit, quantity, price, is_custom_price
   - Корректно определяется is_custom_price через сравнение с оригинальной ценой

Логика обработки items:
- Существующие позиции обновляются (product, quantity, price)
- Новые позиции создаются
- Лишние позиции удаляются
- Поддержка как товаров (product_id), так и комплектов (product_kit_id)

Теперь при перезагрузке страницы:
 Адрес доставки полностью восстанавливается во всех полях
 Товары сохраняются с правильными ценами и количествами
 Изменённые цены корректно отмечаются бейджем "Изменена"
 Все данные синхронизируются между автосохранением и базой данных

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-25 19:57:32 +03:00
parent a3f5ac4c08
commit 80260c8a34
2 changed files with 86 additions and 0 deletions

View File

@@ -181,6 +181,18 @@ class OrderForm(forms.ModelForm):
order__in=customer_orders order__in=customer_orders
).distinct().order_by('-created_at') ).distinct().order_by('-created_at')
# Инициализируем поля адреса из существующего delivery_address
if self.instance.pk and self.instance.delivery_address:
address = self.instance.delivery_address
self.fields['address_street'].initial = address.street or ''
self.fields['address_building_number'].initial = address.building_number or ''
self.fields['address_apartment_number'].initial = address.apartment_number or ''
self.fields['address_entrance'].initial = address.entrance or ''
self.fields['address_floor'].initial = address.floor or ''
self.fields['address_intercom_code'].initial = address.intercom_code or ''
self.fields['address_delivery_instructions'].initial = address.delivery_instructions or ''
self.fields['address_confirm_with_recipient'].initial = address.confirm_address_with_recipient
def save(self, commit=True): def save(self, commit=True):
""" """
Сохраняет форму с учетом автоматического/ручного расчета стоимости доставки. Сохраняет форму с учетом автоматического/ручного расчета стоимости доставки.

View File

@@ -208,6 +208,80 @@ class DraftOrderService:
setattr(order, field, value) setattr(order, field, value)
# Обрабатываем позиции заказа (items)
if 'items' in data:
# Импортируем модели
from products.models import Product, ProductKit
from ..models import OrderItem
items_data = data['items']
# Получаем существующие позиции
existing_items = list(order.items.all())
# Удаляем все существующие позиции, которых нет в новых данных
items_to_keep_count = len(items_data)
for i, existing_item in enumerate(existing_items):
if i >= items_to_keep_count:
# Удаляем лишние позиции
existing_item.delete()
# Обновляем или создаём позиции
for index, item_data in enumerate(items_data):
product_id = item_data.get('product_id')
product_kit_id = item_data.get('product_kit_id')
quantity = item_data.get('quantity', 1)
price = item_data.get('price', 0)
# Конвертируем в Decimal
try:
quantity = Decimal(str(quantity))
price = Decimal(str(price))
except (ValueError, TypeError, decimal.InvalidOperation):
continue
# Получаем товар или комплект
product = None
product_kit = None
if product_id:
try:
product = Product.objects.get(pk=product_id)
except Product.DoesNotExist:
continue
elif product_kit_id:
try:
product_kit = ProductKit.objects.get(pk=product_kit_id)
except ProductKit.DoesNotExist:
continue
else:
continue
# Определяем, изменилась ли цена
original_price = product.actual_price if product else product_kit.actual_price
is_custom_price = abs(price - original_price) > Decimal('0.01')
# Обновляем существующую позицию или создаём новую
if index < len(existing_items):
# Обновляем существующую
item = existing_items[index]
item.product = product
item.product_kit = product_kit
item.quantity = quantity
item.price = price
item.is_custom_price = is_custom_price
item.save()
else:
# Создаём новую
OrderItem.objects.create(
order=order,
product=product,
product_kit=product_kit,
quantity=quantity,
price=price,
is_custom_price=is_custom_price
)
order.modified_by = user order.modified_by = user
order.last_autosave_at = timezone.now() order.last_autosave_at = timezone.now()
order.save() order.save()