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
|
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):
|
||||||
"""
|
"""
|
||||||
Сохраняет форму с учетом автоматического/ручного расчета стоимости доставки.
|
Сохраняет форму с учетом автоматического/ручного расчета стоимости доставки.
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user