- Передаем price_old[amount]="0" для сброса старой цены
- Добавлены флаги is_new и is_popular в маппер
- Добавлен debug логгер для отладки типов данных
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Реализован клиент для работы с API Recommerce, включая:
- Клиент с методами для работы с товарами и заказами
- Сервисный слой для высокоуровневых операций
- Мапперы данных между форматами
- Обработку исключений
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Добавлен endpoint /test/<integration_id>/ для тестирования соединений
- RecommerceService упрощён под реальное API (x-auth-token + store_url)
- Кнопка "Проверить подключение" в UI с обработкой статусов
- Миграция для удаления IntegrationConfig и обновления полей
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Удалена лишняя модель IntegrationConfig из system_settings
- Singleton-паттерн: одна запись на интеграцию с is_active тумблером
- Добавлено шифрование токенов (EncryptedCharField с Fernet AES-128)
- UI: тумблеры слева, форма настроек справа
- API endpoints: toggle, settings, form_data
- Модель Recommerce: store_url + api_token (x-auth-token)
- Модель WooCommerce: store_url + consumer_key/secret
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Создана структура marketplaces/ для маркетплейсов
- Модели: MarketplaceIntegration, WooCommerceIntegration, RecommerceIntegration
- Сервисы: MarketplaceService, WooCommerceService, RecommerceService
- RecommerceService содержит методы для работы с API:
- test_connection(), sync(), fetch_products()
- push_product(), update_stock(), update_price()
- IntegrationConfig обновлён с новой интеграцией
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Создано приложение integrations с базовой архитектурой
- BaseIntegration (абстрактная модель) для всех интеграций
- BaseIntegrationService (абстрактный сервисный класс)
- IntegrationConfig модель для тумблеров в system_settings
- Добавлена вкладка "Интеграции" в системные настройки
- Заготовка UI с тумблерами для включения интеграций
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Удален TenantAdminAccessMiddleware (избыточен — Django Admin уже проверяет is_staff)
- CustomUser.create_superuser теперь устанавливает is_staff=False (нет доступа к /admin/)
- PlatformAdmin с is_staff=True сохраняет доступ к админке
- Обновлен комментарий в onboarding.py
Доступ к /admin/ теперь контролируется стандартным механизмом Django Admin
через has_permission() + существующие authentication backends.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Добавлена кнопка копирования промокода в клипборд с визуальной обратной связью
- Улучшено отображение ошибок валидации в форме заказа (is-invalid класс)
- Добавлен флаг _draftFieldsFilled для корректной обработки пустого черновика
- Убран value="1" для quantity чтобы избежать конфликтов с draft-data
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Добавлен combine_mode в форму создания/редактирования скидок
- Добавлена колонка "Объединение" в список скидок с иконками
- Добавлен фильтр по режиму объединения скидок
- Добавлена валидация: только одна exclusive скидка на заказ
- Удалены дублирующие поля из Order и OrderItem:
- applied_discount, applied_promo_code, discount_amount
- Скидки теперь хранятся только в DiscountApplication
- Добавлены свойства для обратной совместимости
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>
При выборе способа оплаты \"Одним способом\" и вводе суммы меньше
полной стоимости заказа теперь показывается подтверждение с
предложением вернуться и выбрать смешанную оплату.
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>
- Заменен getCookie('csrftoken') на getCsrfToken() во всех fetch запросах
(checkAutoDiscounts, applyPromoCode, handleCheckoutSubmit и др.)
- Это исправляет ошибку 403 Forbidden, возникающую из-за CSRF_USE_SESSIONS=True
fix(discounts): исправлен фильтр товаров в CRUD скидок
- Изменен фильтр с is_active=True на status='active' для корректной
работы с моделью Product
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Добавлена вкладка "Скидки" в страницу настроек
- Созданы views для управления скидками и промокодами с проверкой прав:
* owner/manager/superuser - полный CRUD
* florist - только просмотр
* courier - нет доступа
- Созданы шаблоны: список скидок, форма, подтверждение удаления
- Созданы шаблоны: список промокодов, форма, подтверждение удаления
- Добавлены фильтры по типу, области действия, активности
- Добавлена пагинация
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Добавлен DiscountApplicationInline для просмотра истории скидок на странице заказа
- OrderAdmin: добавлены колонки subtotal_display и discount_display
- OrderAdmin: добавлен фильтр по applied_discount
- OrderAdmin: добавлена секция "Скидки" в fieldsets
- OrderItemInline: добавлено отображение скидки в inline
- OrderItemAdmin: добавлена колонка и фильтр по скидкам
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Интеграция системы скидок с моделями заказов:
Order:
- applied_discount: ForeignKey на Discount
- discount_amount: сумма скидки на заказ
- applied_promo_code: использованный промокод
- calculate_total(): обновлён с учётом скидки
OrderItem:
- applied_discount: ForeignKey на Discount
- discount_amount: сумма скидки на позицию
- get_total_price(): обновлён с учётом скидки
Миграция:
- 0003_order_applied_discount... добавляет новые поля
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Создано новое Django приложение для управления скидками:
Модели:
- BaseDiscount: абстрактный базовый класс с общими полями
- Discount: основная модель скидки (процент/фикс, на заказ/товар/категорию)
- PromoCode: промокоды для активации скидок
- DiscountApplication: история применения скидок
Сервисы:
- DiscountCalculator: расчёт скидок для корзины и заказов
- DiscountApplier: применение скидок к заказам (атомарно)
- DiscountValidator: валидация промокодов и условий
Админ-панель:
- DiscountAdmin: управление скидками
- PromoCodeAdmin: управление промокодами
- DiscountApplicationAdmin: история применения (только чтение)
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
Теперь создание заказов работает корректно в мультитенантной архитектуре.
- Add explicit date input format '%Y-%m-%d' to WriteOffDocumentForm and IncomingDocumentForm
- Disable localization for date fields to ensure yyyy-MM-dd format is used
- Set initial date value to current date in WriteOffDocumentCreateView's get_initial method
- Restrict warehouse queryset to active warehouses in forms initialization
- Improve date widget consistency by adding format parameter to DateInput widgets
- Move default date initialization from form to view initial data
- Add checks for DOM elements existence before event listener attachment
- Handle 'clear' mode in bulk category modal with confirmation and API call
- Improve CSRF token usage and error handling during bulk update requests
- Remove deprecated handleClearAll function and integrate logic into handleApply
- Reset modal state properly including input fields and radio button modes
- Update modal JS file version reference in products list template
- Add null check for selectAllCheckbox to avoid errors in batch-selection.js
- Replace clear existing categories toggle with radio buttons for add, replace, and clear modes
- Disable category search input and fade category list when 'clear' mode is selected
- Update mode hint text dynamically based on selected mode with explanatory messages
- Enable apply button when 'clear' mode is selected regardless of category selection
- Remove clear all categories button from modal footer
- Add event listeners for mode radio buttons to update UI and error states on change
- Initialize mode UI and apply button state on modal setup
- Bump static JS files versions for batch-selection and bulk-category-modal to 1.2 and 1.4 respectively
- CustomUser теперь наследуется от AbstractBaseUser (вместо AbstractUser)
- Удалены поля groups и user_permissions из CustomUser
- Все authentication backends (TenantUserBackend, PlatformAdminBackend, RoleBasedPermissionBackend) больше НЕ наследуются от ModelBackend
- Добавлены методы has_perm() и has_module_perms() в CustomUser для делегирования проверки прав кастомным backends
- Полная изоляция: CustomUser использует только систему ролей (UserRole), PlatformAdmin использует только is_superuser
- Удалён весь старый код, связанный с Django permissions
- Нет обратной совместимости (не требуется)
- Чистая архитектура для multi-tenant приложения
Проблема:
После первого исправления ошибка продолжалась, но теперь в другом месте.
Django's ModelBackend пытался проверить permissions для CustomUser через
Permission.objects.filter(group__user=user_obj), что вызывало ошибку
"Cannot query 'chupa@chus.by': Must be 'PlatformAdmin' instance"
Причина:
RoleBasedPermissionBackend наследует ModelBackend, и для CustomUser
все равно вызывался super().has_perm(), который обращался к Django
Permission таблице в public schema, ожидая PlatformAdmin.
Решение:
Полностью отключен вызов super().has_perm() и super().has_module_perms()
для CustomUser. Теперь для CustomUser используется только role-based
permission checking, а для PlatformAdmin - стандартный ModelBackend.
Изменения в user_roles/auth_backend.py:
- has_perm(): добавлена ветка if is_tenant, которая полностью обрабатывает
CustomUser без вызова super()
- has_module_perms(): аналогичная логика
- Для PlatformAdmin сохранена проверка через super() (ModelBackend)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Устранена ошибка ValueError "Cannot query 'email': Must be 'PlatformAdmin' instance"
при доступе CustomUser к странице /products/.
Проблема:
- Модели products (TENANT_APPS) использовали get_user_model() для ForeignKey
- get_user_model() возвращал PlatformAdmin (AUTH_USER_MODEL)
- Но tenant модели должны ссылаться на CustomUser (tenant пользователей)
- Это создавало конфликт типов при запросах от CustomUser
Изменения:
1. products/models/base.py:
- Убран get_user_model()
- BaseProductEntity.archived_by теперь ForeignKey('accounts.CustomUser')
2. products/models/categories.py:
- Убран get_user_model()
- ProductCategory.deleted_by теперь ForeignKey('accounts.CustomUser')
3. products/models/import_job.py:
- Убран get_user_model()
- ProductImportJob.user теперь ForeignKey('accounts.CustomUser')
4. Создана миграция 0002 с data migration:
- Очистка некорректных ссылок (установка NULL)
- Изменение типа ForeignKey полей с PlatformAdmin на CustomUser
5. user_roles/auth_backend.py:
- Добавлена функция _is_tenant_user() для проверки типа пользователя
- Исправлена логика has_perm() и has_module_perms()
- CustomUser теперь не проверяется через ModelBackend.has_perm()
6. admin_access_middleware.py:
- Улучшены сообщения об ошибках доступа
- Добавлен рендеринг через шаблон access_denied.html
7. templates/errors/access_denied.html:
- Новый шаблон для красивого отображения ошибок доступа
Результат:
- CustomUser может без ошибок работать со страницей /products/
- Корректная архитектура: tenant модели ссылаются на tenant пользователей
- PlatformAdmin продолжает работать корректно
- Чистое решение без костылей
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Platform support пользователь теперь создается с is_superuser=True для полного доступа
- Добавлено сохранение credentials (домен:логин:пароль) в support_credentials.txt
- Добавлен support_credentials.txt в .gitignore для безопасности
- Обновлена документация развертывания на NAS
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- ИНСТРУКЦИЯ_ОБНОВЛЕНИЕ.md:
* Усилено предупреждение о необходимости настройки прав после КАЖДОГО обновления
* Добавлены признаки проблемы: crash loop контейнера, 404 на тенантах
* Подчёркнута критичность выполнения chown/chmod
- DEPLOY_NAS.md:
* Добавлены команды chown/chmod в раздел 'Обновление приложения'
* Новый раздел 'Проблема 7': новый тенант возвращает 404
* Пошаговая диагностика: проверка домена в БД и логов контейнера
* Объяснение причины: контейнер падает из-за Permission denied
Теперь при проблемах после обновления кода пользователь сразу увидит,
что нужно проверить права доступа на файлы проекта.