From 80260c8a34c83bcfd9d14c298c485af7d9c2463a Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Tue, 25 Nov 2025 19:57:32 +0300 Subject: [PATCH] Fix: Restore delivery address and order items data on page reload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлены две критические проблемы с автосохранением и восстановлением данных при перезагрузке страницы редактирования заказа: 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 --- myproject/orders/forms.py | 12 ++++ myproject/orders/services/draft_service.py | 74 ++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/myproject/orders/forms.py b/myproject/orders/forms.py index 226f16e..272cd31 100644 --- a/myproject/orders/forms.py +++ b/myproject/orders/forms.py @@ -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): """ Сохраняет форму с учетом автоматического/ручного расчета стоимости доставки. diff --git a/myproject/orders/services/draft_service.py b/myproject/orders/services/draft_service.py index 81266d3..e04953a 100644 --- a/myproject/orders/services/draft_service.py +++ b/myproject/orders/services/draft_service.py @@ -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()