Перейти к содержимому

7a. Отчётность по выручке

Что это

Модуль отчётности формирует денормализованные записи по каждой продаже для быстрого анализа. Данные приходят из POS (чеки) и раскладываются по позициям и платежам.


Как формируется отчёт

Каждый чек содержит позиции (что продали) и платежи (чем оплатили). Задача отчёта — связать одно с другим.

Проблема: один чек, несколько способов оплаты

Чек #23:
Позиции: Оплата (сплит):
├── Стейк: 1 350 ₽ ├── Наличные: 2 000 ₽
├── Латте: 380 ₽ └── Карта: 1 730 ₽
└── Цезарь: 500 ₽ (скидка 50 ₽)
Итого: 2 180 ₽ Итого: 3 730 ₽ — стоп, не сходится?

На самом деле: сумма оплаты = итого после скидок. Система распределяет пропорционально долям платежей.

Формула распределения

Доля платежа = |сумма_платежа| / СУММА(|все_платежи|)
Для каждой позиции и каждого платежа:
выручка_gross = цена_позиции × доля_платежа
скидка = скидка_позиции × доля_платежа
себестоимость = себест_позиции × доля_платежа
количество = кол_позиции × доля_платежа
выручка_net = выручка_gross − скидка

Пример

Чек #23:
Позиции: Оплата:
├── Стейк: 1 350 ₽ (скидка 0) ├── Наличные: 1 000 ₽ (46%)
├── Латте: 380 ₽ (скидка 0) └── Карта: 1 180 ₽ (54%)
└── Цезарь: 450 ₽ (скидка 50)
Итого: 2 130 ₽ Итого: 2 180 ₽
Доля наличных = 1 000 / 2 180 = 0.4587 (≈46%)
Доля карты = 1 180 / 2 180 = 0.5413 (≈54%)
Распределение «Стейк Рибай» (1 350 ₽, себест. 470 ₽):
┌─────────────────┬──────────────┬──────────────┐
│ │ Наличные │ Карта │
│ │ (46%) │ (54%) │
├─────────────────┼──────────────┼──────────────┤
│ Выручка gross │ 619.27 ₽ │ 730.73 ₽ │
│ Скидка │ 0 │ 0 │
│ Себестоимость │ 215.59 ₽ │ 254.41 ₽ │
│ Количество │ 0.459 шт │ 0.541 шт │
│ Выручка net │ 619.27 ₽ │ 730.73 ₽ │
└─────────────────┴──────────────┴──────────────┘
Итого за «Стейк» — 6 записей в отчёте
(3 позиции × 2 платежа = 6 строк)

Защита от ошибок округления

Последний платёж получает не рассчитанную долю, а остаток:

Стейк: 1 350 ₽
Наличные (расчёт): 1 350 × 0.4587 = 619.27 ₽
Карта (остаток): 1 350 − 619.27 = 730.73 ₽ ← точное число, не округлённое

Учётная дата в отчёте

Чеки привязываются к учётной дате, а не к календарной.

Настройка: начало учётного дня = 06:00
Чек пробит: 16 апреля в 01:30
Учётная дата: 15 апреля (до 06:00 = ещё «вчера»)
→ Чек попадёт в отчёт за 15 апреля

Возвраты в отчёте

Чеки возврата (RETURN) записываются с отрицательным знаком — это автоматически вычитает их из выручки при суммировании.

Продажа: +1 350 ₽ (стейк), количество +1
Возврат: −1 350 ₽ (стейк), количество −1
Итого: 0 ₽ (стейк), количество 0
Количество гостей тоже инвертируется при возврате.

Структура записи отчёта

Каждая запись (RevenueReportEntry) содержит:

┌─────────────────────────────────────────────────────────────────┐
│ ЗАПИСЬ ОТЧЁТА ПО ВЫРУЧКЕ │
├─────────────────────────────────────────────────────────────────┤
│ Учётная дата: 15.04.2026 │
│ Подразделение: Центр │
│ Номенклатура: Стейк Рибай │
│ Метод оплаты: Наличные │
│ Официант: Сидорова И.М. │
│ Тип операции: SALE │
├─────────────────────────────────────────────────────────────────┤
│ Количество: 0.459 шт │
│ Выручка (gross): 619.27 ₽ │
│ Скидка: 0.00 ₽ │
│ Выручка (net): 619.27 ₽ │
│ Себестоимость: 215.59 ₽ │
│ Наценка: 0.00 ₽ │
│ Гостей: 0.459 │
└─────────────────────────────────────────────────────────────────┘

Аналитические срезы

Из этих записей можно строить отчёты в любом разрезе:

По подразделениям:
«Центр»: выручка 98 000 ₽, себестоимость 32 000 ₽, маржа 67%
«Парк»: выручка 72 000 ₽, себестоимость 25 000 ₽, маржа 65%
По блюдам:
Стейк Рибай: 25 шт, выручка 33 750 ₽, маржа 65%
Латте: 48 шт, выручка 18 240 ₽, маржа 78%
Цезарь: 32 шт, выручка 17 600 ₽, маржа 67%
По методам оплаты:
Наличные: 45 000 ₽ (26%)
Карта: 115 000 ₽ (68%)
Безнал: 10 000 ₽ (6%)
По официантам:
Сидорова: 67 чеков, выручка 85 000 ₽
Козлов: 42 чека, выручка 55 000 ₽
По дням/неделям/месяцам:
Средний чек, динамика выручки, сезонность