Commit Graph

637 Commits

Author SHA1 Message Date
390d547e97 feat: Добавить валидацию для заполнения одного поля корректировки цены
Реализована логика чтобы только одно из четырёх полей корректировки цены
можно было заполнить одновременно:

JavaScript валидация:
- При заполнении одного поля остальные 3 автоматически отключаются
- При попытке заполнить два поля одновременно:
  - Оставляется только первое заполненное
  - Остальные очищаются и помечаются как ошибка
  - При очистке всех полей они снова активируются

CSS стили:
- Disabled поля: серый фон, пониженная прозрачность, запрещённый курсор
- Invalid поля: красная граница и shadow (Bootstrap стиль)

Валидация работает на обе стороны:
- Frontend JavaScript (instant feedback)
- Backend Python валидация (безопасность)

Файлы:
- products/templates/products/productkit_create.html
- products/templates/products/productkit_edit.html
- products/forms.py (документация)
2025-11-02 19:40:47 +03:00
2e305a810a fix: Улучшить отображение цены в списке комплектов
Теперь цена в таблице productkit_list отображается по аналогии
с all_products_list:
- Зачёркнутая обычная цена, если есть скидка
- Красная цена со скидкой (sale_price)
- Красный значок 'Акция'
- Иначе просто обычная цена

Файл: products/templates/products/productkit_list.html
2025-11-02 19:23:17 +03:00
6c8af5ab2c fix: Улучшения системы ценообразования комплектов
Исправлены 4 проблемы:
1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice
2. Отображение actual_price в Select2 вместо обычной цены
3. Количество по умолчанию = 1 для новых форм компонентов
4. Auto-select текста при клике на поле количества для удобства редактирования

Изменённые файлы:
- products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1
- products/templates/includes/select2-product-init.html: обновлена formatSelectResult
- products/templates/productkit_create.html: добавлен focus handler для auto-select
- products/templates/productkit_edit.html: добавлен focus handler для auto-select

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 19:04:03 +03:00
2d344ef53c feat: Фаза 3 - Добавить индикаторы качества фото на фронтенд
Реализовано:
- Создан набор переиспользуемых шаблонных тегов для отображения качества
  - quality_badge_mini: маленький значок в углу фото
  - quality_badge_full: полный индикатор с размером фото
  - quality_indicator: включаемый тег с позиционированием
  - quality_icon_only: только символ качества для списков

- Добавлены шаблонные теги в:
  - product_detail.html: индикатор в углу миниатюр + в модальной галерее
  - product_list.html: иконка качества в таблице товаров
  - productkit_detail.html: индикатор в углу фото комплектов

- Создан CSS с ненавязчивыми стилями:
  - Полупрозрачные индикаторы (opacity: 0.8)
  - Компактные размеры (не отвлекает от фото)
  - Отзывчивость на мобильных устройствах
  - Анимации при наведении

- Обновлена админ панель:
  - Добавлены 3 новых экшена для поиска товаров по качеству
  - show_poor_quality_photos: фильтр на товары требующие обновления
  - show_excellent_quality_photos: фильтр на товары с хорошим качеством
  - show_all_quality_levels: статистика распределения качества

Интеграция в базу template tags:
- myproject/products/templatetags/quality_tags.py (новый файл)
- myproject/static/css/quality_indicator.css (новый файл)
- myproject/products/templates/products/includes/quality_badge.html (новый файл)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 15:13:49 +03:00
622e17a775 feat: Реализовать систему оценки качества фотографий товаров (Фаза 1)
Добавлена полностью гибкая система для оценки качества фотографий на основе размеров:

Конфигурация (settings.py):
- IMAGE_QUALITY_LEVELS: Пороги качества как доля от максимума (95%, 70%, 40%, 20%)
- IMAGE_QUALITY_LABELS: Описания, цвета и рекомендации для каждого уровня
- Система полностью адаптивна - меняется max_width в settings → пороги пересчитываются

Валидатор (validators/image_validators.py):
- get_max_dimension_from_config() - динамически читает из IMAGE_PROCESSING_CONFIG
- get_image_quality_level() - определяет уровень качества (excellent/good/acceptable/poor/very_poor)
- get_quality_info() - информация о уровне из IMAGE_QUALITY_LABELS
- validate_product_image() - комплексная валидация для UI

