Управление меню
Назначение
Товарная номенклатура ресторана: блюда, ингредиенты, полуфабрикаты, рецептуры (техкарты), ценообразование, единицы измерения, модификаторы. Центральный справочник товаров — на него ссылаются склад, POS, отчётность.
Самый крупный модуль: 14 контроллеров, 13+ сервисов, ~80 эндпоинтов.
Сценарии
Группы номенклатуры
Актор: Менеджер меню
Иерархическое дерево для структурирования товаров.
Меню ├── Горячие блюда │ ├── Мясо │ └── Рыба ├── Напитки │ ├── Кофе │ └── Алкоголь └── Ингредиенты ├── Овощи └── СпецииОперации: CRUD, перемещение (move), иерархия (parent → children).
Видимость групп — настройка для каждого подразделения: какие группы видны, включать ли в прайс-лист. Позволяет разное меню для разных точек.
Номенклатура
Актор: Менеджер меню
Типы:
- PRODUCT — готовое блюдо/товар для продажи. Пробивается в чеке
- INGREDIENT — сырьё. Закупается, хранится на складе, списывается по техкарте
- SEMI_FINISHED — полуфабрикат. Имеет техкарту и используется как ингредиент
При создании:
- Название, группа, тип
- Внутренний код — числовая сквозная нумерация в рамках корпорации (автогенерация max+1, если не указан); SKU (артикул) — свободное опциональное поле (внешний код/штрихкод, бэк не генерирует); PLU-код
- Опционально: категория учёта (для бухгалтерии), место приготовления (для списания)
Операции: CRUD, копирование (copy), перемещение между группами (move), мягкое удаление/восстановление (restore).
Бизнес-правила:
- Название уникально в рамках группы (value object
NomenclatureName) - SKU и внутренний код уникальны в корпорации
- Группа существует и не удалена
Единицы измерения
Справочник: кг, г, л, мл, шт, порция. Одна может быть основной.
Привязка к номенклатуре — с коэффициентом конвертации к основной единице:
- 1 бутылка = 0.75 л
- 1 ящик = 12 бутылок
Коэффициент > 0, точность до 3 знаков.
Упаковки
Единица закупки с привязкой к единице измерения и штрих-коду.
Пример: «Бутылка 0.75л» — единица «л», количество 0.75, штрих-код 4607001234567.
Штрих-коды
Один или несколько штрих-кодов на номенклатуру — для идентификации при приёмке и продаже.
Пищевая ценность (КБЖУ)
Калорийность, белки, жиры, углеводы на единицу измерения.
Модификаторы
Дополнения к блюду: кофе + сироп, стейк + соус.
- Модификатор — другая номенклатура
- Минимальное и максимальное количество (min ≤ max, оба ≥ 0)
- Пример: сироп — мин 0, макс 3
Техкарты (рецептуры)
Актор: Технолог / Шеф-повар
Описывает из чего и сколько готовится блюдо/полуфабрикат.
Стейк Рибай (выход: 1 порция)├── Говядина рибай — 350г (потери 15%)├── Соль — 5г (потери 0%)├── Перец — 2г (потери 0%)└── Масло оливковое — 20мл (потери 5%)Структура:
- Привязка к номенклатуре (PRODUCT или SEMI_FINISHED)
- Выход партии — сколько порций за цикл
- Ингредиенты: масса брутто, процент потерь, единица измерения
- Версионирование (v1, v2…), текущей может быть только одна
Зачем: автоматическое списание ингредиентов при продаже, расчёт себестоимости, контроль расхода.
Бизнес-правила (агрегат TechCardAggregate, static):
- Выход партии > 0
- Масса каждого ингредиента > 0
- Процент потерь: 0–100%
- Время приготовления > 0 (если указано)
- Дата начала < дата окончания (если диапазон)
Ценообразование
Актор: Менеджер меню / Управляющий
Цены по подразделениям — для номенклатуры можно задать разные цены в разных точках. Пример: кофе в центре — 350р, в пригороде — 280р.
Приказы об изменении цен (PriceChangeOrder):
ЧЕРНОВИК → ПРОВЕДЁН / ОТМЕНЁН- Массовое изменение цен на несколько номенклатур
- При проведении: новые цены применяются к NomenclaturePrice
- Фиксируется себестоимость на момент проведения
- Аудит-лог: кто создал, кто провёл
Бизнес-правила (агрегат PriceChangeOrderAggregate, static и NomenclaturePricingAggregate, static):
- Цена > 0
- При проведении: все позиции содержат цены
- Обязательные цены (для прайс-листа) заполнены
Синхронизация с POS
Номенклатура, группы, цены, модификаторы, техкарты синхронизируются на POS через Kafka + журнал синхронизации.
Статус синхронизации каждой номенклатуры отслеживается (NomenclaturePosSync): синхронизирована/нет, дата, возможность пометить как failed.
Связи с другими контекстами
| Направление | Что | Зачем |
|---|---|---|
| Меню → Склад | Номенклатура | Позиции накладных, инвентаризаций, списаний; складские остатки |
| Меню → POS | Номенклатура | Позиции чеков |
| Меню → Отчётность | Номенклатура | Аналитика продаж по блюдам |
| Организация → Меню | ACL | Подразделения (для цен, видимости), даты блокировки |
| Меню ← Организация (через ACL) | Проверка | Перед удалением места приготовления / категории учёта |
| Меню ← Бухгалтерия (через ACL) | Проверка | Перед удалением категории учёта |
Сущности
| Сущность | Описание |
|---|---|
| Группа номенклатуры | Иерархическое дерево. Поддерживает вложенность |
| Номенклатура | Блюдо / ингредиент / полуфабрикат. Центральная сущность, на неё ссылаются склад, POS, отчёты |
| Техкарта | Рецептура с версионированием. Список ингредиентов с массой и потерями |
| Ингредиент техкарты | Строка: номенклатура, масса, единица, процент потерь |
| Единица измерения | Справочник: кг, л, шт… |
| Привязка единицы к номенклатуре | Допустимая единица с коэффициентом конвертации |
| Упаковка | Закупочная единица + штрих-код |
| Штрих-код | Идентификатор товара |
| Пищевая ценность | КБЖУ на единицу измерения |
| Модификатор | Связь «блюдо ↔ добавка» с min/max |
| Цена номенклатуры | Цена в конкретном подразделении |
| Приказ об изменении цен | Массовое изменение цен. Статусы, аудит, фиксация себестоимости |
| Видимость группы | Настройка видимости группы в подразделении |
| Статус синхронизации | NomenclaturePosSync — отслеживание синхронизации с POS |