Изменения:
- Фильтры теперь расположены горизонтально в одной строке над таблицей
- Кнопка "Создать заказ" перенесена в правый верхний угол рядом с заголовком
- Календарный фильтр дат вынесен во вторую строку для лучшей читаемости
- Убрана двухколоночная компоновка, таблица теперь занимает всю ширину
- Улучшена компактность интерфейса - больше места для таблицы данных
Преимущества новой компоновки:
- Таблица заказов использует всю ширину экрана
- Фильтры компактно организованы сверху
- Улучшена видимость данных
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Основные изменения:
- Установлен и настроен django-filter==24.3
- Создан OrderFilter с фильтрами по дате доставки, статусу, типу, оплате и поиску
- Реализован переиспользуемый компонент календарного фильтра date_range_filter.html
- Добавлены быстрые кнопки выбора дат (Сегодня, Завтра, Неделя)
- Создан templatetag param_replace для сохранения фильтров при пагинации
- Обновлен order_list view для использования django-filter
- Полностью переработан шаблон order_list.html с интеграцией фильтров
- Добавлены стили (date_filter.css) и логика (date_filter.js) для календаря
Структура новых файлов:
- orders/filters.py - FilterSet для заказов
- orders/templatetags/filter_tags.py - кастомные теги для фильтров
- orders/templates/orders/components/date_range_filter.html - компонент календаря
- orders/static/orders/css/date_filter.css - стили
- orders/static/orders/js/date_filter.js - JavaScript логика
- requirements.txt - зависимости проекта
Преимущества:
- Чистая архитектура фильтрации
- Автоматическое сохранение параметров при навигации
- Переиспользуемый календарный компонент
- Улучшенный UX с быстрыми фильтрами
- Готовность к масштабированию на другие модели
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Заказы:
- Добавлены миграции для исторических записей с полями оплаты и получателя
- Расширен admin для заказов с инлайнами товаров/комплектов
- Реализованы представления списка, создания, редактирования и удаления заказов
- Добавлен шаблон подтверждения удаления заказа
- Настроены URL-маршруты для работы с заказами
Клиенты:
- Добавлена миграция с новыми полями адресов и подтверждений
- Обновлена модель клиентов с дополнительными полями
- Улучшен admin для работы с клиентами
Товары:
- Значительно улучшен API поиска товаров с поддержкой фильтрации
- Добавлен Select2 виджет для динамического поиска товаров
- Создан статический JS файл для интеграции Select2
- Оптимизирована обработка запросов и ответов API
Прочее:
- Добавлены новые настройки в settings.py
- Обновлена навигация в navbar.html
- Обновлены URL-маршруты проекта
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Изменена структура страницы /orders/:
- Создана двухколоночная компоновка (фильтры слева, таблица справа)
- Кнопка "Создать заказ" перенесена из верхней части под фильтры в левую панель
- Фильтры преобразованы в вертикальный макет для лучшей организации
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Добавлено поле is_custom_price в модель OrderItem для отслеживания ручных изменений
- Добавлены свойства original_price и price_difference для отображения оригинальной цены и разницы
- Поле цены теперь редактируемое (убран атрибут readonly)
- Добавлены визуальные индикаторы: бейдж "Изменена" и информация об оригинальной цене
- JavaScript автоматически отслеживает изменения цены и устанавливает флаг is_custom_price
- В детальном просмотре заказа показывается информация о кастомных ценах с разницей
- Цена товара в каталоге не изменяется - изменения только для конкретного заказа
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Улучшения:
- Исправлена отображение цены в таблице вариантов: заменено sale_price на actual_price
чтобы правильно обрабатывать случаи когда скидка не установлена
- Оптимизирован property in_stock: вычисляется в памяти из prefetched данных
вместо отдельного запроса EXISTS к БД
- Оптимизирован property price: использует actual_price (sale_price или price)
вместо только sale_price, добавлена документация о требовании prefetch_related
- Оптимизирован DetailView.get_context_data: используется кешированный
prefetch_related вместо создания нового queryset для items
- Исправлена AJAX функция _get_items_data: использует actual_price вместо sale_price
Результат:
- Исчезла проблема с выводом "None" вместо цены
- Сокращено количество запросов к БД с 4-5 до 3 для страницы detail
- Улучшена производительность при работе с группами вариантов
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Удалено поле примечание из JavaScript шаблонов в:
- productkit_create.html (строки 797-802)
- productkit_edit.html (строки 813-818)
Эти шаблоны используются при динамическом добавлении нового товара в комплект
через кнопку 'Добавить товар'.
Раньше это поле было скрыто в обычном template include, но осталось в JS коде,
что приводило к отображению примечания при добавлении нового товара.
Теперь поле примечания полностью удалено из всех частей приложения.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Удалено ненужное поле 'notes' из формы создания/редактирования комплектов:
- Удалено из модели KitItem
- Удалено из формы KitItemForm
- Удалено из template kititem_formset.html
- Удалено из formset'ов KitItemFormSetCreate и KitItemFormSetUpdate
- Создана миграция БД для удаления поля из базы данных
Теперь каждый товар в комплекте отображается с 4 полями:
- Товар (или Группа вариантов)
- Количество
- Кнопка удаления
- ID (скрытое)
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Документ STATUS_RACE_CONDITION_FIX.md содержит:
- Краткое резюме проблемы и решения
- Контрольный список перед использованием
- Метрики улучшения (надёжность 10% → 99%+)
- Инструкции по тестированию (минимальный и полный)
- Git информацию и историю коммитов
- Что дальше и как получить помощь
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлены три документа:
1. FINAL_FIX_SUMMARY.md - Финальное резюме исправления
2. ADJUSTMENT_VALUE_FIX_TESTING.md - План тестирования и проверки
3. TECHNICAL_RACE_CONDITION_FIX.md - Глубокий технический анализ проблемы и решения
Документы включают:
- Описание проблемы и решения
- Пошаговый план тестирования (4 сценария)
- Анализ race condition на примере JS event loop
- Трёхуровневая защита от race condition
- Логирование для отладки
- Сравнение подходов синхронизации
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Исправлена критическая проблема, когда сохранённые значения корректировки цены не отображались
надёжно на странице редактирования (отображались только в 1 из 10 случаев).
Причина проблемы:
- При загрузке значений в поля input, срабатывают события input/change
- Эти события вызывают calculateFinalPrice() и validateSingleAdjustment()
- calculateFinalPrice() перезаписывает скрытые поля со значениями по умолчанию
Решение:
- Добавлен флаг isLoadingAdjustmentValues для подавления событий input/change
- Во время загрузки значений: флаг = true, события игнорируются
- После загрузки: флаг = false, события обрабатываются нормально
- Использование requestAnimationFrame для более надёжной синхронизации
Файлы изменены:
- productkit_edit.html (добавлены флаги и логика подавления событий)
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Скрытые поля для price_adjustment_type и price_adjustment_value
имели жёсткие значения по умолчанию (none и 0) вместо значений из модели.
При редактировании комплекта скрытые поля теперь заполняются
текущими значениями из БД через {{ form.FIELD.value }}.
Теперь JavaScript может правильно загрузить сохранённые значения
и заполнить соответствующие input поля (увеличить %, руб, уменьшить %, руб).
Файл: products/templates/products/productkit_edit.html
При редактировании комплекта поля корректировки цены остаются пустыми,
хотя в БД сохранены корректные значения (price_adjustment_type и value).
Исправлено:
1. Добавлен вызов validateSingleAdjustment() после заполнения полей
- Это отключает остальные поля и помечает валидные
- Реализует логику одного заполненного поля
2. Добавлено логирование в консоль браузера для отладки:
- Показывает какие значения загружены из БД
- Помогает выявить проблемы
Теперь при редактировании:
- Если есть сохранённая корректировка, она отображается
- Остальные поля автоматически отключаются
- Пересчитывается финальная цена
Файл: products/templates/products/productkit_edit.html
Был вызов KitValidator.validate_pricing_method_availability() который
пытался получить атрибут cost_calculation_info - это часть старой
системы ценообразования которая была заменена на новую.
Новая система не требует этой сложной валидации так как просто
вычисляет цену как сумму actual_price компонентов + опциональная корректировка.
Файл: products/views/productkit_views.py
Реализована логика чтобы только одно из четырёх полей корректировки цены
можно было заполнить одновременно:
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 (документация)
Теперь цена в таблице productkit_list отображается по аналогии
с all_products_list:
- Зачёркнутая обычная цена, если есть скидка
- Красная цена со скидкой (sale_price)
- Красный значок 'Акция'
- Иначе просто обычная цена
Файл: products/templates/products/productkit_list.html
Документация включает:
- Список всех исправлений
- Описание каждой проблемы и решения
- Архитектуру системы расчёта цены
- Результаты тестирования
- Точки входа для тестирования
- Справочную информацию по отладке
Исправлены 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>
Реализовано:
- Создан набор переиспользуемых шаблонных тегов для отображения качества
- 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>
Добавлена полностью гибкая система для оценки качества фотографий на основе размеров:
Конфигурация (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>
Проблема была в том, что при сохранении фотографии 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>
- Переместить название и описание над таблицей в отдельную карточку
- Убрать двухколонный 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>
Изменения в API:
- Добавить поле in_stock в возвращаемые данные товаров
- Добавить поддержку запроса товара по ID (параметр ?id=) для получения актуальных данных
- Исправить дублирование информации одного товара на остальные в таблице вариантов
Изменения в форме:
- Добавить автоматическую загрузку данных товара при загрузке страницы для существующих строк
- Правильно отображать артикул, цену и наличие для каждого товара в группе
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблема: при перемещении товаров стрелками вверх/вниз приоритеты изменялись только в 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>
Проблема: товары отображались как "нет в наличии" несмотря на наличие остатков на складе.
Причина: сигналы на обновление 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>
Добавлена визуализация статуса наличия (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>
Добавлена система управления наличием товаров на трёх уровнях:
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>
Основные изменения:
- Создана модель 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>
Реализована полноценная система мультитенантности на базе 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>
Реализована система автоматического создания суперпользователей при активации
новых тенантов (магазинов). 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>
ПРОБЛЕМА:
При создании комплекта с несколькими товарами сохранялся только первый товар.
ПРИЧИНЫ И РЕШЕНИЯ:
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
Реализован современный двухэтапный подход к созданию комплектов:
**Шаг 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>
Реализованы следующие улучшения для формы создания/редактирования комплектов:
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>
- Добавлено поле 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>
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>
- 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>
- 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>
- 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>
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>
- 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>
- Complete guide for using responsive image sizes in templates
- Examples for all template types (lists, galleries, modals)
- Performance metrics and optimization tips
- Size recommendations for each context
- Troubleshooting and best practices