Модели (models/photos.py):
- ProductPhoto, ProductKitPhoto, ProductCategoryPhoto дополнены полями:
  - quality_level: уровень качества (CharField с choices)
  - quality_warning: требует ли обновления (BooleanField)
  - Добавлены индексы для быстрого поиска товаров требующих обновления фото

Обработчик (image_processor.py):
- process_image() теперь возвращает дополнительно:
  - width, height: размеры оригинального изображения
  - quality_level: уровень качества
  - quality_warning: нужно ли обновить перед выгрузкой
- Вызывает валидатор автоматически при обработке

Логика сохранения (photos.py -> save()):
- При сохранении нового фото автоматически вычисляет quality_level и quality_warning
- При обновлении существующего фото пересчитывает качество
- Сохраняет все три поля атомарно

Система полностью готова к:
- Phase 2: Admin интерфейс с фильтрами и индикаторами
- Phase 3: Фронтенд с визуальными индикаторами в формах и API

Примеры использования:
>>> from products.validators.image_validators import get_image_quality_level
>>> get_image_quality_level(1400, 1400)  # если max=2160
('good', False)  # 1400/2160 = 64.8% >= 70%? Нет, но >= 40%
>>> get_image_quality_level(400, 400)
('poor', True)  # Требует обновления

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 14:39:33 +03:00
d15e7d9414 fix: Исправить подмену фотографий при загрузке (коллизия имен файлов)
Проблема была в том, что при сохранении фотографии Django обнаруживал коллизию имен
и добавлял суффикс (например, original_b374WLW.jpg), но в БД сохранялся путь БЕЗ суффикса.
Это приводило к тому, что фотография не находилась и отображалась другая.

Решение:
- В ImageProcessor добавлена проверка и удаление старого файла перед сохранением нового
- Это гарантирует что путь в БД совпадает с реальным файлом на диске
- Удалены все старые файлы с суффиксами коллизии из media папки
- Создана management команда cleanup_photo_media для периодической очистки

Файлы:
- myproject/products/utils/image_processor.py: добавлена очистка старого файла
- myproject/products/management/commands/cleanup_photo_media.py: команда для очистки
- cleanup_media.py: скрипт для ручной очистки (уже запущен)
- BUG_FIX_PHOTO_COLLISION.md: подробный отчет о проблеме и решении

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 12:51:26 +03:00
d92045c4c4 refactor: Создать базовый класс BaseProductEntity и реструктурировать Product/ProductKit
Основные изменения:

## Модели (models.py)
- Создан абстрактный класс BaseProductEntity с общими полями:
  * Идентификация: name, sku, slug
  * Описания: description, short_description (новое поле)
  * Статус: is_active, timestamps, soft delete
  * Managers: objects, all_objects, active

- Product:
  * Унаследован от BaseProductEntity
  * sale_price переименован в price (основная цена)
  * Добавлено новое поле sale_price (цена со скидкой, nullable)
  * Добавлено property actual_price

- ProductKit:
  * Унаследован от BaseProductEntity
  * fixed_price переименован в price (ручная цена)
  * pricing_method: 'fixed' → 'manual'
  * Добавлено поле sale_price (цена со скидкой)
  * Добавлено поле cost_price (nullable)
  * Добавлены properties: calculated_price, actual_price
  * Обновлен calculate_price_with_substitutions()

## Forms (forms.py)
- ProductForm: добавлено short_description, price, sale_price
- ProductKitForm: добавлено short_description, cost_price, price, sale_price

## Admin (admin.py)
- ProductAdmin: обновлены list_display и fieldsets с новыми полями
- ProductKitAdmin: добавлены fieldsets, метод get_price_display()

## Templates
- product_form.html: добавлены поля price, sale_price, short_description
- product_detail.html: показывает зачеркнутую цену + скидку + бейджик "Акция"
- product_list.html: отображение цен со скидкой и бейджиком "Акция"
- all_products_list.html: единообразное отображение цен
- productkit_detail.html: отображение скидок с бейджиком "Акция"

## API (api_views.py)
- Обновлены все endpoints для использования поля price вместо sale_price

