Отчётность
Назначение
Аналитические отчёты по выручке. Денормализованная read-model для быстрых запросов. Данные из POS-чеков распределяются по методам оплаты, сотрудникам, блюдам и временным периодам.
1 контроллер, ~3 эндпоинта.
Сценарии
Дневная выручка
Актор: Владелец / Управляющий
Выручка за каждый день выбранного периода.
Фильтры: корпорация, дата начала/окончания (макс. 366 дней), опционально подразделение и метод оплаты.
Результат: дата, выручка, скидки, себестоимость, прибыль.
Почасовая выручка
Актор: Управляющий
Распределение по часам дня — пиковые часы и «мёртвые зоны».
Результат: час, выручка, количество чеков.
Выручка по сотрудникам
Актор: Управляющий
Сколько выручки принёс каждый официант/кассир.
Результат: имя, количество чеков, выручка, средний чек.
Продажи по блюдам
Актор: Менеджер меню / Управляющий
Какие блюда и сколько продано.
Результат: название, количество, выручка, себестоимость, маржа.
Как устроена read-model
Проблема
Данные для отчётов разбросаны по чекам, позициям, оплатам, номенклатуре, сотрудникам. JOIN на лету — медленно.
Решение — денормализация
При обработке чека создаются плоские записи RevenueReportEntry. Для каждой позиции чека × каждого метода оплаты:
- Рассчитать долю метода в сумме чека (
paymentShare) - Распределить пропорционально: выручка × доля, скидка × доля, себестоимость × доля
- Для возвратов — все суммы со знаком минус
Пример:
Чек 1000р: Стейк (700р) + Кофе (300р). Оплата: карта 600р (60%) + наличные 400р (40%).
| Блюдо | Метод | Доля | Выручка |
|---|---|---|---|
| Стейк | Карта | 60% | 420р |
| Стейк | Наличные | 40% | 280р |
| Кофе | Карта | 60% | 180р |
| Кофе | Наличные | 40% | 120р |
Группировка по любому разрезу без JOIN.
Идемпотентность
При повторной обработке: старые записи удаляются → новые создаются. Безопасный пересчёт.
Бизнес-правила
- Диапазон дат: макс. 366 дней
- Дата начала и окончания обязательны
- Все расчёты с timezone корпорации
- Учётная дата — по настройке «начало учётного дня»
Связи с другими контекстами
| Направление | Что | Зачем |
|---|---|---|
| POS → Отчётность | Чеки, позиции, оплаты | Источник данных |
| Организация → Отчётность | Timezone, учётный день | Группировка по дням |
| Меню → Отчётность | Номенклатура | Группировка по блюдам |
| Закупки → Отчётность | Методы оплаты | Группировка по способам |
| Кадры → Отчётность | Сотрудники | Отчёт по официантам/кассирам |
Сущности
Запись отчёта по выручке (RevenueReportEntry)
Денормализованная запись:
| Поле | Описание |
|---|---|
| Учётная дата | К какому рабочему дню относится |
| Номенклатура | Какое блюдо |
| Метод оплаты | Каким способом |
| Подразделение | В каком подразделении |
| Смена, чек, позиция | Ссылки на исходные данные |
| Количество | Порций |
| Цена за единицу | Цена продажи |
| Скидка | Размер скидки |
| Итоговая цена | После скидки |
| Себестоимость | Себестоимость товара |
| Food cost | Доля себестоимости в выручке |
| Прибыль | Выручка − себестоимость |
| Доля метода оплаты | Какая часть суммы на этот метод |