# Руководство по работе с вариантами товаров ## Введение Система вариантов товаров позволяет создавать букеты с гибкими заменами компонентов. Это полезно когда один товар может быть заменен на другой похожий товар (например, роза 50см на розу 70см), и приоритет замены индивидуален для каждого букета. ## Основные концепции ### 1. Группа вариантов (ProductVariantGroup) **Группа вариантов** - это набор взаимозаменяемых товаров. Пример: - Группа: "Роза красная Freedom" - Роза Freedom 50см - Роза Freedom 60см - Роза Freedom 70см Один товар может входить в несколько групп вариантов. ### 2. Позиция в букете (KitItem) Каждая позиция в букете может быть: - **Конкретным товаром** - без возможности замены - **Группой вариантов** - с приоритетами замен ### 3. Приоритеты (KitItemPriority) Для каждой позиции с группой вариантов можно настроить индивидуальные приоритеты: - Меньшее число = выше приоритет - Приоритет 0 = наивысший приоритет - Приоритет 1 = второй по важности - И т.д. ## Как использовать ### Шаг 1: Создание группы вариантов 1. Откройте Django Admin 2. Перейдите в раздел "Группы вариантов" 3. Нажмите "Добавить группу вариантов" 4. Заполните: - Название: например, "Роза красная Freedom" - Описание: опционально 5. Сохраните ### Шаг 2: Добавление товаров в группу 1. Откройте нужный товар в разделе "Товары" 2. В поле "Группы вариантов" выберите созданную группу 3. Сохраните товар 4. Повторите для всех товаров, которые должны быть в этой группе Альтернативный способ: - Выберите несколько товаров через filter_horizontal в админке товара ### Шаг 3: Создание букета с вариантами 1. Создайте новый комплект (букет) или откройте существующий 2. При добавлении позиции в букете: - **Вариант А**: Укажите конкретный товар (если замены не нужны) - **Вариант Б**: Укажите группу вариантов (если нужны замены) ⚠️ **Важно**: Нельзя указывать одновременно и товар, и группу вариантов! 3. Укажите количество 4. При необходимости добавьте примечание 5. Сохраните позицию ### Шаг 4: Настройка приоритетов Если вы выбрали группу вариантов: 1. Откройте позицию букета (KitItem) 2. В разделе "Приоритеты вариантов" добавьте товары из группы 3. Для каждого товара укажите приоритет: ``` Роза Freedom 70см - приоритет 0 (первый выбор) Роза Freedom 60см - приоритет 1 (второй выбор) Роза Freedom 50см - приоритет 2 (третий выбор) ``` 4. Сохраните ### Шаг 5: Проверка доступности Система автоматически проверяет доступность букета: ```python # В коде или Django shell kit = ProductKit.objects.get(name="Ранчо Виталия") # Проверить доступность if kit.check_availability(): print("Букет можно собрать!") else: print("Букет недоступен") # Рассчитать цену с учетом замен price = kit.calculate_price_with_substitutions() print(f"Цена: {price} руб.") ``` ## Примеры использования ### Пример 1: Премиум букет с розами **Задача**: Создать букет "Ранчо Виталия" где нужны длинные розы, но можно заменить на средние. **Решение**: 1. Создать группу "Роза красная Freedom" 2. Добавить в неё розы 50см, 60см, 70см 3. В букете создать позицию с группой вариантов 4. Настроить приоритеты: - Роза 70см - приоритет 0 - Роза 60см - приоритет 1 - Роза 50см - приоритет 2 При проверке доступности система сначала проверит наличие 70см, потом 60см, и только потом 50см. ### Пример 2: Эконом букет **Задача**: Создать эконом-букет где приоритет у коротких роз. **Решение**: 1. Использовать ту же группу "Роза красная Freedom" 2. Создать новый букет с другими приоритетами: - Роза 50см - приоритет 0 (первый выбор) - Роза 60см - приоритет 1 - Роза 70см - приоритет 2 Та же группа товаров, но другой порядок приоритетов! ### Пример 3: Букет без замен **Задача**: Создать букет где конкретные товары без замен. **Решение**: 1. При создании позиции в букете указать конкретный товар 2. Оставить поле "Группа вариантов" пустым 3. Приоритеты настраивать не нужно ### Пример 4: Смешанный букет **Задача**: В одном букете часть позиций с заменами, часть без. **Решение**: ``` Позиция 1: Роза Freedom (группа вариантов) - 15 шт Позиция 2: Упаковка крафт (конкретный товар) - 1 шт Позиция 3: Лента атласная (конкретный товар) - 2 м Позиция 4: Эустома белая (группа вариантов) - 5 шт ``` ## Как работает система ### Проверка доступности товара Когда вызывается `kit_item.get_best_available_product()`: 1. Система получает список доступных товаров 2. Если настроены приоритеты - сортирует по ним 3. Проходит по списку от высшего приоритета к низшему 4. Для каждого товара проверяет наличие на складе 5. Возвращает первый доступный товар ### Проверка доступности букета Когда вызывается `kit.check_availability()`: 1. Система проходит по всем позициям букета 2. Для каждой позиции ищет доступный товар 3. Если хотя бы одна позиция недоступна - весь букет недоступен 4. Если все позиции доступны - букет можно собрать ### Расчет цены Система рассчитывает цену на основе фактически доступных товаров: ```python # Пример Позиция: Роза Freedom - 15 шт Приоритеты: - Роза 70см (200 руб) - нет в наличии - Роза 60см (150 руб) - нет в наличии - Роза 50см (100 руб) - есть в наличии ✓ Цена позиции: 15 × 100 = 1500 руб ``` ## Интеграция со складом Текущая версия использует заглушку `StockManager`, которая всегда возвращает `True`. В будущем `StockManager` будет интегрирован с реальной системой складского учета: ```python # Будущая реализация class StockManager: def check_stock(self, product, quantity): # Запрос к складской системе available = get_stock_from_warehouse(product.sku) return available >= quantity ``` ## API моделей ### ProductVariantGroup **Методы:** - `get_products_count()` - количество товаров в группе **Поля:** - `name` - название группы - `description` - описание - `products` - товары в группе (M2M) ### KitItem **Методы:** - `get_display_name()` - название для отображения - `has_priorities_set()` - настроены ли приоритеты - `get_available_products()` - список доступных товаров - `get_best_available_product(stock_manager)` - лучший доступный товар - `clean()` - валидация **Поля:** - `product` - конкретный товар (nullable) - `variant_group` - группа вариантов (nullable) - `quantity` - количество - `notes` - примечание ### ProductKit **Методы:** - `get_total_components_count()` - количество позиций - `get_components_with_variants_count()` - позиций с вариантами - `check_availability(stock_manager)` - проверка доступности - `calculate_price_with_substitutions(stock_manager)` - расчет цены ### Product **Методы:** - `get_variant_groups()` - все группы вариантов - `get_similar_products()` - похожие товары **Поля:** - `variant_groups` - группы вариантов (M2M) ## Советы и лучшие практики 1. **Именование групп**: Используйте понятные названия, например "Роза красная Freedom" вместо "Группа 1" 2. **Приоритеты**: Начинайте с 0 и увеличивайте по 1 для простоты 3. **Проверка**: Всегда проверяйте доступность букета перед оформлением заказа 4. **Цены**: Учитывайте, что цена может меняться в зависимости от того, какой вариант доступен 5. **Несколько групп**: Один товар может быть в нескольких группах - это нормально 6. **Валидация**: Система не даст сохранить позицию, где указаны одновременно товар И группа ## Часто задаваемые вопросы **Q: Можно ли товар добавить в несколько групп вариантов?** A: Да, один товар может быть в любом количестве групп. **Q: Что если не настроить приоритеты?** A: Система вернет все товары из группы в произвольном порядке. **Q: Можно ли изменить приоритеты после создания букета?** A: Да, приоритеты можно менять в любое время. **Q: Как система выбирает товар, если несколько имеют одинаковый приоритет?** A: По ID (первый созданный). **Q: Влияет ли порядок товаров в группе на выбор?** A: Нет, только приоритеты имеют значение. Если приоритеты не настроены - порядок не определен. ## Устранение неполадок ### Ошибка: "Нельзя указывать одновременно товар и группу вариантов" **Причина**: Заполнены оба поля - `product` и `variant_group` **Решение**: Очистите одно из полей. Оставьте либо товар, либо группу. ### Букет показывается как недоступный, хотя товары есть **Причина**: Возможно, `StockManager` некорректно работает **Решение**: Проверьте реализацию `StockManager.check_stock()` ### Приоритеты не работают **Причина**: Приоритеты не были сохранены для позиции **Решение**: 1. Откройте позицию букета 2. Убедитесь, что в разделе "Приоритеты вариантов" есть записи 3. Проверьте значения приоритетов (меньше = выше) ## Дополнительная информация Для получения помощи обратитесь к разработчикам или создайте issue в репозитории проекта. --- **Дата создания**: 2025-10-21 **Версия**: 1.0