Commit Graph

57 Commits

Author SHA1 Message Date
275bc1b78d Исправлена ошибка создания заказов в POS после рефакторинга модели доставки
- Обновлён 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'
2026-01-02 17:46:32 +03:00
1ead77b2d8 Добавлено округление количества для корректного отображения в POS
Проблема:

- JavaScript float arithmetic даёт погрешность при вычислениях

- На карточке товара показывалось -0.050000000000044

- Происходило при: available - reserved - inCart

Решение:

- Добавлена функция roundQuantity(value, decimals=3)

- Округляет результат вычислений до 3 знаков после запятой

- Применяется ТОЛЬКО для отображения, не для расчётов

- Используется для: free, reserved, inCart в карточках товаров

Результат:

- Отображение: -0.05 вместо -0.050000000000044

- Данные с бэка остаются точными (строка)

- Погрешность устранена только визуально

Примечание:

- Округление в JS НЕИЗБЕЖНО для отображения

- Это НЕ маскировка - это правильное форматирование

- Бэкенд уже отдаёт точные данные как строки
2026-01-02 15:38:41 +03:00
ce2cfca3f2 Добавлена возможность добавлять новые товары в витринный комплект при редактировании
- Интегрирован готовый компонент ProductSearchPicker в модалку редактирования
- Добавлен collapse-блок с поиском товаров, который отображается только в режиме редактирования
- При выборе товара он автоматически добавляется в tempCart или увеличивается количество если уже есть
- Добавлен CSS и JS для компонента product-search-picker
- В view передаётся categories QuerySet для работы фильтров компонента
- Блок добавления товаров показывается только при редактировании, скрыт при создании нового комплекта
2025-12-14 14:00:51 +03:00
aff25d0317 Реализована возможность редактирования состава витринного комплекта с поддержкой отрицательных резервов
- Добавлены методы reserve_product_to_showcase и release_showcase_reservation в ShowcaseManager
- Методы работают с резервами для всех активных экземпляров витринного комплекта
- НЕ блокируют создание резерва при нехватке товара, возвращают информацию о дефиците (overdraft)
- Обновлён API endpoint update_product_kit для корректировки резервов при изменении состава
- Добавлено визуальное предупреждение на фронте о нехватке товара на складе
- В модалке редактирования комплекта добавлены контролы для изменения количества товаров (+/-, поле ввода, удаление)
- Автоматический пересчёт цен при изменении состава
- Очистка корзины POS после успешного создания витринного комплекта
2025-12-14 13:49:13 +03:00
4ce610985b Исправлен порядок операций при конвертации резервов в продажи
Проблема:
При продаже витринного комплекта резервы оставались в статусе 'reserved'
вместо 'converted_to_sale'. Товары из состава комплекта не освобождались.

Причина:
В методе sell_showcase_items порядок операций был неправильный:
1. create_sale_from_reservation вызывался ПЕРВЫМ
2. reservation.order_item устанавливался ПОСЛЕ

В SaleProcessor.create_sale_from_reservation есть логика:
  if order and reservation.order_item:
      sale_price = reservation.order_item.price
  else:
      sale_price = reservation.product.actual_price

Так как order_item был None, цена бралась из product.actual_price,
а не из OrderItem, и резерв не конвертировался корректно.

Решение:
Правильный порядок операций:
1. Устанавливаем reservation.order_item = order_item
2. Сохраняем reservation
3. Вызываем create_sale_from_reservation (теперь order_item доступен)
4. Обновляем статус на 'converted_to_sale'
5. Сохраняем финальное состояние

Теперь резервы корректно преобразуются в продажи с правильной ценой
из позиции заказа, и товары освобождаются после продажи.
2025-12-11 22:55:06 +03:00
741fdc97a8 Добавлены кнопки +/- для управления количеством витринных комплектов в корзине
Теперь витринные букеты можно увеличивать и уменьшать по экземплярам:

UI изменения:
- Заменен badge на полноценные кнопки +/- как у обычных товаров
- Поле количества readonly с желтым фоном для визуального отличия
- Кнопки используют тот же дизайн что и для обычных товаров

