Каталог
Источник требований
Единый справочник товаров и категорий франшизы. Управляется только Франшизой. Изменения применяются напрямую.
Категории
Дерево категорий для структурирования товаров. Категория — standalone сущность (franchise-level). Товар имеет category_id (nullable). Управление категориями — отдельный раздел /catalog/categories.
”Без категории”
Товар с category_id = NULL отображается в разделе “Без категории”.
Поля
| Поле | Обязательность | Описание |
|---|---|---|
| Название | Обязательно | |
| Родительская категория | Необязательно | null = корневая |
| Порядок отображения | Обязательно | Число для сортировки внутри уровня |
| Активность | Обязательно | Вкл/выкл (неактивная скрыта от клиентов) |
Иерархия
- Неограниченная вложенность (adjacency list с parent_id)
- На практике 2-3 уровня: “Еда” → “Горячее” → “Пицца”
- Товар привязывается к любой категории любого уровня
CRUD
- Создание (с выбором родителя или без)
- Редактирование (название, порядок, активность, смена родителя)
- Удаление — только если нет дочерних (
CATEGORY_HAS_CHILDREN) и нет товаров (CATEGORY_HAS_PRODUCTS) - Деактивация каскадная — при отключении родительской все дочерние и их товары деактивируются. Активация — поштучно или каскадно (выбор в UI)
Товары
Единый каталог товаров для всей сети. Изменения применяются мгновенно.
Поля
| Поле | Обязательность | Описание |
|---|---|---|
| Название | Обязательно | Уникальное в рамках каталога франшизы |
| Описание | Необязательно | Текстовое |
| Тип | Обязательно | dish (блюдо) / good (продукт). (BR 1.11: type=ingredient убран — ингредиенты перенесены в Warehouse Service) |
| Категория | Необязательно | FK → categories. NULL = “Без категории” |
| (Убрано в BR 1.10. Цена определяется прейскурантом.) | ||
| Единица измерения | Обязательно | шт, кг, г, л, мл, порция |
| Статус | Обязательно | active / inactive (default active) |
Требует приготовления (requires_kitchen) | Обязательно | Boolean, default false. Если true — товар идёт через кухонный flow заказа (см. Заказы). Примеры true: шаурма, бургер, пицца. Примеры false: бутылочная вода, печенье в витрине. (Добавлено в BR 2.5) |
Кухонная станция (kitchen_station_id) | Условно (см. ниже) | FK → kitchen_stations. Определяет на какой станции готовится товар. (Добавлено в BR 2.5) |
Ставка НДС (vat_rate) | Обязательно | Enum: none / vat0 / vat10 / vat20 / vat110 / vat120. Default vat20. Передаётся в инвойс PayKeeper для формирования фискального чека 54-ФЗ. (Добавлено в BR 3.3) |
Предмет расчёта (payment_subject) | Обязательно | Enum: goods / service / work / excise / job / payment / agency / composite / another. Default goods. Признак предмета расчёта (тег 1212 по 54-ФЗ). (Добавлено в BR 3.3) |
Способ расчёта (payment_type) | Обязательно | Enum: full / prepay / advance / partial_prepay / credit / credit_pay / partial. Default full. Признак способа расчёта (тег 1214). (Добавлено в BR 3.3) |
Бизнес-правило: requires_kitchen ↔ kitchen_station_id
(Добавлено в BR 2.5)
- Если
requires_kitchen = true— полеkitchen_station_idобязательно (не NULL). Иначе API отклоняет сохранение товара с кодомVALIDATION_ERROR/MISSING_KITCHEN_STATION. - Если
requires_kitchen = false—kitchen_station_idдолжно быть NULL (нет смысла указывать станцию для товара который не готовится). - Изменение
requires_kitchenсtrue → falseпри сохранении сбрасываетkitchen_station_id.
Подробнее о сущности кухонных станций — Кухонные станции.
Бизнес-правило: фискальные атрибуты обязательны для PayKeeper
(Добавлено в BR 3.3)
- Поля
vat_rateиpayment_subject— обязательны при создании и редактировании товара. Без них товар нельзя включить в инвойс PayKeeper (не сформируется фискальный чек). - Default при миграции существующих товаров:
vat_rate=vat20,payment_subject=goods,payment_type=full. - В карточке товара (таб «Информация») — подсекция «Фискальные атрибуты» с тремя полями. Видна всегда (не зависит от активности PK-интеграции).
Soft delete
- Помечается
deleted_at, скрывается из общего списка - Удалённые доступны в отдельной вкладке “Удалённые” с кнопкой “Восстановить”
Вычисляемое меню
Меню — не отдельная сущность. Вычисляется на лету:
Все активные товары с категориями
+ Прейскурант (дефолтный или per-ТТ) — [[08-Specs/Админка Франшизы/Прейскуранты|см. Прейскуранты]]
+ Модификаторы (structural + free с ценами из прейскуранта)
− Стоп-листы (per-ТТ, [[08-Specs/Админка Франшизы/Стоп-листы|BR 1.13]])
− Проверка складских остатков (per-ТТ)
= Финальное меню для клиента
- MVP: вычисляется при каждом запросе
- Целевой: вычисляется и кэшируется в Redis
BR 1.16 — Реализовано
Эндпоинт
GET /internal/catalog/menuреализован с поддержкой:
- Фильтрация по стоп-листам (параметр
store_id)- Модификаторы товаров (structural + free) с ценами из прейскуранта
- Контракт: menu
Ролевая матрица
Франшиза (владелец бренда)
- CRUD всех товаров (с категорией)
- CRUD категорий (standalone)
Франчайзи (партнёр)
- Просмотр активных товаров и категорий
Менеджер ТТ
- Просмотр активных товаров и категорий
Кассир
- Нет доступа в админке
Список товаров
Колонки
- Название
- Тип (Блюдо / Продукт)
- Категория
- Ед. изм.
- Статус
Фильтры
- По типу
- По статусу
- По категории
Поиск
- По названию
Пагинация
- 20 записей на страницу
Карточка товара
- Просмотр: все поля
- Создание: форма с обязательными полями + категория (select из дерева, nullable)
- Редактирование: все поля включая категорию. Изменения применяются мгновенно.
(Обновлено в BR 1.8.1)
Конструктор товара
Единый экран управления товаром — /catalog/products/{id}:
- Шапка: название, тип (dish/good), статус
- Табы:
- Таб “Информация” — поля товара (название, описание, категория, единица измерения)
- Таб “Модификаторы” — все модификаторы, разделённые на две секции (BR 1.9.3):
- Секция “Закреплённые” (
binding_type = structural) — вверху - Секция “Свободные” (
binding_type = free) — внизу - [+ Добавить закреплённый] / [+ Добавить свободный] → модалки
- [Убрать] модификатор
- Секция “Закреплённые” (
- Таб “Техкарта” — только рецептура блюда. Виден только для type=dish. В табе:
- Per-option вкладки (25см / 30см / 35см) — определяются закреплёнными модификаторами из таба “Модификаторы”
- Управление модификаторами — в табе “Модификаторы”, не здесь
- См. Техкарты (BR 1.9)
Что НЕ входит
Ингредиенты— перенесены в Warehouse Service (BR 1.11)- Фото товаров (S3) — Phase 2
- КБЖУ, аллергены, штрихкод — Phase 2
Модификаторы— см. Модификаторы (BR 1.8)Прейскуранты — BR 1.10→ реализовано: Прейскуранты- Техкарты — BR 1.9
Комбо и бизнес-ланчи
Комбо/бизнес-ланч — это обычный товар в каталоге без специальной логики. Владелец заводит позицию «Комбо №1 (солянка, пюре с котлетой, салат, компот)» через стандартный UI создания товара, выставляет цену в прейскуранте.
При продаже:
- В POS-меню комбо выглядит как отдельная позиция (как любой другой товар).
- В фискальном чеке — одна строка с одним наименованием и одной ценой.
- Списания со склада нет (расход по составу через техкарту — не реализовано в этой итерации).
Когда понадобится списание ингредиентов
Если потребуется учитывать расход компонентов комбо (солянку, котлету и т.д.) — нужна техкарта в Warehouse Service. Эта функциональность — отдельная задача (BR 1.9 / расширение).
Связи с другими модулями
- Прейскуранты — цены per-ТТ (BR 1.10)
- Стоп-листы (BR 1.13) — скрытие позиций per-ТТ
- Временные тарифы — happy hours, скидки по расписанию (BR loyalty T1)
- Техкарты (BR 1.9) — рецептуры привязаны к товарам, живут в Warehouse Service
- Торговые точки (BR 1.5) — прейскуранты и стоп-листы per-ТТ
Ссылки
- Админка Франшизы — бизнес-обзор
- Ролевая модель
ADR-012 — Ингредиенты отложены(superseded: BR 1.11 — ингредиенты в Warehouse)