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:
@@ -181,6 +181,18 @@ class OrderForm(forms.ModelForm):
|
||||
order__in=customer_orders
|
||||
).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):
|
||||
"""
|
||||
Сохраняет форму с учетом автоматического/ручного расчета стоимости доставки.
|
||||
|
||||
@@ -208,6 +208,80 @@ class DraftOrderService:
|
||||
|
||||
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.last_autosave_at = timezone.now()
|
||||
order.save()
|
||||
|
||||
Reference in New Issue
Block a user