M meni.ge
🍽️ Зал, кухня и учёт

🔮 Прогноз спроса

Медиана по дню недели, план заготовок, черновик закупки и риск «закончится к 19:00»

Документация

Прогноз спроса

Повар каждое утро отвечает на один и тот же вопрос: сколько чего заготовить. Закупщик — на соседний: сколько чего заказать. Обычно оба отвечают по памяти.

Откройте Админ-панель → Склад → вкладка «Прогноз» (admin.meni.ge/inventory). Вкладка берёт историю продаж и превращает её в три конкретных артефакта. Порядок на экране — по срочности: сверху то, что рискует закончиться до конца дня, ниже — план заготовок, ещё ниже — черновик заказа поставщику. Если рисковых позиций нет, верхнего блока не будет вовсе. В самом низу, свёрнутой справкой, лежит таблица «Прогноз по блюдам» — на неё можно не смотреть, пока не захотелось проверить цифру.

Доступно на брендах AWS (cenaly.com, meni.ge и другие), на cenaly.ru — нет. Аналитическая база платформы, которая считает историю продаж для прогноза, в российском контуре не поднята. Сама вкладка «Прогноз» там открывается, но всегда показывает «Пока мало истории заказов, чтобы прогнозировать спрос» — независимо от того, сколько продаж на самом деле накопилось.


Как считается прогноз

Ровно две статистики, обе объяснимые повару вслух:

  1. Сколько этого блюда обычно продаётся в этот день недели. Окно истории — 8 недель (56 дней). Точечная оценка — медиана, а не среднее: восемь вторников, один из которых был днём рождения на 40 человек, средним говорят «готовь на 40» каждую неделю, а медиана этот вторник игнорирует. В справочной таблице «Прогноз по блюдам» рядом с числом показан честный разброс наблюдений (минимум–максимум), сколько наблюдений в выборке и пик — часть суток с наибольшей долей продаж. В шапке вкладки написано основание расчёта: «медиана того же дня недели за 56 дней · N рабочих дней истории».
  2. Как этот спрос распределён внутри дня — доли по частям суток: утро (6–11), обед (11–16), вечер (16–23), ночь (23–6). Границы одинаковы для всех заведений, а сам профиль считается по всем дням истории сразу, не отдельно по вторникам.

Что считается наблюдением, тоже решено осознанно: отменённые заказы в историю не идут; сегодняшний незакрытый день в выборку не попадает; дни до первой продажи блюда не считаются нулями (новинка не получает «ноль продаж» за те недели, когда её ещё не было в меню); «день без продаж» отличается от «дня, когда заведение было закрыто». Сутки считаются в часовом поясе локации. В расчёт берутся топ-500 позиций локации по обороту — длинный хвост меню отсекается.

Никакого машинного обучения — и это решение, а не недоделка. У заведения с одной-десятью точками история измеряется десятками недель, а не годами, и её насквозь пробивают выбросы: дождь, концерт по соседству, один щедрый стол. Модели на таких данных подгоняются под шум и выдают уверенные числа, которым нельзя верить.

Меньше трёх наблюдений одного дня недели — числа не будет. В таблице вместо цифры встанет прочерк, а в колонке наблюдений — пометка «мало». В план заготовок и в закупку такое блюдо не попадёт вовсе. Прогноз, которому нельзя верить, хуже отсутствующего: по нему готовят и закупают.

Переключатель вверху выбирает, на какой день строить прогноз — сегодня или завтра.


План заготовок

Прогноз по блюдам разворачивается по тех-картам в потребность в товарах и полуфабрикатах. Разворот идёт по текущим тех-картам, на момент открытия вкладки — если шеф поменял рецептуру утром, план это учтёт (правку, сделанную в соседнем окне, подхватит обновление страницы).

Вложенные полуфабрикаты разворачиваются вглубь: если соус варят из бульона, а бульон тоже полуфабрикат, в план попадут оба — иначе повару велели бы сварить соус, не сказав, что бульона под него нет. Глубина вложенности ограничена пятью уровнями (и защищена от рецептур, ссылающихся друг на друга по кругу): всё, что глубже, считается сырьём и уходит в закупку, а не в план заготовок.

Таблица плана:

Колонка Что означает
Название товара полуфабрикат, который нужно выпустить
Остаток сколько уже есть
Нужно валовая потребность по прогнозу за день
Выпустить нехватка — сколько реально варить/резать
К час, к которому остатка перестаёт хватать

Срок — это не «начало смены». Если соуса хватает на утро, но не на обед, повару надо успеть к 11:00, а не к 6:00. Час округляется до ближайшей границы части суток (6:00, 11:00, 16:00, 23:00), а у вложенных полуфабрикатов срока нет вовсе — там стоит прочерк: их варят «до» того, что из них делают. Строки отсортированы по сроку: раньше дедлайн — выше в списке. Если заготавливать нечего, вкладка так и пишет: остатков хватает на прогноз.

Остаток полуфабриката тратится один раз: если один и тот же бульон входит и в соус, и в суп, наивный расчёт применил бы остаток дважды и закупка недобрала бы сырья.

Кнопка «В доску смены» превращает план в чек-лист задач — см. Доска задач смены. Создаётся одна общая задача «План заготовок — <дата>», а каждая заготовка становится её подзадачей с количеством и часом прямо в заголовке («Соус демиглас — 16 шт к 11:00»); закрыть общую задачу можно только когда закрыты все подзадачи. Повторное нажатие не плодит дубли: если план на эту дату уже стоит на доске, кнопка так и скажет.