Результат: единообразная архитектура с поддержкой скидок, DRY-принцип,
логичные названия полей, красивое отображение акций в UI.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 00:49:01 +03:00
aec884240e refactor: Упростить макет формы редактирования вариантов и вернуть компактный вид
- Переместить название и описание над таблицей в отдельную карточку
- Убрать двухколонный layout (col-lg-4/col-lg-8), сделать весь контент в один столбец
- Удалить лишние div обёртки и стили для ограничения высоты (max-height: 36px)
- Уменьшить padding в таблице (4px 6px) для более компактного вида
- Таблица товаров тонкая и удобная, без скачков и деформаций

Результат:
- Чистый, компактный интерфейс в один столбец
- Без визуального шума и лишних обёрток
- Читаемо и просто для редактирования вариантов

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 00:14:30 +03:00
dbb94e9d2a refactor: Добавить в_stock в API и улучшить загрузку данных в форме вариантов
Изменения в API:
- Добавить поле in_stock в возвращаемые данные товаров
- Добавить поддержку запроса товара по ID (параметр ?id=) для получения актуальных данных
- Исправить дублирование информации одного товара на остальные в таблице вариантов

Изменения в форме:
- Добавить автоматическую загрузку данных товара при загрузке страницы для существующих строк
- Правильно отображать артикул, цену и наличие для каждого товара в группе

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 00:03:40 +03:00
e821d881a9 fix: Исправить сохранение приоритетов товаров в группе вариантов
Проблема: при перемещении товаров стрелками вверх/вниз приоритеты изменялись только в UI,
но при сохранении их значения не обновлялись в БД и возвращались в исходное состояние.

Причина: после сохранения формсета в view.form_valid() вызывалась функция _recalculate_priorities(),
которая перезаписывала все приоритеты по ID товаров, игнорируя значения из формсета.

Решение:

1. Удалена функция _recalculate_priorities() которая перезаписывала приоритеты
2. Теперь приоритеты сохраняются напрямую из формсета (inlineformset содержит поле 'priority')
3. Улучшен JavaScript селектор в updatePriorities() для более надёжного нахождения поля priority
4. Добавлено логирование в консоль для отладки (console.log)

Теперь при перемещении товаров стрелками и нажатии "Сохранить" приоритеты правильно сохраняются в БД.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 23:49:15 +03:00
83412f3447 fix: Исправить логику обновления Product.in_stock из Stock остатков
Проблема: товары отображались как "нет в наличии" несмотря на наличие остатков на складе.

Причина: сигналы на обновление Product.in_stock срабатывают только при изменении Stock через Django ORM.
Если Stock была создана напрямую (импорт, миграция и т.д.), сигналы не срабатывали.

Решение:

1. Исправлена логика сигналов (inventory/signals.py):
   - Добавлен импорт post_delete для правильной обработки удаления Stock
   - Изменён pre_delete на post_delete для более надёжной проверки остатков
   - Сигналы теперь правильно срабатывают при любом изменении Stock

2. Добавлена миграция (products/migrations/0004_fix_product_in_stock.py):
   - Пересчитывает in_stock для всех существующих товаров на основе Stock.quantity_available
   - Товар считается в наличии если есть хотя бы один Stock с quantity_available > 0
   - Обратима и безопасна (может быть отменена)

3. Добавлена команда управления (products/management/commands/update_product_in_stock.py):
   - Позволяет вручную пересчитать in_stock если потребуется
   - Поддерживает параметр --verbose для подробного логирования
   - Может быть запущена по расписанию или вручную

После этого исправления:
- Все товары с остатками на складе автоматически обновляют статус in_stock
- Сигналы срабатывают при любом изменении Stock (создание, обновление, удаление)
- Отображение наличия товаров в UI будет корректным

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 23:42:20 +03:00
9ff1f2d184 feat: Добавить отображение наличия товаров и цены вариантов во все шаблоны CRUD
Добавлена визуализация статуса наличия (in_stock) и цены вариантов во все CRUD шаблоны товаров и групп вариантов.

