Commit Graph

112 Commits

Author SHA1 Message Date
1d97da0d3e Исправлено обновление TOTAL_FORMS при удалении формы через крестик 2025-12-09 00:59:20 +03:00
6230e0fc5d Добавлено логирование в select2:clear для отладки 2025-12-09 00:58:11 +03:00
33533e6268 Исправлено удаление пустых форм: пересчёт индексов и TOTAL_FORMS 2025-12-09 00:53:03 +03:00
91383a2bf7 Добавлены подробные логи в скрипт очистки пустых форм для отладки 2025-12-09 00:51:16 +03:00
347f2357fd Убрано автозаполнение quantity=1 из шаблона пустой формы товара 2025-12-09 00:47:12 +03:00
364012b114 Исправлено: при очистке Select2 теперь также очищается поле количества 2025-12-09 00:43:26 +03:00
bdfb89115a Автоматическая очистка полностью пустых форм товаров перед валидацией заказа 2025-12-09 00:40:33 +03:00
34fa5d12eb Рефакторинг расчёта суммы заказа: упрощена структура и убраны избыточные логи 2025-12-09 00:29:49 +03:00
e32254e62d Сделана функция updateOrderItemsTotal глобальной для доступа из AJAX колбэков 2025-12-09 00:17:13 +03:00
0f22520ecc Добавлены логи для отладки пересчёта суммы товаров 2025-12-09 00:15:36 +03:00
e021c68beb Добавлен автоматический пересчёт суммы товаров после загрузки из черновика 2025-12-09 00:14:07 +03:00
12204bd34a Добавлен механизм отложенного заполнения полей с ожиданием рендеринга формсета 2025-12-09 00:00:20 +03:00
27b988dda7 Исправлена загрузка товаров из черновика через прямое заполнение скрытых полей 2025-12-08 20:06:31 +03:00
2735d745a1 Добавлено детальное логирование загрузки товаров в формсет 2025-12-08 19:22:58 +03:00
8805e3ad41 Добавлена автозагрузка товаров в Select2 при создании заказа из POS 2025-12-08 19:04:04 +03:00
9dab280def Рабочие изменения: улучшения UI, настройки и бэкенд авторизации
Собрал накопившиеся изменения из рабочей директории:

UI улучшения:
- customer_detail.html: Расширен интерфейс детальной страницы клиента
- order_detail.html: Добавлены элементы отображения деталей заказа
- order_list.html: Улучшена визуализация списка заказов

Бэкенд:
- customers/views.py: Доработаны представления для работы с клиентами
- products/views/product_views.py: Минорные правки
- user_roles/auth_backend.py: Добавлен кастомный бэкенд авторизации

Настройки:
- myproject/settings.py: Обновлены конфигурации
- .gitignore: Добавлен для игнорирования служебных файлов
- requirements.txt: Удален (вероятно заменен на poetry/pipenv)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 01:08:53 +03:00
dcfb76121d SECURITY: Защита критичных полей системных статусов от редактирования
Заблокировал изменение полей is_positive_end и is_negative_end для
системных статусов заказов, так как эти флаги используются в сигналах
inventory для управления резервированием и списанием товаров со склада.

Что изменено:
- OrderStatusForm: Добавлена блокировка (disabled=True) для полей
  is_positive_end и is_negative_end при редактировании системных статусов
- status_form.html: Заменено информационное предупреждение на красное
  с детальным описанием заблокированных полей и их влияния на систему

Почему это критично:
Эти флаги проверяются в 3 сигналах inventory/signals.py:
1. rollback_sale_on_status_change - откатывает продажи при уходе от 'completed'
2. release_reservations_on_cancellation - освобождает резервы при отмене
3. reserve_stock_on_uncancellation - резервирует при восстановлении заказа

Случайное изменение флагов может привести к:
- Неправильному освобождению резервов товара
- Двойному резервированию
- Блокировке товара навсегда
- Списанию товара для отмененных заказов

Разрешено редактировать для системных статусов: name, label, color, description

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 01:07:15 +03:00
702d42e943 Removed 'Not set' status option from order list dropdown 2025-12-01 12:19:16 +03:00
4343b2eb5b Улучшен UI формы оплаты: красивый бейдж НЕ ОПЛАЧЕНО с пульсирующей анимацией, убран устаревший код смешанной оплаты, исправлены критичные ошибки JavaScript 2025-11-29 22:47:56 +03:00
9c6092262c Добавлена автоподстановка суммы для оплаты с кошелька и подсказка при нулевом балансе 2025-11-29 22:29:28 +03:00
4d197790fc Упрощена форма оплаты заказа: единая форма платежа/возврата с переключателем режимов 2025-11-29 22:23:42 +03:00
7d45106411 Убрана автоматическая обработка переплаты - только ручное управление 2025-11-29 20:42:58 +03:00
8cd2cfdb84 Уточнен текст предупреждения о переплате - объяснена автоматика 2025-11-29 20:40:37 +03:00
7c1780697a Добавлено свойство overpayment для корректного отображения переплаты 2025-11-29 20:38:15 +03:00
42eddc0fd1 Упрощена логика обработки переплаты - убрана автоматика из calculate_total
Проблема:
- calculate_total() пытался автоматически обрабатывать переплату
- Это приводило к дублированию логики и сложной отладке
- Нарушался принцип единственной ответственности