Функционал увеличения (increaseShowcaseKitQty):
- Блокирует еще один доступный экземпляр через API
- Проверяет наличие свободных букетов на витрине
- Показывает сообщение если нет доступных
- Обновляет showcase_item_ids и qty в корзине

Функционал уменьшения (decreaseShowcaseKitQty):
- Снимает блокировку с последнего экземпляра из списка
- При qty=1 полностью удаляет из корзины
- Обновляет список витрины после изменения

Все операции синхронизируются с сервером и Redis.
2025-12-11 22:10:06 +03:00
65ffed2f9b Блокировка кнопки 'НА ВИТРИНУ' при наличии витринного комплекта в корзине
- Добавлена проверка наличия витринных комплектов (showcase_kit) в корзине
- Кнопка 'НА ВИТРИНУ' блокируется при наличии витринного букета
- Добавлено визуальное оформление: opacity 0.5, disabled state, tooltip
- Показывается предупреждение при попытке создать новый букет
- Функция updateShowcaseButtonState() вызывается при каждом изменении корзины
2025-12-11 22:01:32 +03:00
c76163640e Рефакторинг POS терминала: устранение дублирования кода и оптимизация UI
- Удалены дублирующиеся функции getCookie() и getCsrfToken() в terminal.js
- Оставлена единая версия getCookie() с алиасом getCsrfToken для совместимости
- Удалены неиспользуемые пустые кнопки из панели действий
- Добавлена логика скрытия поля 'Количество букетов' в режиме редактирования комплекта
- Оптимизирована компоновка кнопок действий (используется offset-4)
- Улучшены комментарии в коде

Результат: -44 строки, код стал чище и поддерживаемее
2025-12-10 00:35:56 +03:00
5c94a5ab95 POS: улучшения работы с витринными букетами
- Упрощено добавление в корзину: 1 клик = 1 шт (без prompt)
- API показывает все букеты (available + in_cart), не только доступные
- Карточка показывает available/total и сколько в корзине
- Корзина показывает реальное количество витринных букетов
- Кнопка "Очистить" сбрасывает блокировки и обновляет отображение
- API release-all-my-locks для сброса зависших блокировок
- Автоочистка истёкших блокировок при загрузке витрины

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 00:23:00 +03:00
cfc6ce451e ShowcaseItem: защита от двойной продажи витринных букетов
Новая архитектура:
- 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>
2025-12-09 23:51:37 +03:00
40b180171a Исправлена кнопка ОТЛОЖЕННЫЙ заказ - удален старый обработчик 2025-12-08 19:00:54 +03:00
6c19c9e093 POS deferred order feature 2025-12-08 18:56:14 +03:00
18a6c5fa05 FIX: Обновление баланса в виджете оплаты при смене клиента
Проблема:
- При сбросе клиента на системного в модальном окне продажи баланс кошелька
  в виджете оплаты (возле кнопки "С баланса счёта") не обновлялся
- Виджет PaymentWidget сохранял данные предыдущего клиента

Исправления:
- Добавлена функция updatePaymentWidgetCustomer() для переинициализации виджета
- Функция updateCheckoutWalletBalance() теперь вызывает updatePaymentWidgetCustomer()
- При смене клиента виджет оплаты автоматически переинициализируется с новыми данными

Результат:
При смене клиента баланс кошелька обновляется везде, включая виджет оплаты

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:35:40 +03:00
4817bc388b FIX: Обновление баланса кошелька при смене клиента в модальном окне
Проблема:
- При сбросе клиента на системного в модальном окне продажи баланс кошелька
  оставался от предыдущего клиента и не обновлялся

Исправления:
- Добавлена функция updateCheckoutWalletBalance() для обновления баланса
- Функция updateCustomerDisplay() теперь вызывает updateCheckoutWalletBalance()
- Исправлены все кнопки сброса/выбора системного клиента - теперь передают wallet_balance