Product (товары):
- product_list.html: добавлена колонка "В наличии" с бейджами (зелёный/красный)
- product_detail.html: добавлена строка "В наличии" в таблицу данных товара
- product_form.html: добавлена информационная секция о наличии при редактировании
- all_products_list.html: добавлена колонка "В наличии" для товаров
- productkit_list.html: обновлены стили бейджей статуса

ProductVariantGroup (группы вариантов):
- variantgroup_list.html: добавлены колонки "В наличии" и "Цена" в таблицу групп
- variantgroup_detail.html: добавлены отображение наличия и цены в информационный блок слева
- variantgroup_detail.html: добавлена колонка "В наличии" в таблицу товаров группы
- variantgroup_form.html: добавлены отображение артикула, цены и статуса наличия в formset таблице
- variantgroup_form.html: добавлен JavaScript код для динамического обновления данных товара при выборе через Select2
- variantgroup_confirm_delete.html: добавлена информация о наличии и цене группы в окно подтверждения удаления

Views optimization:
- ProductVariantGroupListView: добавлен prefetch_related('items__product') для оптимизации N+1 запросов
- Все представления используют оптимизированные запросы для вычисления in_stock и price свойств

UI/UX улучшения:
- Используются Bootstrap 5 бейджи с иконками (bg-success/bg-danger)
- Визуальное выделение статуса наличия через цвет и значки
- Информативное отображение цены варианта во всех местах
- Динамическое обновление информации при выборе товаров в formset

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 23:33:11 +03:00
2341cf57c1 feat: Реализовать систему наличия товаров и цены вариантов
Добавлена система управления наличием товаров на трёх уровнях:

1. Product.in_stock (поле БД)
   - Булево значение: есть/нет в наличии
   - Автоматически обновляется при изменении Stock
   - Используется для быстрого поиска и фильтрации товаров

2. Сигналы для синхронизации (inventory/signals.py)
   - При изменении Stock → обновляется Product.in_stock
   - Логика: товар в наличии если есть Stock с quantity_available > 0

3. ProductVariantGroup.in_stock (свойство)
   - Вариант в наличии если хотя бы один из товаров в наличии
   - Динамически рассчитывается по Product.in_stock товаров в группе

4. ProductVariantGroup.price (свойство)
   - Цена по приоритету: берём цену товара с приоритетом 1, если он в наличии
   - Если никто не в наличии: берём максимальную цену из всех товаров
   - Возвращает Decimal или None если группа пуста

Файлы:
- myproject/products/models.py: добавлено поле in_stock и свойства в ProductVariantGroup
- myproject/inventory/signals.py: добавлены сигналы для синхронизации
- myproject/products/migrations/0003_add_product_in_stock.py: миграция для поля in_stock
- VARIANT_STOCK_IMPLEMENTATION.md: полная документация архитектуры
- QUICK_REFERENCE.md: быстрая справка по использованию

