From 8cc8cd133999bc9e23563e65f6d575df6a8296ab Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Tue, 11 Nov 2025 16:59:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=B5=D1=80=D1=81=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=D0=B0=20=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=20=D0=B0=D0=B2=D1=82=D0=BE=D1=81=D0=BE?= =?UTF-8?q?=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проблема: После переключения между "С доставкой" и "Самовывоз" и автосохранения, при перезагрузке страницы всегда отображался "Самовывоз", независимо от фактически сохраненного значения. Изменения: 1. **orders/templates/orders/order_form.html**: - Переписана инициализация управления типом доставки - Код вынесен из jQuery document.ready в отдельный DOMContentLoaded обработчик - Разделена логика синхронизации: * syncDeliveryTypeFromRadio() - для обработки кликов пользователя * syncUIFromCheckbox() - для инициализации UI из значения чекбокса - Исправлен рендеринг скрытого чекбокса is_delivery с явным атрибутом checked - Удалена лишняя закрывающая скобка, вызывавшая JS ошибку - Удален дублирующийся обработчик select2:opening для выбора клиента 2. **orders/services/draft_service.py**: - Добавлена явная конвертация boolean полей (is_delivery, customer_is_recipient, is_anonymous) - Обработка различных типов данных (bool, string, None) в единый boolean - Добавлено логирование для отладки is_delivery (временно) Результат: Тип доставки теперь корректно сохраняется через автосохранение и восстанавливается при перезагрузке страницы. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .claude/settings.local.json | 3 +- myproject/orders/services/draft_service.py | 21 ++++++- .../orders/templates/orders/order_form.html | 60 +++++++++++++++---- 3 files changed, 70 insertions(+), 14 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index be97d13..e4b001b 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -3,7 +3,8 @@ "allow": [ "Bash(dir /b /s settings.py)", "Bash(git add:*)", - "Bash(..venvScriptspython.exe manage.py check)" + "Bash(..venvScriptspython.exe manage.py check)", + "Bash(python:*)" ], "deny": [], "ask": [] diff --git a/myproject/orders/services/draft_service.py b/myproject/orders/services/draft_service.py index a5d972a..7e60dd3 100644 --- a/myproject/orders/services/draft_service.py +++ b/myproject/orders/services/draft_service.py @@ -143,8 +143,27 @@ class DraftOrderService: if field in data: value = data[field] + # Конвертируем boolean поля + if field in ['is_delivery', 'customer_is_recipient', 'is_anonymous']: + # Явно конвертируем в bool, обрабатывая различные типы данных + original_value = value + if isinstance(value, bool): + value = value + elif isinstance(value, str): + value = value.lower() in ('true', '1', 'yes', 'on') + elif value is None: + value = False + else: + value = bool(value) + + # Логируем для отладки + if field == 'is_delivery': + import logging + logger = logging.getLogger(__name__) + logger.info(f"[AUTOSAVE] is_delivery: original={original_value} (type={type(original_value)}), converted={value}") + # Конвертируем числовые поля в Decimal - if field in ['delivery_cost', 'discount_amount']: + elif field in ['delivery_cost', 'discount_amount']: if value == '' or value is None: value = None else: diff --git a/myproject/orders/templates/orders/order_form.html b/myproject/orders/templates/orders/order_form.html index cef2de1..881e166 100644 --- a/myproject/orders/templates/orders/order_form.html +++ b/myproject/orders/templates/orders/order_form.html @@ -188,18 +188,24 @@
- +
+ +
- + - + @@ -842,19 +848,29 @@ initCustomerSelect2(); // Инициализация Select2 для остальных полей (после jQuery загружен) if (typeof $ !== 'undefined') { $(document).ready(function() { + console.log('[INIT] jQuery document ready triggered'); + $('.select2:not(.select2-order-item)').select2({ theme: 'bootstrap-5', width: '100%', language: 'ru' }); + }); +} + +// === УПРАВЛЕНИЕ ТИПОМ ДОСТАВКИ (КНОПКИ) === +// ВАЖНО: Этот код должен быть ВНЕ jQuery document.ready, +// чтобы выполниться после полной загрузки DOM +document.addEventListener('DOMContentLoaded', function() { + console.log('[DELIVERY TYPE] DOM loaded, initializing...'); - // === УПРАВЛЕНИЕ ТИПОМ ДОСТАВКИ (КНОПКИ) === const deliveryTypeRadios = document.querySelectorAll('input[name="delivery-type"]'); const isDeliveryCheckbox = document.getElementById('{{ form.is_delivery.id_for_label }}'); const deliveryModeFields = document.getElementById('delivery-mode-fields'); const pickupFields = document.getElementById('pickup-fields'); - function syncDeliveryType() { + function syncDeliveryTypeFromRadio() { + // Синхронизирует чекбокс И UI с выбранной радиокнопкой const selectedType = document.querySelector('input[name="delivery-type"]:checked').value; if (selectedType === 'delivery') { @@ -872,14 +888,33 @@ if (typeof $ !== 'undefined') { } } - // Обработчики для кнопок + function syncUIFromCheckbox() { + // Синхронизирует ТОЛЬКО UI (не трогает чекбокс) с текущим значением чекбокса + if (isDeliveryCheckbox.checked) { + // Синхронизируем радиокнопки + document.getElementById('delivery-type-delivery').checked = true; + // Синхронизируем видимость секций + deliveryModeFields.style.display = 'block'; + pickupFields.style.display = 'none'; + console.log('[DELIVERY TYPE] UI synced: showing delivery fields'); + } else { + // Синхронизируем радиокнопки + document.getElementById('delivery-type-pickup').checked = true; + // Синхронизируем видимость секций + deliveryModeFields.style.display = 'none'; + pickupFields.style.display = 'block'; + console.log('[DELIVERY TYPE] UI synced: showing pickup fields'); + } + } + + // Обработчики для кнопок - при клике синхронизируем чекбокс с радиокнопками deliveryTypeRadios.forEach(radio => { - radio.addEventListener('change', syncDeliveryType); + radio.addEventListener('change', syncDeliveryTypeFromRadio); }); - // Инициализация при загрузке - console.log('[DELIVERY TYPE] Initializing delivery type buttons'); - syncDeliveryType(); + // Инициализация при загрузке - синхронизируем UI с текущим значением чекбокса (из формы) + console.log('[DELIVERY TYPE] Initializing delivery type, checkbox value:', isDeliveryCheckbox.checked); + syncUIFromCheckbox(); // Показ/скрытие полей получателя const customerIsRecipientCheckbox = document.getElementById('{{ form.customer_is_recipient.id_for_label }}'); @@ -1353,8 +1388,9 @@ if (typeof $ !== 'undefined') { alert('Произошла ошибка при создании комплекта: ' + error.message); }); }); - }); -} + +// Закрытие обработчика DOMContentLoaded для управления типом доставки и остальных функций +});