Результат:
При смене клиента баланс кошелька в модальном окне обновляется корректно

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:14:47 +03:00
16234b0a1f FIX: Добавлен баланс кошелька клиента в модальное окно продажи POS
Проблема:
- Баланс кошелька клиента не отображался в модальном окне при нажатии "ПРОДАТЬ"
- Данные о балансе не передавались из 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>
2025-12-04 13:11:50 +03:00
f290ae4102 FIX: Убрана ошибка updateCartCount + добавлена перезагрузка страницы после продажи
Исправления:
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>
2025-12-03 20:37:56 +03:00
aa7085d6e1 FIX: Добавлена версия JS для очистки кэша + автообновление товаров после продажи
1. Добавлен параметр ?v=2 к terminal.js для принудительной загрузки новой версии
2. Добавлен вызов loadItems() после успешной продажи для обновления списка товаров

Теперь после продажи:
- Корзина очищается
- Список товаров слева автоматически обновляется (показывает актуальные остатки)
- Витринные комплекты перезагружаются
- Не требуется ручное обновление страницы

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:17:42 +03:00
4160c015f8 FIX: Исправлена ошибка updateCartUI is not defined после оплаты
Заменен вызов несуществующей функции updateCartUI() на корректный renderCart().
Теперь после успешной оплаты корзина корректно очищается и обновляется в UI.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:11:42 +03:00
fe6e4d6682 Fix: добавлена передача данных о текущем складе в JavaScript
Исправлена ошибка '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>
2025-12-03 20:05:11 +03:00
1cda9086d0 Реализована полноценная система оплаты для POS-терминала
Добавлена интеграция оплаты в 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>
2025-12-03 15:38:35 +03:00
87cba63c47 Fix: Add _open() and path() methods to TenantAwareFileSystemStorage
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>
2025-11-23 20:30:52 +03:00
33e33ecbac Добавлена система Soft Lock для витринных комплектов в POS-терминале
Реализована элегантная блокировка витринных букетов при добавлении в корзину,
предотвращающая многократную продажу одного физического комплекта.

## Изменения в БД:
- Добавлены поля в Reservation: cart_lock_expires_at, locked_by_user, cart_session_id
- Созданы индексы для оптимизации запросов блокировок
- Миграция 0006: добавление полей Soft Lock

## Backend (pos/views.py):
- add_showcase_kit_to_cart: создание блокировки на 30 минут с проверкой конфликтов
- remove_showcase_kit_from_cart: снятие блокировки при удалении из корзины
- get_showcase_kits_api: возврат статусов блокировок (is_locked, locked_by_me)

## Frontend (terminal.js):
- addToCart: AJAX запрос для создания блокировки, запрет qty > 1
- removeFromCart: автоматическое снятие блокировки
- renderCart: желтый фон, badge "1 шт (витрина)", скрыты кнопки +/−
- UI индикация: зеленый badge "В корзине" (свой), красный "Занят" (чужой)

## Автоматизация (inventory/tasks.py):
- cleanup_expired_cart_locks: Celery periodic task (каждые 5 минут)
- Автоматическое освобождение истекших блокировок (30 минут timeout)
- Логирование очистки для мониторинга

## Маршруты (pos/urls.py):
- POST /api/showcase-kits/<id>/add-to-cart/ - создание блокировки
- POST /api/showcase-kits/<id>/remove-from-cart/ - снятие блокировки

## Документация:
- ЗАПУСК.md: инструкция по запуску Celery Beat