Решение:
- Удалена автоматическая обработка переплаты из Order.calculate_total()
- Теперь calculate_total() ТОЛЬКО считает сумму - всё
- Переплата обрабатывается ТОЛЬКО в TransactionService при создании платежей/возвратов
- Добавлено предупреждение в UI о переплате с инструкцией

Как работает теперь:
1. При оплате - TransactionService автоматически вызывает add_overpayment()
2. При изменении товаров - calculate_total() только пересчитывает сумму
3. Если появилась переплата - оператор видит предупреждение
4. Оператор вручную создаёт возврат в кошелёк через форму

Преимущества:
- Одно место ответственности за переплаты
- Прозрачность для оператора
- Нет скрытых автоматизмов
- Легко обслуживать и отлаживать
- Стандартный подход для e-commerce
2025-11-29 20:34:20 +03:00
3f22677573 Защита от переплаты кошельком и улучшение отображения транзакций
Изменения в 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 автоматически зачислится в кошелёк как переплата

Цель:
- Исключить путаницу в истории транзакций при оплате кошельком
- Разграничить поведение: кошелёк строго ограничен, внешние методы допускают переплату
- Обеспечить прозрачность движения средств для операторов
2025-11-29 16:54:24 +03:00
312cd808e6 Уточнение UI возвратов: пометка метода кошелька и корректный текст предупреждения
Изменения:
- Добавлена пометка '(кошелёк клиента)' к методу оплаты с кодом account_balance в селектах платежа и возврата
- Обновлён текст предупреждения о возврате: теперь явно указано, что зачисление в кошелёк происходит только при выборе метода 'кошелёк клиента'
- Для всех остальных методов (наличные, карта и т.п.) возврат — это информационная метка для истории, без фактического движения средств

Цель:
- Устранить путаницу операторов относительно поведения возвратов
- Чётко разделить возврат клиенту (внешними способами) и зачисление в кошелёк (только для account_balance)
- UI теперь соответствует фактической серверной логике в Transaction.save()

Защита от переплаты:
- Серверная валидация в TransactionService.create_refund проверяет amount <= order.amount_paid
- UI ограничение max на поле ввода суммы возврата
- ValidationError с понятным сообщением при попытке превысить лимит
2025-11-29 15:47:47 +03:00
2ec6d1935d Refactor order edit page layout and payment UI
- 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.
2025-11-29 15:12:07 +03:00
c1351e1f49 Исправлена форма заказа: две колонки и корректная работа кнопки сохранения
- Разделен экран на две колонки: заказ слева, оплата справа
- Форма оплаты вынесена за пределы основной формы заказа (устранена проблема вложенных форм)
- Исправлен метод calculate_total() для сохранения итоговой суммы в БД
- Добавлена модель Transaction для учета платежей и возвратов
- Добавлена модель PaymentMethod для методов оплаты
- Удалена старая модель Payment, заменена на Transaction
- Добавлен TransactionService для управления транзакциями
- Обновлен интерфейс форм оплаты для правой колонки
- Кнопка 'Сохранить изменения' теперь работает корректно
2025-11-29 14:33:23 +03:00
438ca5d515 Move payment form back to Payment section (outside main form)\n\nPayment add form is now positioned right after the Payment card section,\nmaking it more logical - all payment-related UI is together.\n\nThe form remains OUTSIDE the main order form to avoid nested forms issue. 2025-11-29 02:34:08 +03:00
84ed3a0c7d Рефакторинг: отдельные endpoints для управления платежами (Django best practices)
ПРОБЛЕМА:
Использование 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: чище и понятнее
2025-11-29 02:27:50 +03:00
ee002d5fed Исправить: кнопка сохранения заказа не работала (вложенная форма)
ПРОБЛЕМА:
После предыдущего коммита кнопка сохранения заказа перестала работать.
Клик на кнопку не приводил к отправке формы - ноль реакции.

ПРИЧИНА:
Вложенная форма удаления платежа внутри основной формы 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)
2025-11-29 02:18:05 +03:00
f9e086fd89 Исправить: показывать существующие платежи информационно при редактировании заказа
ПРОБЛЕМА:
При редактировании заказа с уже существующими платежами из кошелька,
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'
 Правильный подсчет итоговой суммы (существующие + новые)
2025-11-29 02:14:54 +03:00
cf1dce2621 Удалить поле discount_amount из модели Order
Убрано поле скидки из системы для последующей реализации полноценной системы скидок.

