Прейскуранты
(Добавлено в BR 1.10)
Назначение
Прейскурант — именованный набор цен на товары и опции модификаторов. Цена товара определяется только через прейскурант. В каталоге (ассортименте) цен нет — только состав блюд и модификаторов.
Сущность “Прейскурант”
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| Название | string (255) | Да | Уникальное в рамках франшизы |
| Дефолтный | boolean | Да | Ровно один на франшизу. Применяется ко всем ТТ без явного назначения |
| Статус | active / inactive | Да | Inactive нельзя назначить на ТТ |
Версионирование
Прейскурант версионируется совместно с каталогом (связь 1:1):
| Событие каталога | Действие с прейскурантами |
|---|---|
| Создание draft каталога | Автоматически создаются draft-версии всех прейскурантов (дефолтного + всех кастомных). Цены копируются из предыдущей published-версии. |
| Публикация каталога | Все draft-прейскуранты публикуются вместе с каталогом |
| Удаление draft каталога | Все draft-прейскуранты удаляются |
Пример:
Каталог v3 (published)
└── Прейскурант "Стандартный" v3 (published)
└── Прейскурант "Аэропорт" v3 (published)
Каталог v4 (draft)
└── Прейскурант "Стандартный" v4 (draft) — скопировал цены из v3
└── Прейскурант "Аэропорт" v4 (draft) — скопировал цены из v3
Позиции прейскуранта (цены)
Каждая версия прейскуранта содержит:
| Тип позиции | Описание | Правило |
|---|---|---|
| Цена товара | Цена для каждого товара из каталога данной версии | >= 0₽, обязательна |
| Цена опции модификатора | Цена для каждой опции модификатора, привязанного к товарам | >= 0₽, обязательна (0 = бесплатная опция) |
Если товар добавлен в draft каталога — в draft прейскурантах его цена = 0₽ (франшиза обязана задать перед публикацией).
Назначение на ТТ
- Франшиза назначает прейскурант на конкретные ТТ
- Один прейскурант → множество ТТ (даже из разных франчайзи)
- Одна ТТ → максимум один прейскурант
- Нет назначения → применяется дефолтный
Бизнес-правила
- Единственный дефолтный — ровно один прейскурант на франшизу помечен как дефолтный в любой момент
- Нельзя удалить дефолтный — сначала перенести флаг на другой, потом удалить
- Нельзя удалить назначенный — сначала снять назначение со всех ТТ
- Цена = 0 блокирует публикацию — если в дефолтном прейскуранте есть товар с ценой 0 → публикация каталога запрещена
- Inactive нельзя назначить — прейскурант со статусом inactive нельзя назначить на ТТ
- Смена дефолтного — ТТ без явного назначения автоматически переходят на нового дефолтного (не требует действий)
- Автозаполнение при создании — новый прейскурант автоматически заполняется всеми активными товарами и опциями модификаторов. Цены копируются из дефолтного прейскуранта; если дефолтного нет (первый прейскурант) — цена 0₽ (Исправлено в BUG-001)
- Автодобавление нового товара/опции — при создании нового товара или опции модификатора автоматически создаётся запись с ценой 0₽ во всех существующих прейскурантах франшизы (Исправлено в BUG-001)
Сборка меню (резолвинг цены)
1. Каталог → текущий published
2. Прейскурант ТТ → назначенный на ТТ, или дефолтный (fallback)
3. Для каждого товара каталога:
a. Цена = price_list_items[product_id] (версия = published каталога)
b. Для каждого модификатора:
- Цена каждой опции = price_list_items[modifier_option_id]
4. Применить стоп-листы (будущая BR)
5. = Финальное меню
Ролевой доступ
| Действие | Франшиза | Франчайзи | Менеджер ТТ | Кассир |
|---|---|---|---|---|
| Создание прейскуранта | ✅ | ❌ | ❌ | ❌ |
| Редактирование цен (draft) | ✅ | ❌ | ❌ | ❌ |
| Удаление прейскуранта | ✅ | ❌ | ❌ | ❌ |
| Назначение на ТТ | ✅ | ❌ | ❌ | ❌ |
| Просмотр прейскурантов | ✅ | ✅ (свои ТТ) | ✅ (своя ТТ) | ❌ |
| Просмотр цен в меню | ✅ | ✅ | ✅ | ✅ (POS) |
Связи с другими модулями
- Каталог — прейскурант версионируется вместе с каталогом. Каталог определяет ассортимент, прейскурант — цены.
- Модификаторы — цена опции модификатора определяется прейскурантом
- Торговые точки — прейскурант назначается на ТТ
- ADR-007 — только Франшиза задаёт цены