Преимущества:
✓ Предотвращает конфликты между кассирами
✓ Автоматическое освобождение при таймауте
✓ Понятный UX с визуальной индикацией
✓ Совместимость с существующей логикой резервирования

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 23:45:34 +03:00
ff0756498c Fix Product filtering and add kit disassembly functionality
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>
2025-11-20 23:03:47 +03:00
dd184265ee Add default showcase selection per warehouse
- Add is_default field to Showcase model with unique constraint per warehouse
- Implement Showcase.save() to ensure only one default per warehouse
- Add SetDefaultShowcaseView for AJAX-based default selection
- Update ShowcaseForm to include is_default checkbox
- Add interactive checkbox UI in showcase list with AJAX functionality
- Update POS API to return showcase.is_default instead of warehouse.is_default
- Update terminal.js to auto-select showcase based on its is_default flag
- Add migration for is_default field

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 11:40:08 +03:00
07c8819936 Add interactive customer selection to checkout modal
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>
2025-11-20 10:31:42 +03:00
763ad2ce07 Add styled +/- quantity controls to POS cart
Implemented intuitive quantity management in the cart with:
- Minus button (-): Decreases quantity by 1, removes item if qty becomes 0
- Plus button (+): Increases quantity by 1
- Quantity input field: Centered, uniform styling with buttons
- All controls styled with Bootstrap outline-secondary (gray) for cohesive look
- Buttons feature Bootstrap Icons (dash-circle, plus-circle) at 1.2em size
- Auto-save to Redis after each quantity change

Benefits:
 Faster quantity adjustments without keyboard input
 Consistent gray styling across all quantity controls
 Mobile-friendly touch targets
 Automatic cart persistence maintained

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 10:19:28 +03:00
eac778b06d Add Redis-based persistence for POS cart and customer selection
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>
2025-11-20 09:55:03 +03:00
755e4fc9d9 комит 2025-11-19 22:12:01 +03:00
b2a69fbc83 Reduce search debounce from 600ms to 300ms for better responsiveness 2025-11-17 16:37:58 +03:00
0db845b133 Add minimum 3 character requirement for POS search 2025-11-17 16:36:38 +03:00
99be95aab1 POS search improvements: clear button, 600ms debounce, empty screen on clear 2025-11-17 16:34:40 +03:00
4c66a6f8f4 Fix POS card display: show free qty (available-reserved) instead of available qty 2025-11-17 16:27:49 +03:00
c06e569cbd Server-side search in POS: instant search by name and SKU with debounce 300ms 2025-11-17 16:10:23 +03:00
42c6e086da Расширен поиск в POS: теперь ищет по названию и артикулу, по любой части, без учета регистра 2025-11-17 15:59:53 +03:00
cfae2fb5fb Реализована прогрессивная загрузка товаров в POS с пагинацией и infinite scroll. Первая загрузка только категорий и склада, товары подгружаются по 60 штук при клике на категорию с сортировкой по свободным остаткам (available-reserved) по убыванию. Добавлен API endpoint /pos/api/items/ с фильтрацией по категориям и пагинацией. Infinite scroll для догрузки следующих страниц. Lazy loading для изображений. 2025-11-17 14:43:49 +03:00
e23bdef679 Добавлено отображение остатков и резервов в карточках товаров POS
- Аннотация товаров остатками (available_qty) и резервами (reserved_qty) через Subquery
- Компактный формат отображения: X(−Y) где X - доступно, Y - зарезервировано
- Визуальная стилизация: крупное число для остатков, мелкое для резервов
- Цветовая индикация: зелёный (≥5), жёлтый (<5), красный (≤0)
- Без дополнительных SQL-запросов, оптимизировано через подзапросы
2025-11-17 14:03:31 +03:00
4961660b7a Реализован выбор склада для POS: добавлена логика выбора склада по умолчанию из сессии, эндпоинт смены склада, модалка выбора и отображение текущего склада 2025-11-17 13:17:38 +03:00
580003ec8b feat: оптимизация размера шрифта и межстрочного расстояния кнопок POS
- Уменьшен размер шрифта с 0.95rem до 0.85rem для лучшей читаемости
- Уменьшен line-height с 1.2 до 1.1 для компактного расположения текста
- Текст теперь полностью помещается внутри кнопок без выхода за границы
- Сохранена возможность переноса текста на две строки для кнопки 'Отложенный заказ'
2025-11-17 12:56:07 +03:00
eecc2f75cf style: разрешён перенос текста для кнопки Отложенный заказ
- Добавлено исключение для кнопки #scheduleLater
- Для этой кнопки white-space: normal вместо nowrap
- Текст переносится на две строки для лучшей читаемости
- Остальные кнопки остаются в одну строку
2025-11-17 12:52:34 +03:00
c79e20aee3 style: улучшен внешний вид кнопок в панели действий POS
- Увеличен размер шрифта кнопок с 0.75rem до 0.95rem
- Добавлен жирный шрифт (font-weight: 700)
- Изменено white-space с normal на nowrap для избежания переносов строк
- Убраны word-wrap: break-word (не нужен при nowrap)
- Кнопки теперь более читабельны на планшете
2025-11-17 12:51:43 +03:00
cefd6c98a2 feat: добавлено редактирование витринных комплектов и изолированное состояние tempCart
- Добавлены API endpoints для получения и обновления витринных комплектов
  - GET /pos/api/product-kits/<id>/ - получение деталей комплекта
  - POST /pos/api/product-kits/<id>/update/ - обновление комплекта