Изменения:
- Удалено поле 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
2025-11-29 02:00:23 +03:00
a97fc39a2c Рефакторинг: убрана финализация черновиков и улучшены шаблоны заказов
- Убран черновик как отдельная сущность с процессом финализации
- Черновик теперь просто обычный OrderStatus
- Удалены кнопки 'Сохранить как черновик' и 'Финализировать черновик'
- Унифицирована логика сохранения/обновления заказов для всех статусов

Улучшения шаблонов:
- Стандартизировано форматирование валюты через floatformat:2
- Исправлено отображение статуса (используется OrderStatus.label и color)
- Исправлено отображение способа оплаты (корректное использование ForeignKey)
- Добавлены иконки к заголовкам секций для лучшего UX
- Удалены избыточные console.log (~160 строк)
- Очищены комментарии и улучшена читаемость кода
- Убрано использование переменной is_draft в контексте
- Добавлена визуальная согласованность между шаблонами заказов
2025-11-29 01:51:19 +03:00
9415aca63d Исправлена проблема с сохранением платежей и автоматический пересчёт статуса оплаты
- Добавлен префикс 'payments' для PaymentFormSet во всех представлениях
- Добавлен атрибут form='order-form' для динамически создаваемых полей платежей
- Убрано переопределение has_changed() в PaymentForm (использует стандартную логику Django)
- Автоматическая установка created_by для новых платежей
- Автоматический пересчёт payment_status при изменении суммы заказа
- Автоматическая обработка переплаты с возвратом в кошелёк клиента
- Убран весь отладочный код
2025-11-29 00:48:04 +03:00
a101d2919c fix: Payment formset not saving - fixed template replacement and has_changed()
Проблема: Платежи не сохранялись при создании/редактировании заказа.

Причины:
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>
2025-11-28 23:58:39 +03:00
9a44c98e6e Simplify order creation and editing - remove autosave
- 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)
2025-11-28 23:29:19 +03:00
f911a57640 Before simplifying order creation and editing 2025-11-28 23:11:34 +03:00
82ed5a409e Добавлена функциональность редактирования заказов с обновлением резервов товаров 2025-11-27 21:13:42 +03:00
c62cdb0298 feat: Add customer prefill from URL parameter in order creation
- 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
2025-11-27 00:17:02 +03:00
5ead7fdd2e Реализация системы кошелька клиента для переплат
- Добавлено поле wallet_balance в модель Customer
- Создана модель WalletTransaction для истории операций
- Реализован сервис WalletService с методами:
  * add_overpayment - автоматическое зачисление переплаты
  * pay_with_wallet - оплата заказа из кошелька
  * adjust_balance - ручная корректировка баланса
- Интеграция с Payment.save() для автоматической обработки переплат
- UI для оплаты из кошелька в деталях заказа
- Отображение баланса и долга на странице клиента
- Админка с inline транзакций и запретом ручного создания
- Добавлен способ оплаты account_balance
- Миграция 0004 для customers приложения
2025-11-26 14:47:11 +03:00
0653ec0545 Рефакторинг моделей заказов и добавление методов оплаты 2025-11-26 13:38:02 +03:00
08e8409a66 Fix: Restore checkbox values on page reload for recipient fields
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>
2025-11-26 06:34:44 +03:00
3b4785e2ad Fix: Implement proper deletion of order items with confirmation dialog
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>
2025-11-26 06:27:27 +03:00
5df182e030 Fix: Auto-fill product prices when empty or zero in autosave
Исправлена проблема с пропаданием цен товаров при автосохранении и
перезагрузке страницы.

ПРОБЛЕМА:
- При автосохранении пустые поля цен отправлялись как '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>
2025-11-25 20:15:50 +03:00
fbc9d86a62 Fix: Set original price for existing order items on page load
Исправлена проблема с отображением бейджа "Изменена" для существующих
товаров в заказе. Теперь при загрузке страницы для всех существующих
позиций устанавливается атрибут 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>
2025-11-25 19:42:18 +03:00
436cac28ed Feat: Add order items total sum display with real-time calculation
Добавлено отображение общей суммы всех товаров в заказе с автоматическим
обновлением в реальном времени при изменении количества, цены, добавлении
или удалении товаров.

Изменения:
- HTML: Добавлен блок отображения итоговой суммы товаров под списком позиций
- JavaScript: Реализованы функции calculateOrderItemsTotal() и updateOrderItemsTotal()
- Интеграция: Подключены слушатели событий на поля quantity и price
- Обновление суммы происходит при:
  * Изменении количества или цены товара
  * Добавлении новой позиции
  * Удалении позиции
  * Загрузке страницы

Сумма автоматически исключает удалённые формы и корректно обрабатывает
пустые значения. Форматирование: 2 знака после запятой.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 19:39:03 +03:00
fdd14804a7 Улучшена таблица статусов заказов: заменены иконки Font Awesome на Bootstrap Icons, увеличены бейджи, полные названия типов и итогов, кнопки действий только с иконками 2025-11-19 00:53:16 +03:00
a1888b7745 Optimize order statuses list page with compact card layout
- 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>
2025-11-18 23:00:29 +03:00