Проблема:
- calculate_total() пытался автоматически обрабатывать переплату
- Это приводило к дублированию логики и сложной отладке
- Нарушался принцип единственной ответственности
Решение:
- Удалена автоматическая обработка переплаты из Order.calculate_total()
- Теперь calculate_total() ТОЛЬКО считает сумму - всё
- Переплата обрабатывается ТОЛЬКО в TransactionService при создании платежей/возвратов
- Добавлено предупреждение в UI о переплате с инструкцией
Как работает теперь:
1. При оплате - TransactionService автоматически вызывает add_overpayment()
2. При изменении товаров - calculate_total() только пересчитывает сумму
3. Если появилась переплата - оператор видит предупреждение
4. Оператор вручную создаёт возврат в кошелёк через форму
Преимущества:
- Одно место ответственности за переплаты
- Прозрачность для оператора
- Нет скрытых автоматизмов
- Легко обслуживать и отлаживать
- Стандартный подход для e-commerce
Изменения в UI (order_form.html):
- Добавлен data-code к опциям способов оплаты для идентификации метода кошелька
- ID для селекта способа оплаты (payment-method-select) и поля суммы (payment-amount-input)
- Динамическое ограничение max на поле суммы платежа при выборе кошелька
- Подсказка 'Макс: X руб.' отображается только для оплаты кошельком
- Для внешних методов (карта, наличные) ограничение отсутствует — переплата допустима
Логика JS:
- При выборе метода с code == 'account_balance' устанавливается max = order.amount_due
- Для остальных методов max удаляется — оператор может внести сумму больше остатка
- Переплата по внешним методам корректно зачисляется в кошелёк через WalletService.add_overpayment
Серверная защита (transaction_service.py):
- В TransactionService.create_payment добавлена проверка:
если payment_method.code == 'account_balance' и amount > order.amount_due — ValidationError
- Сообщение: 'Сумма оплаты из кошелька (X руб.) не может превышать остаток к оплате (Y руб.)'
- Защита от обхода UI через API или прямой вызов
Улучшение отображения (order_form.html, order_detail.html):
- Для возврата в кошелёк (transaction_type == 'refund' и code == 'account_balance') показываем 'на баланс счёта' вместо названия метода
- История становится понятнее: '−750,00 руб. Возврат 29.11.2025 на баланс счёта'
Сценарий:
- Кошелёк клиента 500 руб., заказ 65 руб.
- Оператор выбирает оплату из кошелька — поле суммы ограничено 65 руб.
- Попытка ввести 500 заблокирована UI и серверной валидацией
- Для внешней оплаты (карта онлайн) можно внести 500 руб. — остаток 435 автоматически зачислится в кошелёк как переплата
Цель:
- Исключить путаницу в истории транзакций при оплате кошельком
- Разграничить поведение: кошелёк строго ограничен, внешние методы допускают переплату
- Обеспечить прозрачность движения средств для операторов
Изменения:
- Добавлена пометка '(кошелёк клиента)' к методу оплаты с кодом account_balance в селектах платежа и возврата
- Обновлён текст предупреждения о возврате: теперь явно указано, что зачисление в кошелёк происходит только при выборе метода 'кошелёк клиента'
- Для всех остальных методов (наличные, карта и т.п.) возврат — это информационная метка для истории, без фактического движения средств
Цель:
- Устранить путаницу операторов относительно поведения возвратов
- Чётко разделить возврат клиенту (внешними способами) и зачисление в кошелёк (только для account_balance)
- UI теперь соответствует фактической серверной логике в Transaction.save()
Защита от переплаты:
- Серверная валидация в TransactionService.create_refund проверяет amount <= order.amount_paid
- UI ограничение max на поле ввода суммы возврата
- ValidationError с понятным сообщением при попытке превысить лимит
- Move order form scope to left column only to avoid nested forms
- Place payment/refund forms in right column within same grid row
- Remove transaction delete button - use refunds instead for audit trail
- Simplify transaction history table: show only Date, Payment Method, Amount, and Created By
- Fix form submit buttons to use form attribute for proper association
- Improve visual alignment of two-column layout without empty gaps
This ensures valid HTML (no nested forms), clean financial audit history, and better UX with aligned columns.
- Разделен экран на две колонки: заказ слева, оплата справа
- Форма оплаты вынесена за пределы основной формы заказа (устранена проблема вложенных форм)
- Исправлен метод calculate_total() для сохранения итоговой суммы в БД
- Добавлена модель Transaction для учета платежей и возвратов
- Добавлена модель PaymentMethod для методов оплаты
- Удалена старая модель Payment, заменена на Transaction
- Добавлен TransactionService для управления транзакциями
- Обновлен интерфейс форм оплаты для правой колонки
- Кнопка 'Сохранить изменения' теперь работает корректно
ПРОБЛЕМА:
Использование PaymentFormSet для платежей было НЕПРАВИЛЬНЫМ подходом:
1. Платежи = финансовые транзакции (не должны редактироваться inline)
2. Формы валидировали существующие платежи как новые
3. Сложная логика с formset management forms
4. Конфликты валидации кошелька
РЕШЕНИЕ (Django Best Practices):
Разделили управление платежами на отдельные операции:
АРХИТЕКТУРА:
`
POST /orders/111/payments/add/ # Добавить платеж
POST /orders/111/payments/123/delete/ # Удалить платеж
`
ПРЕИМУЩЕСТВА:
✅ Чистая архитектура (separation of concerns)
✅ Платежи = неизменяемые транзакции
✅ Простая валидация (только для новых)
✅ Легко тестировать
✅ API-ready структура
ИЗМЕНЕНИЯ:
1. orders/views.py:
- Убран PaymentFormSet из order_create и order_update
- Добавлен payment_add(request, order_number)
- Добавлен payment_delete(request, order_number, payment_id)
- Используется простой PaymentForm вместо formset
- Payment.save() автоматически обрабатывает:
* Списание из кошелька
* Обработку переплаты
* Обновление amount_paid
2. orders/urls.py:
- Добавлены URL patterns для payment-add и payment-delete
- Структура: /orders/<number>/payments/add|<id>/delete/
3. orders/templates/orders/order_form.html:
- Убран PaymentFormSet и все его скрипты (~265 строк)
- Простая HTML форма для добавления платежа
- Существующие платежи: read-only список с кнопками удаления
- Каждое удаление = отдельный POST запрос
- Для создания: показываем предупреждение вместо формы
4. orders/templatetags/orders_tags.py (NEW):
- Template tag get_payment_methods
- Загружает активные способы оплаты
- Использование: {% get_payment_methods as payment_methods %}
РЕЗУЛЬТАТ:
- Код: -191 строка
- Логика: простая и понятная
- Архитектура: правильная (как в учебнике)
- Платежи: только add/delete (без edit)
- Валидация: работает корректно
- UX: чище и понятнее
ПРОБЛЕМА:
После предыдущего коммита кнопка сохранения заказа перестала работать.
Клик на кнопку не приводил к отправке формы - ноль реакции.
ПРИЧИНА:
Вложенная форма удаления платежа внутри основной формы order-form.
Вложенные формы недопустимы в HTML и браузер неправильно обрабатывает
submit-события.
РЕШЕНИЕ:
Заменил вложенную форму на JavaScript обработчик:
- Кнопка удаления теперь type=button (не submit)
- Добавлены data-атрибуты: payment-id, payment-name, payment-amount
- JavaScript создает временную форму для POST-запроса с delete_payment_id
- Форма отправляется программно через form.submit()
ИЗМЕНЕНИЯ:
- Заменена форма на button для удаления платежей
- Добавлен JavaScript обработчик .delete-existing-payment-btn
- Подтверждение удаления с именем и суммой платежа
РЕЗУЛЬТАТ:
✅ Кнопка сохранения заказа работает
✅ Удаление существующих платежей работает
✅ Нет вложенных форм (валидный HTML)
ПРОБЛЕМА:
При редактировании заказа с уже существующими платежами из кошелька,
formset пытался валидировать ВСЕ платежи как новые, включая уже
проведенные. Это вызывало ошибки валидации кошелька, даже когда
пользователь просто хотел добавить новый платеж другим методом.
РЕШЕНИЕ:
Разделили отображение платежей на две части:
1. УЖЕ ПРОВЕДЕННЫЕ ПЛАТЕЖИ (информационный блок):
- Показываются в виде read-only карточек (bg-light)
- Не проходят через formset валидацию
- Можно удалить через отдельную форму с POST-запросом
- Содержат: способ оплаты, сумму, примечания, кнопку удаления
2. НОВЫЕ ПЛАТЕЖИ (formset):
- Добавляются через кнопку 'Добавить платеж'
- Проходят валидацию только для новых записей
- Контейнер изначально пустой (#payments-container)
ИЗМЕНЕНИЯ:
orders/templates/orders/order_form.html:
- Добавлен блок 'Проведенные платежи' с информационным отображением
- Каждый существующий платеж с формой удаления (delete_payment_id)
- Контейнер для новых платежей теперь пустой при загрузке
- Обновлен calculatePaymentsTotal(): считает существующие + новые
- Убраны обработчики для несуществующих элементов formset
- Итоговая сумма инициализируется из order.amount_paid
orders/views.py (order_update):
- Добавлена обработка delete_payment_id из POST
- При удалении платежа из кошелька - возврат средств через WalletService
- Пересчет amount_paid после удаления
- Редирект обратно в форму после удаления
РЕЗУЛЬТАТ:
✅ Существующие платежи не валидируются повторно
✅ Можно свободно добавлять новые платежи любым методом
✅ Удаление существующих платежей работает корректно
✅ Возврат в кошелек при удалении платежа 'account_balance'
✅ Правильный подсчет итоговой суммы (существующие + новые)
Убрано поле скидки из системы для последующей реализации полноценной системы скидок.
Изменения:
- Удалено поле discount_amount из модели Order
- Убрано из формы OrderForm
- Удалено из шаблонов order_form.html и order_detail.html
- Убрано из админки OrderAdmin
- Обновлен метод calculate_total() (без вычитания скидки)
В будущем будет создана отдельная модель Discount с промокодами, процентными скидками и автоматическими акциями.
ВАЖНО: После этого коммита нужно создать и применить миграцию:
python manage.py makemigrations orders -n remove_discount_amount
python manage.py migrate orders
- Добавлен префикс 'payments' для PaymentFormSet во всех представлениях
- Добавлен атрибут form='order-form' для динамически создаваемых полей платежей
- Убрано переопределение has_changed() в PaymentForm (использует стандартную логику Django)
- Автоматическая установка created_by для новых платежей
- Автоматический пересчёт payment_status при изменении суммы заказа
- Автоматическая обработка переплаты с возвратом в кошелёк клиента
- Убран весь отладочный код
Проблема: Платежи не сохранялись при создании/редактировании заказа.
Причины:
1. JavaScript функция addNewPayment() использовала неправильный метод
замены __prefix__. При clone().innerHTML.replace() атрибуты name
оставались с буквальным "__prefix__" вместо номера формы.
2. PaymentForm не переопределял has_changed(), из-за чего Django formset
считал заполненные формы "пустыми" и не сохранял их.
Исправления:
- order_form.html: Переписана addNewPayment() - теперь клонирует
template.content, конвертирует в HTML строку, делает replace,
и только потом парсит обратно в DOM элемент
- forms.py: Добавлен метод PaymentForm.has_changed() который правильно
определяет что форма заполнена если указан payment_method ИЛИ amount
- views.py: Добавлена отладочная информация для диагностики проблем
с formset (TODO: удалить после тестирования)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed autosave.js (665 lines) and draft-creator.js (441 lines)
- Removed draft_service.py (~500 lines) and DraftOrderService
- Removed AJAX endpoints: autosave and create-draft
- Updated order_create() to add is_create_page flag
- Updated order_update() to finalize drafts without DraftOrderService
- Added get_new_status() method to OrderStatusService
- Updated order_form.html:
- Removed old JS includes
- Added beforeunload warning for unsaved data
- Updated buttons: separate buttons for create/draft/finalize
- Total code reduction: ~1600 lines (92% removed)
New workflow:
- /orders/create/ - user fills form, chooses button
- /orders/<id>/edit/ - simple editing without autosave
- beforeunload warning when leaving page (except on submit)
- Modified order_create view to read customer from GET parameter
- Pass preselected_customer to template context
- Template renders select with preselected option for Select2
- Fixed draft creation timing with callback after Select2 initialization
- Auto-create draft when customer is preselected from URL
- Graceful handling if customer not found or invalid ID
- Добавлено поле wallet_balance в модель Customer
- Создана модель WalletTransaction для истории операций
- Реализован сервис WalletService с методами:
* add_overpayment - автоматическое зачисление переплаты
* pay_with_wallet - оплата заказа из кошелька
* adjust_balance - ручная корректировка баланса
- Интеграция с Payment.save() для автоматической обработки переплат
- UI для оплаты из кошелька в деталях заказа
- Отображение баланса и долга на странице клиента
- Админка с inline транзакций и запретом ручного создания
- Добавлен способ оплаты account_balance
- Миграция 0004 для customers приложения
Adds proper initialization for checkbox fields on page load:
- address_confirm_with_recipient (Уточнить адрес у получателя)
- customer_is_recipient (Покупатель является получателем)
These fields are already tracked by autosave.js and properly saved
by backend, but were not displaying saved values after page reload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes deletion functionality for order items across frontend and backend:
- Remove restriction preventing deletion of last item
- Add confirmation dialog before deletion
- Properly track and send deleted item IDs to backend via autosave
- Update backend to handle item deletion by ID instead of index
- Fix visual feedback: deleted items are hidden immediately
- Auto-recalculate total sum after deletion
Technical changes:
- order_form.html: Add confirmation dialog, trigger autosave on delete
- autosave.js: Collect deleted item IDs, send to backend
- draft_service.py: Process deleted_item_ids, update items by ID
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Исправлена проблема с пропаданием цен товаров при автосохранении и
перезагрузке страницы.
ПРОБЛЕМА:
- При автосохранении пустые поля цен отправлялись как '0'
- Backend сохранял 0 в базу данных
- При перезагрузке страницы поля цен оставались пустыми
- Итоговая сумма товаров показывала 0.00 руб.
РЕШЕНИЕ 1 - Backend (draft_service.py):
- Изменена логика обработки цен в update_draft()
- Если цена пустая или равна 0, используется actual_price из каталога
- Добавлена корректная обработка price_raw перед конвертацией в Decimal
- Улучшена логика определения is_custom_price
Логика обработки цены:
1. Получаем price_raw из items_data
2. Если price_raw пустой или 0 → используем original_price из каталога
3. Если price_raw заполнен → используем его и сравниваем с original_price
4. is_custom_price = True только если разница больше 0.01
РЕШЕНИЕ 2 - Frontend (order_form.html):
- Добавлена fallback логика в шаблоне для отображения цены
- Если item_form.instance.price пустой/None/0 → показываем actual_price
- Используется inline условие {% if %} для проверки наличия цены
- Отдельная логика для product и product_kit
Теперь работает корректно:
✅ При выборе товара цена автоматически заполняется из каталога
✅ Автосохранение сохраняет правильную цену (из каталога или изменённую)
✅ При перезагрузке страницы цены отображаются корректно
✅ Итоговая сумма товаров рассчитывается правильно
✅ Бейдж "Изменена" показывается только для реально изменённых цен
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Исправлена проблема с отображением бейджа "Изменена" для существующих
товаров в заказе. Теперь при загрузке страницы для всех существующих
позиций устанавливается атрибут data-original-price с актуальной ценой
из каталога, что позволяет корректно отслеживать изменения цены.
Изменения:
- Добавлена условная логика рендеринга поля price с атрибутом data-original-price
- Для товаров используется item_form.instance.product.actual_price
- Для комплектов используется item_form.instance.product_kit.actual_price
- Бейдж "Изменена" теперь работает одинаково для всех форм
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлено отображение общей суммы всех товаров в заказе с автоматическим
обновлением в реальном времени при изменении количества, цены, добавлении
или удалении товаров.
Изменения:
- HTML: Добавлен блок отображения итоговой суммы товаров под списком позиций
- JavaScript: Реализованы функции calculateOrderItemsTotal() и updateOrderItemsTotal()
- Интеграция: Подключены слушатели событий на поля quantity и price
- Обновление суммы происходит при:
* Изменении количества или цены товара
* Добавлении новой позиции
* Удалении позиции
* Загрузке страницы
Сумма автоматически исключает удалённые формы и корректно обрабатывает
пустые значения. Форматирование: 2 знака после запятой.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed from table to card-based design for better space efficiency
- Reduced padding and margins to fit 15+ statuses on screen without scrolling
- Minimized font sizes and icon sizes for compact display
- Added proper styling for edit and delete buttons with hover effects
- Improved visual hierarchy with color indicators and badges
- Maintained all functionality while improving UX
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Изменения:
- Заменено жёсткое кодирование статусов ('draft', 'new' и т.д.) на динамическое отображение из OrderStatus объекта
- Теперь статусы берут цвет (color) и название (label/name) из модели OrderStatus
- Обновлена логика отображения статуса оплаты: заменено payment_status на is_paid и amount_paid
- Добавлены иконки для наглядности (check-circle, exclamation-circle, x-circle)
- Для частичной оплаты теперь показывается сумма уже оплаченного
Это позволяет:
- Добавлять новые статусы без изменения шаблона
- Менять цвета статусов через admin панель
- Использовать правильные поля из модели Order
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Упрощена логика системы путём замены отдельной сущности "Магазин"
на универсальную сущность "Склад", которая может использоваться
как точка самовывоза.
Изменения:
- Расширена модель Warehouse: добавлены адрес, контакты, флаг is_pickup_point
- Модель Order: поле pickup_shop заменено на pickup_warehouse
- Обновлены все формы, сервисы, views, admin для работы со складами
- Обновлены шаблоны HTML и JavaScript код
- Удалено приложение shops полностью
- Пересозданы миграции БД
- Обновлён навбар (удалена ссылка на магазины)
Преимущества:
- Упрощена архитектура системы
- Единая точка управления складами и точками самовывоза
- Интеграция с системой инвентаризации
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated terminology across the order status management system to use 'исход сделки' (deal outcome) instead of 'конец' (end) for better clarity and professional language.
Changes:
- Fixed AttributeError in order_status_list view by removing attempt to set read-only property orders_count
- Updated OrderStatus model verbose_name fields for is_positive_end and is_negative_end
- Updated status form template badges and preview JavaScript
- Updated status list table header
- Created migration for verbose_name changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Features:
- Created OrderStatus model for managing statuses per tenant
- Added system-level statuses: draft, new, confirmed, in_assembly, in_delivery, completed, return, cancelled
- Implemented CRUD views for managing order statuses
- Created OrderStatusService with status transitions and business logic hooks
- Updated Order model to use ForeignKey to OrderStatus
- Added is_returned flag for tracking returned orders
- Updated filters to work with new OrderStatus model
- Created management command for status initialization
- Added HTML templates for status list, form, and confirmation
- Fixed views.py to use OrderStatus instead of removed STATUS_CHOICES
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Кнопка создания заказа вынесена за пределы формы (правильная семантика)
- Добавлена адаптивная верстка для кнопок фильтров:
* На мобильных: кнопки в колонку на всю ширину
* На планшетах+: кнопки в строку
- Добавлен отступ для пагинации (mt-4)
- Колонка "Создан" скрыта на мобильных устройствах (d-none d-md-table-cell)
- Улучшено использование пространства на всех размерах экранов
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Удален заголовок страницы для экономии места
- Кнопка создания заказа перенесена в блок фильтров под календарь
- Кнопка теперь занимает всю ширину для удобства использования
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Фильтры и календарь остаются в стандартном контейнере
- Таблица вынесена в container-fluid с адаптивными отступами
- Уменьшены padding карточки таблицы для максимального использования пространства
- Сохранена адаптивность для всех размеров экранов
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Изменения:
### 1. ProductKit - расчет цены для вариантов товаров
- Добавлена обработка variant_group в методах расчета base_price
- Теперь учитываются варианты товаров при расчете стоимости комплекта
### 2. DraftOrderService - упрощение логики автосохранения
- Удалена проверка is_draft() при обновлении (позволяет обновлять заказы в других статусах)
- Улучшена документация метода update_draft
### 3. Шаблоны и скрипты
- Обновлены шаблоны форм создания/редактирования комплектов
- Обновлены скрипты автосохранения
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Изменен порядок секций формы: товары перемещены выше доставки
- Добавлена защита от двойного создания клиента
- Улучшена валидация при создании клиента с детализацией ошибок
- Добавлен индикатор загрузки при сохранении клиента
- Исправлена логика обработки специальной опции создания клиента
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблема: После переключения между "С доставкой" и "Самовывоз" и автосохранения, при перезагрузке страницы всегда отображался "Самовывоз", независимо от фактически сохраненного значения.
Изменения:
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 <noreply@anthropic.com>
Изменения:
1. **Стоимость доставки (автоматическая/ручная)**:
- Добавлено поле `is_custom_delivery_cost` в модель Order для отслеживания ручной стоимости
- Создан сервис DeliveryCostCalculator для автоматического расчета стоимости доставки
- Реализована логика: бесплатная доставка от 100 руб., иначе 15 руб.
- В форме поле "Ручная стоимость доставки" - если заполнено, используется ручная стоимость, если пустое - автоматический расчет
- Добавлены методы Order.get_delivery_cost(), set_delivery_cost(), reset_delivery_cost(), recalculate_delivery_cost()
2. **Исправление бага выбора клиента в Select2**:
- Удален избыточный обработчик события select2:opening, который блокировал клики
- Добавлены проверки на наличие e.params.data в обработчиках select2:selecting и select2:select
- Теперь выбор клиента работает корректно, создается черновик заказа и происходит редирект
3. **Опциональные поля адреса**:
- Поля recipient_name, street, building_number в модели Address сделаны необязательными (blank=True, null=True)
- Обновлены методы __str__ и full_address для безопасной работы с None значениями
4. **UI улучшения**:
- Удалена звездочка обязательности с полей адреса
- Добавлена подсказка под полем ручной стоимости доставки о правилах автоматического расчета
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Удален выбор режима адреса (История/Новый/Пусто)
- Поля адреса теперь показаны сразу под кнопками доставки
- Создана новая секция "Получатель" под полями адреса с бордюром сверху
- Перемещен чекбокс "Покупатель является получателем" в секцию Получатель
- Поля получателя (имя и телефон) теперь в той же секции
- Удалены CSS стили для скрытого/видимого режимов адреса
- Удалена функция initAddressModeToggle()
- Упрощена UX: доставка → адрес → получатель
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Все поля ввода адреса доставки теперь расположены под кнопками "С ДОСТАВКОЙ" / "САМОВЫВОЗ"
- Поля адреса скрыты когда выбран вариант "САМОВЫВОЗ"
- Поля адреса видны только когда выбрана "С ДОСТАВКОЙ"
- Переименован div с id="delivery-fields" на id="delivery-mode-fields" для лучшей организации
- Обновлена функция syncDeliveryType() для управления видимостью полей доставки
- Улучшена структура формы для лучшей UX
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Увеличен padding-top контейнера с pt-4 до pt-5 для большего отступа от шапки
- Метка "Статус:" теперь расположена слева от поля выбора
- Все элементы в строке заголовка выровнены по нижней базовой линии (align-items-end)
- Используется flexbox (d-flex gap-2) для горизонтального выравнивания
- Все элементы заголовка (Название, Статус, Кнопка) находятся на одной линии
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Статус заказа теперь отображается в один ряд с заголовком и кнопкой "Назад к списку"
- Статус размещен перед кнопкой "Назад к списку" (слева от неё)
- Добавлен больший отступ от шапки сайта (pt-4)
- Удален статус из карточки "Основная информация" для уменьшения дублирования
- Используется align-items-center для визуального выравнивания элементов
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>