- Реализовано редактирование комплектов из POS интерфейса
  - Кнопка редактирования (карандаш) на карточках витринных букетов
  - Модальное окно предзаполняется данными комплекта
  - Поддержка изменения состава, цен, описания и фото
  - Умное управление резервами при изменении состава
- Введено изолированное состояние tempCart для модального окна
  - Основная корзина (cart) больше не затрагивается при редактировании
  - tempCart используется для создания и редактирования комплектов
  - Автоочистка tempCart при закрытии модального окна
- Устранён побочный эффект загрузки состава комплекта в основную корзину
2025-11-16 23:41:27 +03:00
9dff9cc200 feat: динамическая загрузка витринных комплектов в POS
- Добавлен API endpoint GET /pos/api/showcase-kits/ для получения актуальных витринных букетов
- Изменена переменная SHOWCASE_KITS на изменяемую showcaseKits
- Добавлена функция refreshShowcaseKits() для обновления данных с сервера
- Кнопка ВИТРИНА теперь загружает свежие данные перед отображением
- После создания временного букета автоматически обновляется список и переключается вид на витрину
- Исправлена проблема с отображением только что созданных витринных букетов
2025-11-16 23:08:34 +03:00
660c0cb97b feat(pos): Add kit icon indicator in cart
- Added Bootstrap icon (bi-box-seam) for kit items in POS cart
- Kits and showcase kits now display with blue icon for visual distinction
- Regular products remain without icons for cleaner look
- Maintains consistency with product list view styling
2025-11-16 21:42:03 +03:00
852bb92cfb feat(pos): Display showcase kits in POS interface
- 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
2025-11-16 21:36:55 +03:00
156f646252 Реализован функционал создания временных комплектов на витрину из POS
- Добавлен API endpoint для создания временного комплекта из корзины
- Реализован endpoint получения списка активных витрин
- Создано модальное окно для настройки комплекта и выбора витрины
- JavaScript логика: валидация корзины, отправка данных, очистка после успеха
- Автоматическая генерация названия комплекта с датой и временем
- Агрегация дубликатов товаров в корзине перед созданием
- Резервирование компонентов на витрину через ShowcaseManager
- Расчёт и отображение итоговой цены комплекта
2025-11-16 21:24:07 +03:00
8f6acfb364 Добавлена функциональность витрин для POS: модели, сервисы, UI
- Создана модель Showcase (витрина) привязанная к складу
- Расширена Reservation для поддержки витринных резервов
- Добавлены поля в OrderItem для маркировки витринных продаж
- Реализован ShowcaseManager с методами резервирования, продажи и разбора
- Обновлён админ-интерфейс для управления витринами
- Добавлена кнопка Витрина в POS (категории) и API для просмотра
- Добавлена кнопка На витрину в панели действий POS
- Миграции готовы к применению
2025-11-16 21:12:22 +03:00
e98bf3cfb4 Улучшен UI корзины: увеличена кнопка удаления товара и возвращено использование onchange для поля количества 2025-11-16 19:54:08 +03:00
cd1a123dcd Починили работу курсора 2025-11-16 19:52:27 +03:00
9669459920 мелкие улучшения 2025-11-16 19:42:01 +03:00
61595e31d4 Исправлен конфликт ID между товарами и комплектами в корзине, использован составной ключ type-id 2025-11-16 19:24:04 +03:00