Files
octopus/myproject/docs/product_variants_guide.md

311 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Руководство по работе с вариантами товаров
## Введение
Система вариантов товаров позволяет создавать букеты с гибкими заменами компонентов. Это полезно когда один товар может быть заменен на другой похожий товар (например, роза 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