- Добавить inline-редактирование цен в списке товаров
- Оптимизировать карточки товаров в POS-терминале
- Рефакторинг моделей единиц измерения
- Миграция unit -> base_unit в SalesUnit
- Улучшить UI форм создания/редактирования товаров
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Добавлено поле combine_mode с тремя режимами:
- stack - складывать с другими скидками
- max_only - применять только максимальную
- exclusive - отменяет все остальные скидки
Изменения:
- Модель Discount: добавлено поле combine_mode
- Calculator: новый класс DiscountCombiner, методы возвращают списки скидок
- Applier: создание нескольких DiscountApplication записей
- Admin: отображение combine_mode с иконками
- POS API: возвращает списки применённых скидок
- POS UI: отображение нескольких скидок с иконками режимов
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Добавлен API endpoint /pos/api/discounts/available/ для получения списка доступных скидок
- Добавлен метод DiscountApplier.apply_manual_discount() для применения ручных скидок
- Обновлен POS checkout для обработки manual_discount_id
- Расширена секция скидок в модальном окне:
* Отображение автоматических скидок (read-only)
* Dropdown для выбора скидки вручную
* Подробная детализация: подитог, общая скидка, скидки на позиции
* Поле промокода с иконкой
- Увеличен размер модального окна и изменено соотношение колонок (5/7)
- Убрана вертикальная прокрутка из модального окна
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Добавлен pre_save сигнал для Order вместо django-simple-history
- Переписаны все функции signals.py без использования instance.history
- Заменены .username на .name|default:.email для CustomUser в шаблонах
- Исправлен CSRF-токен в POS для работы с CSRF_USE_SESSIONS=True
Теперь создание заказов работает корректно в мультитенантной архитектуре.
- Обновлён pos/views.py: метод pos_checkout теперь создаёт Order и связанную модель Delivery
- Обновлён showcase_manager.py: метод sell_showcase_item_to_customer использует новую архитектуру
- Удалён устаревший скрипт create_demo_orders.py
- Исправлена ошибка 'property is_delivery of Order object has no setter'
- Интегрирован готовый компонент ProductSearchPicker в модалку редактирования
- Добавлен collapse-блок с поиском товаров, который отображается только в режиме редактирования
- При выборе товара он автоматически добавляется в tempCart или увеличивается количество если уже есть
- Добавлен CSS и JS для компонента product-search-picker
- В view передаётся categories QuerySet для работы фильтров компонента
- Блок добавления товаров показывается только при редактировании, скрыт при создании нового комплекта
- Удалены дублирующиеся функции getCookie() и getCsrfToken() в terminal.js
- Оставлена единая версия getCookie() с алиасом getCsrfToken для совместимости
- Удалены неиспользуемые пустые кнопки из панели действий
- Добавлена логика скрытия поля 'Количество букетов' в режиме редактирования комплекта
- Оптимизирована компоновка кнопок действий (используется offset-4)
- Улучшены комментарии в коде
Результат: -44 строки, код стал чище и поддерживаемее
Новая архитектура:
- ShowcaseItem модель - физический экземпляр букета на витрине
- OneToOneField(sold_order_item) - БД-уровневая защита от двойной продажи
- Поддержка создания нескольких экземпляров одного букета
- Возможность продавать N из M доступных (например 2 из 5)
Изменения:
- inventory/models.py: добавлена модель ShowcaseItem с методами lock/unlock/mark_sold
- inventory/services/showcase_manager.py: переработан для работы с ShowcaseItem
- pos/views.py: API поддерживает quantity и showcase_item_ids
- pos/templates/pos/terminal.html: поле "Сколько букетов создать"
- pos/static/pos/js/terminal.js: выбор количества, передача showcase_item_ids
Миграции:
- 0007: создание модели ShowcaseItem
- 0008: data migration существующих букетов
- 0009: очистка ShowcaseItem для уже проданных букетов
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Проблема:
- Баланс кошелька клиента не отображался в модальном окне при нажатии "ПРОДАТЬ"
- Данные о балансе не передавались из backend в frontend
Исправления:
1. pos/views.py:
- Добавлен wallet_balance в selected_customer при загрузке из Redis
- Добавлен wallet_balance в system_customer
- Добавлен wallet_balance в API set_customer (Redis + response)
- Используется json.dumps() для корректной сериализации данных клиента
2. customers/views.py:
- Добавлен wallet_balance в API поиска клиентов (api_search_customers)
- Добавлен wallet_balance в API создания клиента (api_create_customer)
3. pos/static/pos/js/terminal.js:
- Обновлена функция selectCustomer() для получения walletBalance
- Обновлены все вызовы selectCustomer() для передачи баланса
- selectedCustomer теперь содержит wallet_balance
4. pos/templates/pos/terminal.html:
- Используются готовые JSON-строки из backend (system_customer_json, selected_customer_json)
- Исправлена проблема с локализацией чисел в JSON
Результат:
Баланс кошелька клиента теперь корректно отображается в модальном окне продажи
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
1. Убран параметр версии ?v=4 из подключения terminal.js (для разработки не нужен)
2. Исправлена логика автоподстановки суммы в PaymentWidget:
- Теперь при выборе способа оплаты подставляется ОСТАТОЧНАЯ сумма
- Остаток = amount_due - уже добавленные платежи
- Добавлена подсказка "Осталось оплатить: X руб."
Пример:
- Заказ на 30 руб.
- Добавили платеж 10 руб. наличными
- Выбираем картой → автоматически подставится 20 руб. (а не 30!)
Это предотвращает ошибки и переплаты при смешанной оплате.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Убрана кнопка "Оплатить" внутри PaymentWidget, чтобы избежать путаницы.
Теперь есть только одна кнопка "Подтвердить продажу" внизу модального окна.
При смешанной оплате:
- Кнопка "Добавить платеж" для добавления способов оплаты
- Кнопка "Подтвердить продажу" для завершения (внизу модалки)
Это удобнее и безопаснее - пользователи не будут случайно нажимать
не ту кнопку при добавлении нескольких платежей.
Версия JS: v4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Исправления:
1. Удален вызов несуществующей функции updateCartCount()
2. Добавлена автоматическая перезагрузка страницы через 500ms после успешной продажи
3. Добавлены console.log для отладки процесса продажи
Теперь после успешной продажи:
- ✅ Заказ создается
- ✅ Корзина очищается
- ✅ Модалка закрывается
- ✅ Страница автоматически перезагружается
- ✅ Остатки товаров обновляются
- ❌ Никаких ошибок в консоли
Версия JS: v3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
1. Добавлен параметр ?v=2 к terminal.js для принудительной загрузки новой версии
2. Добавлен вызов loadItems() после успешной продажи для обновления списка товаров
Теперь после продажи:
- Корзина очищается
- Список товаров слева автоматически обновляется (показывает актуальные остатки)
- Витринные комплекты перезагружаются
- Не требуется ручное обновление страницы
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Исправлена ошибка 'currentWarehouse is not defined' при проведении продажи.
Добавлен JSON блок currentWarehouseData в template и инициализация
переменной currentWarehouse в terminal.js.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлена интеграция оплаты в POS с поддержкой одиночной и смешанной оплаты,
работой с кошельком клиента и автоматическим созданием заказов.
Backend изменения:
- TransactionService: добавлены методы get_available_payment_methods() и create_multiple_payments()
для фильтрации способов оплаты и атомарного создания нескольких платежей
- POS API: новый endpoint pos_checkout() для создания заказов со статусом "Выполнен"
с обработкой платежей, освобождением блокировок и очисткой корзины
- Template tags: payment_tags.py для получения способов оплаты в шаблонах
Frontend изменения:
- PaymentWidget: переиспользуемый ES6 класс с поддержкой single/mixed режимов,
автоматической валидацией и интеграцией с кошельком клиента
- terminal.html: компактное модальное окно (70vw) с оптимизированной компоновкой,
удален функционал скидок, добавлен показ баланса кошелька
- terminal.js: динамическая загрузка PaymentWidget, интеграция с backend API,
обработка успешной оплаты и ошибок
Поддерживаемые способы оплаты: наличные, карта, онлайн, баланс счёта.
Смешанная оплата позволяет комбинировать несколько способов в одной транзакции.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Critical fix for Celery photo processing. The storage class now correctly
handles file reading operations by automatically adding tenant_id prefix
when opening files.
Problems fixed:
- Celery tasks could not open image files from storage
- PIL/Pillow couldn't locate files in tenant-specific directories
- temp file deletion was failing due to path validation
Changes:
- Added _open() method to add tenant_id prefix when opening files
- Added path() method to convert relative paths to full filesystem paths
- Updated delete() method to handle paths with or without tenant prefix
- All methods include security checks to prevent cross-tenant access
Testing:
- All 5 existing tests pass
- Verified photo processing task works end-to-end:
* Reads temp image file from disk
* Processes and creates all image versions
* Saves processed files to tenant-specific directory
* Cleans up temporary files correctly
- Files correctly stored in: media/tenants/{tenant_id}/products/{product_id}/{photo_id}/
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed:
- Replace is_active with status='active' for Product filtering in IncomingModelForm
- Product model uses status field instead of is_active
Added:
- Showcase field to ProductKit for tracking showcase placement
- product_kit field to Reservation for tracking kit-specific reservations
- Disassemble button in POS terminal for showcase kits
- API endpoint for kit disassembly (release reservations, mark discontinued)
- Improved reservation filtering when dismantling specific kits
Changes:
- ShowcaseManager now links reservations to specific kit instances
- POS terminal modal shows disassemble button in edit mode
- Kit disassembly properly updates stock aggregates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced static customer display in the checkout/sale modal with the same interactive button functionality from the cart sidebar.
Changes:
- **HTML**: Replaced static div with interactive button + reset button in checkout modal
- **JavaScript**:
- Updated updateCustomerDisplay() to handle both locations (cart + checkout modal)
- Added event listeners for checkout modal customer buttons
- Both buttons now synchronized and use the same selection modal
Benefits:
✅ Consistent UX across cart and checkout modal
✅ Full code reuse - same selection modal, search, and logic
✅ Both locations stay synchronized automatically
✅ Can search, select, and reset customer directly from checkout modal
Implementation:
- Cart sidebar button: customerSelectBtn, resetCustomerBtn
- Checkout modal button: checkoutCustomerSelectBtn, checkoutResetCustomerBtn
- Single updateCustomerDisplay() updates both locations
- Single selectCustomer() used by all buttons
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented Redis caching with 2-hour TTL for POS session data:
Backend changes:
- Added Redis cache configuration in settings.py
- Created save_cart() endpoint to persist cart state
- Added cart and customer loading from Redis in pos_terminal()
- Validates cart items (products/kits) still exist in DB
- Added REDIS_HOST, REDIS_PORT, REDIS_DB to .env
Frontend changes:
- Added saveCartToRedis() with 500ms debounce
- Cart auto-saves on add/remove/quantity change
- Added cart initialization from Redis on page load
- Enhanced customer button with two-line display and reset button
- Red X button appears only for non-system customers
Features:
- Cart persists across page reloads (2 hour TTL)
- Customer selection persists (2 hour TTL)
- Independent cart per user+warehouse combination
- Automatic cleanup of deleted items
- Debounced saves to reduce server load
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Добавлен API endpoint GET /pos/api/showcase-kits/ для получения актуальных витринных букетов
- Изменена переменная SHOWCASE_KITS на изменяемую showcaseKits
- Добавлена функция refreshShowcaseKits() для обновления данных с сервера
- Кнопка ВИТРИНА теперь загружает свежие данные перед отображением
- После создания временного букета автоматически обновляется список и переключается вид на витрину
- Исправлена проблема с отображением только что созданных витринных букетов
- Reduced spacing around 'Итого:' line for more compact design
- Changed from h5 to strong tags for better space utilization
- Removed bottom margin from cart list
- Set symmetric padding (py-1) for total section
- More vertical space now available for cart items
- Added get_showcase_kits_for_pos() function to retrieve showcase kits with active reservations
- Modified POS terminal to show showcase kits when 'Витрина' button is clicked
- Showcase kits displayed as product cards with showcase name badge (🌺 icon)
- Added isShowcaseView flag to toggle between regular and showcase view modes
- Implemented distinct styling for active showcase button:
* Bright orange background (#ff6600)
* Black text for contrast
* Thicker border (3px)
* Enhanced shadow and scale effect (1.05)
- Showcase kits can be added to cart for sale from POS interface
- Добавлен API endpoint для создания временного комплекта из корзины
- Реализован endpoint получения списка активных витрин
- Создано модальное окно для настройки комплекта и выбора витрины
- JavaScript логика: валидация корзины, отправка данных, очистка после успеха
- Автоматическая генерация названия комплекта с датой и временем
- Агрегация дубликатов товаров в корзине перед созданием
- Резервирование компонентов на витрину через ShowcaseManager
- Расчёт и отображение итоговой цены комплекта
- Создана модель Showcase (витрина) привязанная к складу
- Расширена Reservation для поддержки витринных резервов
- Добавлены поля в OrderItem для маркировки витринных продаж
- Реализован ShowcaseManager с методами резервирования, продажи и разбора
- Обновлён админ-интерфейс для управления витринами
- Добавлена кнопка Витрина в POS (категории) и API для просмотра
- Добавлена кнопка На витрину в панели действий POS
- Миграции готовы к применению