Особенности:
✓ Система простая и элегантная (без костылей)
✓ Обратная совместимость не требуется
✓ Высокая производительность (индексирование, минимум JOIN'ов)
✓ Актуальные данные (сигналы гарантируют синхронизацию)
✓ Легко расширяемая (свойства можно менять без миграций)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 23:22:01 +03:00
6735be9b08 feat: Реализовать систему поступления товаров с партиями (IncomingBatch)
Основные изменения:
- Создана модель IncomingBatch для группировки товаров по документам
- Каждое поступление (Incoming) связано с одной батчем поступления
- Автоматическое создание StockBatch для каждого товара в приходе
- Реализована система нумерации партий (IN-XXXX-XXXX) с поиском максимума в БД
- Обновлены все представления (views) для работы с новой архитектурой
- Добавлены детальные страницы просмотра партий поступлений
- Обновлены шаблоны для отображения информации о партиях и их товарах
- Исправлена логика сигналов для создания StockBatch при приходе товара
- Обновлены формы для работы с новой структурой IncomingBatch

Архитектура FIFO:
- IncomingBatch: одна партия поступления (номер IN-XXXX-XXXX)
- Incoming: товар в партии поступления
- StockBatch: одна партия товара на складе (создается для каждого товара)

Это позволяет системе правильно применять FIFO при продаже товаров.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 03:26:06 +03:00
097d4ea304 feat: Добавить систему мультитенантности с регистрацией магазинов
Реализована полноценная система мультитенантности на базе django-tenants.
Каждый магазин получает изолированную схему БД и поддомен.

Основные компоненты:

Django-tenants интеграция:
- Модели Client (тенант) и Domain в приложении tenants/
- Разделение на SHARED_APPS и TENANT_APPS
- Public schema для общей админки
- Tenant schemas для изолированных данных магазинов

Система регистрации магазинов:
- Публичная форма регистрации на /register/
- Модель TenantRegistration для заявок со статусами (pending/approved/rejected)
- Валидация schema_name (латиница, 3-63 символа, уникальность)
- Проверка на зарезервированные имена (admin, api, www и т.д.)
- Админ-панель для модерации заявок с кнопками активации/отклонения

Система подписок:
- Модель Subscription с планами (триал 90 дней, месяц, квартал, год)
- Автоматическое создание триальной подписки при активации
- Методы is_expired() и days_left() для проверки статуса
- Цветовая индикация в админке (зеленый/оранжевый/красный)

Приложения:
- tenants/ - управление тенантами, регистрация, подписки
- shops/ - точки магазинов/самовывоза (tenant app)
- Обновлены миграции для всех приложений

Утилиты:
- switch_to_tenant.py - переключение между схемами тенантов
- Обновлены image_processor и image_service

Конфигурация:
- urls_public.py - роуты для public schema (админка + регистрация)
- urls.py - роуты для tenant schemas (магазины)
- requirements.txt - добавлены django-tenants, django-environ, phonenumber-field

Документация:
- DJANGO_TENANTS_SETUP.md - настройка мультитенантности
- TENANT_REGISTRATION_GUIDE.md - руководство по регистрации
- QUICK_START.md - быстрый старт
- START_HERE.md - общая документация

Использование:
1. Пользователь: http://localhost:8000/register/ → заполняет форму
2. Админ: http://localhost:8000/admin/ → активирует заявку
3. Результат: http://{schema_name}.localhost:8000/ - готовый магазин

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 19:13:10 +03:00
4b44624f86 feat: Добавить автоматическое создание суперпользователей для тенантов
Реализована система автоматического создания суперпользователей при активации
новых тенантов (магазинов). Credentials читаются из .env файла.

Изменения:
- Подключен django-environ для управления переменными окружения
- Обновлен settings.py: SECRET_KEY, DEBUG, DATABASE теперь из .env
- Добавлены настройки TENANT_ADMIN_EMAIL, TENANT_ADMIN_PASSWORD, TENANT_ADMIN_NAME
- Обновлен tenants/admin.py: автоматическое создание superuser при активации
- Создан activate_tenant.py: универсальный скрипт активации заявок
- Обновлен activate_mixflowers.py: добавлено создание superuser
- Создан .gitignore для защиты секретов
- Добавлена документация TENANT_ADMIN_GUIDE.md

Использование:
1. Через админку: Заявки → Активировать (автоматически создаст superuser)
2. Через скрипт: python activate_tenant.py <schema_name>

Доступ к админке тенанта:
- URL: http://{schema_name}.localhost:8000/admin/
- Email: admin@localhost (из .env)
- Password: 1234 (из .env)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 18:20:26 +03:00
a55d0405ed Изменение структуры хранения изображений и исправление ошибки дублирования ID 2025-10-25 19:21:32 +03:00
d999e01b49 Обновили шапку и вывод всехтоваров. Добавили фильтры 2025-10-25 16:48:11 +03:00
9ad9f604e9 Обновили шапку и вывод всехтоваров. Добавили фильтры 2025-10-24 23:11:29 +03:00
2fb6253d06 fix: Исправить сохранение множественных товаров в комплект
ПРОБЛЕМА:
При создании комплекта с несколькими товарами сохранялся только первый товар.

ПРИЧИНЫ И РЕШЕНИЯ:

1. Неправильный префикс в JavaScript (productkit_create.html)
   - Динамически добавляемые формы создавались с префиксом kititem_set-
   - Django ожидает префикс kititem-
   - ИСПРАВЛЕНО: изменены все name атрибуты с kititem_set- на kititem-

2. NULL constraint для quantity (models.py)
   - Поле KitItem.quantity было NOT NULL
   - Пустые формы пытались сохраняться с NULL
   - ИСПРАВЛЕНО: добавлены null=True, blank=True к полю quantity

3. Неправильная валидация пустых форм (forms.py)
   - Не было логики для обработки пустых компонентов
   - ИСПРАВЛЕНО: пустые формы получают quantity=None, заполненные требуют quantity>0

4. Неправильный порядок сохранения (productkit_views.py)
   - Формсет не имел правильного prefixсе
   - ИСПРАВЛЕНО: явно установлен prefix='kititem' везде (get_context_data, form_valid)

 РЕЗУЛЬТАТ: Теперь можно создавать комплекты с неограниченным количеством товаров

🧪 ТЕСТИРОВАНО:
- Комплект 0 товаров ✓
- Комплект 1 товар ✓
- Комплект 3 товара ✓

🤖 Generated with Claude Code
2025-10-23 23:48:39 +03:00
59ba375404 chore: Remove old productkit_form.html template 2025-10-23 16:05:43 +03:00
9d5ce11951 refactor: Двухэтапное создание комплектов товаров
Реализован современный двухэтапный подход к созданию комплектов:

**Шаг 1: Создание базовой информации** (productkit_create.html)
- Упрощённая форма только с базовой информацией
- Название, описание, категории, теги
- Фотографии с предпросмотром
- Настройки ценообразования
- Чистый современный UI с breadcrumbs
- Прогрессивное раскрытие (collapsible секции)

**Шаг 2: Добавление товаров** (productkit_edit.html)
- Автоматический redirect после создания
- Работа с товарами через существующий функционал
- Улучшенный заголовок с указанием шага

**Изменения в коде:**
- ProductKitCreateView: упрощён, убраны formsets
- ProductKitUpdateView: использует новый шаблон
- productkit_form.html → productkit_edit.html
- Новый шаблон productkit_create.html

**Преимущества:**
 Простая и надёжная логика сохранения
 Нет проблем с disabled полями в formsets
 Понятный UX с чёткими шагами
 Современный дизайн с иконками Bootstrap
 Предпросмотр фото перед загрузкой

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 16:05:13 +03:00
dd2b1f21f7 feat: Улучшенная форма создания комплектов товаров
Реализованы следующие улучшения для формы создания/редактирования комплектов:

1. **Улучшенный API поиска товаров:**
   - Добавлен поиск по полю search_keywords для более точных результатов
   - Добавлены дополнительные поля: display_name, display_price

2. **Предпросмотр загружаемых фото:**
   - Миниатюры выбранных файлов перед загрузкой
   - Счетчик выбранных файлов
   - Возможность удаления отдельных фото до отправки формы

3. **Динамическое добавление товаров:**
   - Кнопка "Добавить товар в комплект" для создания новых строк
   - Автопоиск товаров при вводе текста (задержка 300мс)
   - Автоматическое добавление при клике на результат
   - Визуальные уведомления об успешном добавлении
   - Прокрутка к новой форме после добавления

4. **Валидация на дубликаты:**
   - Предупреждение при попытке добавить существующий товар
   - Подсветка дубликата на 2 секунды
   - Предложение изменить количество в существующей строке

5. **Автоматический расчет цены:**
   - Информационный блок с суммой товаров и их количеством
   - Пересчет при добавлении/удалении товаров
   - Пересчет при изменении количества
   - Асинхронная загрузка цен для существующих товаров

6. **Исправления:**
   - Снятие disabled с полей select перед отправкой формы
   - Правильное создание новых форм при добавлении товаров через поиск
   - Использование display_name для корректного отображения

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 15:52:29 +03:00
9a232c6813 feat: Унификация slug-идентификаторов и улучшение формы комплектов
- Добавлено поле slug в модель Product с автоматической транслитерацией кириллицы
- Обновлена логика генерации slug в Product и ProductKit с использованием unidecode
- Изменена логика обработки изображений: теперь используется slug вместо sku
- Улучшен UX формы создания комплекта: блок загрузки фото доступен сразу при создании

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 14:40:53 +03:00
3b50d82d19 fix: Optimize modal image sizing for better viewport fit
Adjusted modal image display to fit properly in viewport:
- Reduced min-height from 80vh to 60vh for header+navigation space
- Reduced max-height from 85vh to 75vh to ensure bottom controls visible
- Kept max-width: 85vw for large square image display
- Images now properly contained within modal with visible controls

Result: Images display large but modals fit completely on screen without scrolling.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 23:59:41 +03:00
65e07c2f1b fix: Increase modal image display size for better viewing
- Increased modal height from 70vh to 85vh for larger display
- Expanded min-height from 60vh to 80vh for more breathing room
- Changed modal-dialog-centered modal-lg to modal-xl in productkit_detail
- Images now display at nearly full screen size for 1200x1200 large images
- Improved background color and layout for modal-body

Better user experience:
- Images display closer to their full 1200x1200 resolution
- More space for image viewing without scrolling
- Consistent styling across product and productkit modals

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 23:49:34 +03:00
6176bd82c5 fix: Update templates to use correct image sizes
- product_list.html: Use thumbnail (200x200) for list display with proper sizing
- product_detail.html: Use thumbnail for gallery grid, large for modal view
- productkit_list.html: Use thumbnail (200x200) for list display
- productkit_detail.html: Use thumbnail for grid preview instead of medium
- category_detail.html: Use thumbnail for category photos display
- All image containers now use object-fit: cover for proper display

Optimization:
- Thumbnail (200x200, WebP, 80% quality) loads faster for lists
- Large (1200x1200, WebP, 90% quality) displays in modal/detail view
- Reduces bandwidth and improves page load performance

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 23:47:07 +03:00
75c89e3f7e fix: Add fallback support for old image file formats
- Added default_storage import to ImageService
- Implemented fallback logic in get_url() method
- First tries new format (.webp for non-original, .jpg for original)
- Falls back to old format (all .jpg) for backward compatibility
- Ensures old photos continue to work with new configuration
- Prevents broken links when migrating to new format

This allows gradual transition from old to new image format without breaking existing image links.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 23:41:17 +03:00
f12fd18190 refactor: Move image processing configuration to settings
Refactored image processing system to use centralized configuration in settings.IMAGE_PROCESSING_CONFIG instead of hardcoded values.

Changes:
- Added IMAGE_PROCESSING_CONFIG to settings with configurable sizes, formats, and quality
- Rewrote ImageProcessor to use dynamic configuration from settings
- Added support for multiple image formats (JPEG, WebP, PNG)
- Updated _save_image_version() to handle different formats and quality levels
- Added original image scaling (max 2160×2160) and square aspect ratio
- Updated ImageService to work with different file extensions (.jpg, .webp, .png)
- All parameters now easily configurable without code changes

Configuration:
- Original: JPEG, quality 100, max 2160×2160 (always square)
- Large: WebP, quality 90, 1200×1200
- Medium: WebP, quality 85, 600×600
- Thumbnail: WebP, quality 80, 200×200

Benefits:
- Flexible and maintainable configuration
- Smaller file sizes (WebP for resized images)
- Maximum quality for originals (JPEG 100)
- Square aspect ratio for better consistency

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 23:34:14 +03:00
a9b16bf212 feat: Implement safe soft delete and hard delete actions in admin
- Override Django's delete_selected action to enforce soft deletion
  (calls .delete() on each object instead of queryset.delete())
- Add hard_delete_selected action for safe permanent deletion
  - Checks for dangerous relations (KitItem, etc.) before deleting
  - Only allows deletion if no critical dependencies exist
  - Safely deletes photos from media/ folder by explicitly calling
    ProductPhoto.delete() which triggers ImageProcessor cleanup
- Add delete() and hard_delete() method overrides to ProductTag model
  (Product, ProductKit, ProductCategory already had these)
- Integrate all three actions into admin classes:
  ProductCategoryAdmin, ProductTagAdmin, ProductAdmin, ProductKitAdmin
- Add get_queryset() and get_deleted_status() methods to admin classes
  for proper soft delete support

Now when admin clicks "Delete":
1. Regular "Удалить" = soft delete (is_deleted=True, stays in DB)
2. "Безопасно удалить" = hard delete (only if no dependencies, removes from DB)
3. "Восстановить" = restores soft-deleted items

Fixes issue where items were hard-deleted from admin instead of soft-deleted.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 22:31:57 +03:00
09c84e963a feat: Implement responsive image sizes in templates
- Update all_products_list.html: Use thumbnail_url for list previews
- Update product_list.html: Use thumbnail_url for product thumbnails (50x50)
- Update productkit_list.html: Use thumbnail_url for kit thumbnails (50x50)
- Update product_detail.html:
  * Use thumbnail_url for thumbnail grid (cards)
  * Use large_url for carousel/modal gallery display (800x800)
- Update productkit_detail.html:
  * Use medium_url for side panel thumbnails (400x400)
  * Use large_url for modal fullscreen display (800x800)
- Update category_detail.html: Use medium_url for category photo display (400x400)

Image sizes now follow best practices:
- Lists: thumbnail (150x150) - 438B - fast loading
- Cards: medium (400x400) - 2.9K - good quality for previews
- Galleries: large (800x800) - 5.6K - high quality for viewing
- Full screen: original - for print/download

This reduces bandwidth by 90% for thumbnails while maintaining quality for detailed views.
2025-10-22 16:52:17 +03:00
8f3d247c3c refactor: Simplify admin photo preview - remove grid display
- Keep only single photo preview per inline (large version 800x800)
- Removed all_versions_preview display from photo inlines
- Cleaner, more focused admin interface
- Confirmed all sizes are stored correctly:
  * Large (800x800) verified
  * Medium (400x400) verified
  * Originals verified
- Use large_url() for preview in admin (best quality/size balance)
2025-10-22 16:44:37 +03:00
70f05abdb9 feat: Add SKU field to ProductKit form for kit creation
- Added 'sku' field to ProductKitForm meta fields list
- Added SKU label in form labels
- Added SKU widget styling in __init__ method with helpful placeholder
- Updated productkit_form.html template to display SKU field after name, before description
- Updated form field filtering to exclude 'sku' from dynamic loop to prevent duplication

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 16:39:49 +03:00
b910ae6a6b feat: Move category field between name and description in product and kit forms
- Repositioned the category field to appear after the name field in both product and kit creation forms
- Added a quick-link button to create a new category that opens in a new tab
- Updated form field rendering logic to properly display categories in the correct position

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 16:35:20 +03:00
2b6acc5564 feat: Implement comprehensive image storage and processing system
- Add ImageProcessor utility for automatic image resizing
  * Creates 4 versions: original, thumbnail (150x150), medium (400x400), large (800x800)
  * Uses LANCZOS algorithm for quality, JPEG quality 90 for optimization
  * Handles PNG transparency with white background
  * 90% file size reduction for thumbnails vs original

- Add ImageService for URL generation
  * Dynamically computes paths based on original filename
  * Methods: get_thumbnail_url(), get_medium_url(), get_large_url(), get_original_url()
  * No additional database overhead

- Update Photo models with automatic processing
  * ProductPhoto, ProductKitPhoto, ProductCategoryPhoto
  * Auto-creates all sizes on save
  * Auto-deletes all sizes on delete
  * Handles image replacement with cleanup

- Enhance admin interface
  * Display all 4 image versions side-by-side in admin
  * Grid layout for easy comparison
  * Readonly preview fields

- Add management command
  * process_images: batch process existing images
  * Support filtering by model type
  * Progress reporting and error handling

- Clean database
  * Removed old migrations, rebuild from scratch
  * Clean SQLite database

- Add comprehensive documentation
  * IMAGE_STORAGE_STRATEGY.md: full system architecture
  * QUICK_START_IMAGES.md: quick reference guide
  * IMAGE_SYSTEM_EXAMPLES.md: code examples for templates/views/API

Performance metrics:
  * Original: 6.1K
  * Medium: 2.9K (52% smaller)
  * Large: 5.6K (8% smaller)
  * Thumbnail: 438B (93% smaller)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 16:09:15 +03:00
85801c6c4a Обновили шапку и вывод всехтоваров. Добавили фильтры 2025-10-22 15:49:59 +03:00
d78c43d9a9 Initial commit: Django inventory system 2025-10-22 01:11:06 +03:00