Блюда без тех-карты в план не идут и перечисляются отдельным предупреждением (до 20 названий): по ним прогноз ничего сказать не может, и это лучше сказать вслух, чем сделать вид, что заказ полный.


Черновик заказа поставщику

Ниже плана — черновик закупки на выбранный горизонт покрытия (поле «Покрытие, дней»: обычно срок поставки плюс запас; по умолчанию 3 дня, допустимо от 1 до 30).

Для каждого товара считаются две величины, и берётся бо́льшая:

  • потребность по прогнозу за горизонт минус текущий остаток;
  • добор до целевого остатка (а если он у товара не задан — до точки заказа) — обычная складская логика.

Почему бо́льшая, а не одна вместо другой: страховой запас не знает про завтрашнюю пятницу с двойной посадкой; а прогноз не знает про товары, которые вообще не участвуют в тех-картах (упаковка, расходники) — у них складские нормативы единственный ориентир. Строки, попавшие в список по второму правилу, помечены «по точке заказа». Обратите внимание: правило смотрит на целевой остаток, поэтому в черновик попадёт и товар, который ещё выше точки заказа, но ниже целевого — вкладка «Нужно заказать» такой товар пока не показывает.

По прогнозу закупаются только конечные ингредиенты: полуфабрикаты в заказ поставщику по прогнозу не идут (их выпускают по плану заготовок) — они могут попасть в черновик разве что по складскому нормативу.

Количество округляется вверх до кратности упаковки, если она задана у товара. Строки сгруппированы по поставщикам (товары без назначенного поставщика — отдельной группой), и кнопка создаёт свой заказ на каждого поставщика — дальше это обычные закупки из раздела Склад.


«Закончится к 19:00»

Самый верхний блок вкладки — риск исчерпания до конца дня: то, что горит прямо сейчас. Он сравнивает текущий остаток с ожидаемым расходом за оставшиеся часы, посчитанным по профилю частей суток, и называет час, к которому остаток обнулится. Если час определить не удаётся, строка честно говорит «не хватит до конца дня», без выдуманного времени.

Блок считается только для сегодня: при переключении на «завтра» он исчезает — риска «закончится к 19:00» у завтрашнего дня не бывает.

Поправка на сегодняшний темп: если к обеду уже израсходовали больше обычного, ожидание на остаток дня пропорционально поднимается, и в строке появляется пометка вроде «темп дня ×1.4». Темп считается по фактическим продажам (списания, порча и питание персонала в него не идут) и измеряется для первых десятка с небольшим самых рискованных строк — остальные считаются по обычному профилю. Коэффициент зажат в диапазоне ×0.5…×2 — поправка на «сегодня людно» нужна, а предсказание по одному чеку нет. Если темп измерить не из чего вообще, вкладка честно скажет, что взят обычный профиль дня недели.


Что нужно, чтобы прогноз появился

Нужно Зачем Без этого
Бренд на контуре AWS (cenaly.com, meni.ge…) историю продаж считает серверная аналитическая база, а она поднята только там на cenaly.ru вкладка всегда пишет «Пока мало истории заказов» — сообщение про историю, но причина другая: считать её там нечем
История продаж посчитать медиану по дню недели «Пока мало истории заказов, чтобы прогнозировать спрос»
≥ 3 одинаковых дня недели в истории считать выборкой блюдо в таблице помечено «мало» и в планы не идёт
Тех-карты блюд развернуть прогноз в товары блюдо попадёт в предупреждение «без тех-карты»
Актуальные остатки посчитать нехватку и риск вкладка не покажет ничего, пока остатки не загрузятся

Агрегат истории пересчитывается на сервере примерно раз в полчаса (и только для аккаунтов, которые сейчас работают); разворот тех-карт и вычет остатков считаются в момент открытия вкладки, по текущим данным.


Связанные разделы


Частые вопросы

Почему у половины блюд стоит пометка «мало»?

Потому что по этим блюдам в истории меньше трёх продаж в этот день недели — например, блюдо появилось в меню две недели назад. Число появится само, когда наблюдений станет достаточно; до этого блюдо не участвует ни в плане заготовок, ни в закупке.

Почему используется медиана, а не среднее?

Медиана устойчива к выбросам. Один банкет на 40 человек сдвигает среднее так, что заведение неделями готовит лишнее. Среднее в интерфейсе не показывается вовсе — только медиана, разброс и число наблюдений.

Прогноз учитывает погоду, праздники, футбол?

Нет. Он знает только день недели и время суток. Праздничную неделю и матч по соседству по-прежнему держит в голове управляющий — и это честнее, чем модель, делающая вид, что учла их.

Можно ли строить прогноз на неделю вперёд?

Вкладка показывает сегодня и завтра. Для закупки горизонт задаётся отдельно — полем «Покрытие, дней»: прогноз одного дня умножается на него.

Черновик закупки сразу отправляет заказ поставщику?

Нет. Это именно черновик: лишние строки вы снимаете галочкой и только затем нажимаете создание — получаются обычные черновики закупок раздела «Склад», по одному на поставщика. Количества правятся уже в созданном заказе, там же, где и обычно.