Готовые отчёты

Отчёты, которые не укладываются в OLAP: зарплата и мотивации, кассовые смены, движение денег, долги и оплаты контрагентов, список товаров с ценами и стоп-лист, ABC-XYZ-анализ товаров, склад, оплата Mison по точкам. У них фиксированный набор полей.

Доступ и правила расчёта — те же, что у OLAP продаж: нужна галочка «Доступ к отчётам» на ключе, день считается бизнес-днём точки.

Зарплата и мотивации

GET /reports/payroll?date_from=2026-09-01&date_to=2026-09-30[&point_id={uuid}]

Начисления и выплаты по каждому сотруднику за период. Цифры те же, что на странице Сотрудники → Зарплата в кабинете: оклад или почасовая ставка, мотивационные программы по чекам периода, ручные премии, штрафы и выплаты.

ПараметрОписание
point_idUUID точки, можно несколько через запятую. Без него — все точки бренда одним запросом
date_from, date_toПериод, не длиннее 62 дней
{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "date_from": "2026-09-01",
  "date_to": "2026-09-30",
  "employees": [
    {
      "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
      "point_name": "Чиланзар",
      "employee_id": 11842,
      "employee_name": "Азиз",
      "role": "ROLE_WAITER",
      "role_name": "Официант",
      "position": "Официант зала",
      "salary_type_id": 3,
      "working_days": 22,
      "working_hours": 198.5,
      "sales": 47678973.5,
      "salary_amount": 3000000,
      "motivation_amount": 1907158.94,
      "motivation_programs": [
        {
          "motivation_id": 717,
          "name": "4% от личных продаж",
          "calculation_type": "personal_sales",
          "sales": 47678973.5,
          "amount": 1907158.94
        }
      ],
      "bonus_amount": 200000,
      "fines_amount": 50000,
      "accrued_amount": 5057158.94,
      "paid_amount": 3000000,
      "payments": [
        { "payment_purpose_id": 7, "name": "Зарплата", "is_payout": true, "amount": 3000000, "operations_count": 2 }
      ],
      "balance_start": 0,
      "balance_end": 2057158.94
    }
  ]
}
ПолеОписание
point_id (верхний)Точка запроса, если она одна; при нескольких — null, точка строки в employees[].point_id
point_id, point_nameТочка, по которой посчитан сотрудник. Работает на двух точках — две строки, ведомость поточечная, как в кабинете
salary_type_idТип оплаты должности: 1 по графику, 2 почасовая, 3 оклад, 4 KPI, 5 произвольная, null — не задан
working_days, working_hoursОтработано: по посещаемости, иначе по сменам
salesПродажи сотрудника за период — база для мотиваций
salary_amountОклад или почасовая оплата за период
motivation_amountНачислено по мотивационным программам, всего
motivation_programsТо же по каждой программе: база (sales) и начисление (amount)
bonus_amountПремии, начисленные вручную
fines_amountШтрафы и удержания
accrued_amountИтого начислено за период, за вычетом штрафов
paid_amountВыплачено деньгами
paymentsОперации по назначениям. is_payout: true — деньги выданы, false — начисление или удержание без выдачи
balance_startДолг перед сотрудником на начало периода. null, если заведение не ведёт сальдо по зарплате
balance_endДолг на конец периода: сколько ещё нужно выплатить

accrued_amount — это затраты периода на сотрудника, его берут в P&L. paid_amount — движение денег, его берут в отчёт о движении денежных средств.

Расчёт на лету

Мотивации считаются по чекам в момент запроса. Если заведение изменит программу мотивации задним числом, цифры за прошлый период тоже изменятся. Для хранилища перезагружайте текущий и прошлый месяц.

Кассовые смены

GET /reports/shifts?date_from=2026-09-01&date_to=2026-09-30
GET /reports/shifts?date_from=2026-09-01&date_to=2026-09-30&point_id={uuid}

Смены, закрытые в периоде, с продажами и движением денег — как X-отчёт кассира. Без point_id — все точки бренда. Период — до 92 дней.

GET /reports/shifts?state=open
GET /reports/shifts?state=open&point_id={uuid}

Смены, открытые прямо сейчас. Период не нужен. В cash_balance — наличные в кассе на этот момент, в money — движение денег смены по типам оплат на этот момент. Именно так отвечайте на вопрос «сколько сейчас наличных»: смена и бизнес-день не совпадают (смена может идти с 03:00 до 03:00), поэтому сумма наличных оплат из /reports/olap за календарные даты — не то же самое, что остаток в кассе. У строк есть поле is_open: у открытой смены closed_at пуст.

{
  "date_from": "2026-09-28",
  "date_to": "2026-09-28",
  "shifts": [
    {
      "shift_id": 103542,
      "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
      "point_name": "Mison TEST",
      "shift_number": "09-27",
      "business_date": "2026-09-28",
      "opened_at": "2026-09-27 00:11:51",
      "closed_at": "2026-09-28 01:03:14",
      "is_accepted": true,
      "cashier_login": "cashier1",
      "cashier_name": "Асилбек Каримов",
      "cheques_count": 1721,
      "goods_amount": 224510790,
      "discount": 272850,
      "delivery_amount": 1470000,
      "revenue": 237045590,
      "debt_amount": 19769000,
      "deleted_cheques_count": 11,
      "deleted_cheques_amount": 788750,
      "deleted_items_count": 3,
      "deleted_items_amount": 129000,
      "cash_balance": 159644656,
      "money": [
        {
          "payment_type_id": 218,
          "payment_type_name": "Наличные",
          "payment_category_id": 1,
          "payment_purpose_id": 1,
          "payment_purpose_name": "Продажа",
          "direction": "plus",
          "amount": 165359495
        },
        {
          "payment_type_id": 218,
          "payment_type_name": "Наличные",
          "payment_category_id": 1,
          "payment_purpose_id": 757,
          "payment_purpose_name": "Закупка продуктов",
          "direction": "minus",
          "amount": 4319950
        }
      ]
    }
  ]
}
ПолеОписание
business_dateБизнес-день закрытия смены
is_acceptedСмена принята старшим кассиром или бухгалтером
revenueВыручка закрытых чеков смены с обслуживанием и доставкой
debt_amountИз выручки — продано в долг
deleted_cheques_*Удалённые за смену чеки: количество и сумма
deleted_items_*Позиции, удалённые из закрытых чеков смены: число строк и сумма. Позиции удалённого целиком чека сюда не входят — они уже в deleted_cheques_amount, так что «всего удалено» = deleted_cheques_amount + deleted_items_amount
cash_balanceНаличные в кассе на закрытии смены
moneyДвижение денег по типу оплаты и назначению

В money каждая строка — сумма операций одного типа оплаты и одного назначения: direction: plus — деньги пришли, minus — ушли (расход из кассы, выплата, возврат). Долг и бонусы деньги не двигают и приходят с direction: neutral.

Расходы кассы по дням и статьям за месяц удобнее брать из движения денег: source=cashbox&direction=minus&group_by=day_purpose.

Движение денег

GET /reports/money-movements?date_from=2026-10-01&date_to=2026-10-13
GET /reports/money-movements?date_from=2026-10-01&date_to=2026-10-13&source=safe,bank
GET /reports/money-movements?date_from=2026-09-01&date_to=2026-09-30&point_id={uuid}&source=cashbox&direction=minus&group_by=day_purpose

Приход и расход денег за период: касса, сейф, расчётный счёт и другие денежные счета — дата, точка, сумма, направление, статья, источник. Период — до 92 дней, point_id необязателен. День операции — бизнес-день точки по времени операции.

ПараметрОписание
sourceИсточники через запятую, по умолчанию все (см. таблицу ниже)
directionplus — только приход, minus — только расход
group_bymovement (по умолчанию) — операции списком в movements; day — итоги по дням; purpose — по статьям; day_purpose — по дням и статьям. Итоги приходят в groups

Источники:

sourceЧто входит
cashboxКасса: операции кассира в смене без продаж — расходы и приходы по статьям, выплаты сотрудникам, погашения долгов, предоплаты. Продажи кассы — в сменах и OLAP
safeСейф и счета, заведённые внутри него
cashПрочие наличные счета (ветка «Денежные средства, наличные», кроме кассы и сейфа)
bankБезналичные: расчётный счёт, эквайринг, деньги в пути и счета внутри этой ветки
accountableДеньги под отчётом

Источник определяется по ветке плана счетов, куда заведение поставило счёт. Названия своих счетов заведение даёт само — например, счёт «Карта» может стоять внутри «Сейфа», тогда его операции придут с source: safe и account_name: "Карта".

{
  "date_from": "2026-10-12",
  "date_to": "2026-10-12",
  "group_by": "movement",
  "totals": [
    { "source": "safe", "plus": 35213000, "minus": 35213000, "count": 26 }
  ],
  "movements": [
    {
      "point_id": "c91fdd54-a539-44ab-8a8f-103838d31388",
      "point_name": "Donerci Bilal",
      "register": "account",
      "id": 526862,
      "business_date": "2026-10-12",
      "created_at": "2026-10-12 18:34:27",
      "source": "safe",
      "account_id": 7,
      "account_code": "1.03",
      "account_name": "Сейф",
      "direction": "plus",
      "amount": 498000,
      "operation": "organization_payment",
      "payment_purpose_id": 952,
      "payment_purpose_name": "Tashkilotdan to'lov",
      "payment_type_id": null,
      "payment_type_name": null,
      "shift_id": null,
      "note": null
    }
  ]
}
ПолеОписание
registershift — операция кассы в смене, account — проводка по счёту. Пара register + id уникальна
account_*Счёт плана, по которому прошли деньги. У операций кассы в смене пусто
directionplus — деньги пришли, minus — ушли
operationЧто за операция, см. ниже
payment_purpose_*Статья (тип прихода или расхода). У сдачи выручки, переводов и корректировок пусто
payment_type_*Тип оплаты операции на кассе (наличные, карта)
shift_idСмена: у операций кассы и у сдачи выручки смены в сейф или банк

Значения operation:

operationОперация
expenseПриход или расход по статье
salaryВыплата сотруднику (зарплата, аванс) или возврат от него
organization_paymentОрганизация погасила долг — подробнее в оплатах организаций
supplier_paymentОплата поставщику
client_paymentКлиент погасил долг
shift_revenueВыручка смены сдана в сейф или банк при приёме смены
shift_accept_diffНедостача или излишек при приёме смены
transferПеревод между своими счетами
correctionРучная корректировка остатка счёта
prepayment, prepayment_refundПредоплата заказа и её возврат
otherПрочее

С group_by вместо movements приходит groups. Строка итога — source, direction, count, amount; с day и day_purpose ещё business_date, с purpose и day_purpose — operation, payment_purpose_id, payment_purpose_name:

{
  "group_by": "day_purpose",
  "totals": [{ "source": "cashbox", "plus": 0, "minus": 292951020, "count": 872 }],
  "groups": [
    {
      "business_date": "2026-09-01",
      "source": "cashbox",
      "direction": "minus",
      "operation": "salary",
      "payment_purpose_id": 374,
      "payment_purpose_name": "Xodimlar uchun naqd pul (kassa)",
      "count": 10,
      "amount": 1598000
    }
  ]
}

Что важно знать:

  • Перемещения между своими деньгами — не доход и не расход. Перевод между счетами (transfer) приходит двумя строками: расход одного счёта и приход другого. Сдача выручки смены (shift_revenue) — приход в сейф или банк тех денег, что уже посчитаны в смене. Для оборота по всем источникам вместе исключайте transfer и shift_revenue.
  • Отменённые операции не приходят. Удалённый расход или выплата не стирается, а гасится встречной проводкой — такие пары в отчёт не попадают, иначе расход сидел бы в расходах по статье, а его отмена — в приходах.
  • Продажи кассы сюда не входят — это смены и OLAP.

Вопросы и ответы:

  • «Расходы пиццерии по дням за сентябрь» — point_id точки, source=cashbox&direction=minus&group_by=day_purpose. Если расходы делают и из сейфа — уберите source или укажите source=cashbox,safe.
  • «Сколько пришло на расчётный счёт за неделю» — source=bank&direction=plus&group_by=purpose.
  • «Куда ушли деньги из сейфа» — source=safe&direction=minus&group_by=purpose.

Новые клиенты и организации

GET /reports/registrations?date_from=2026-09-01&date_to=2026-09-30&group_by=month

Сколько клиентов и организаций зарегистрировано в базе заведения за период. Считается по дате создания записи, удалённые не считаются. Клиенты и организации общие на бренд, поэтому отчёт — по всему бренду, без point_id.

ПараметрОписание
date_from, date_toПериод, YYYY-MM-DD, обе даты включительно. Не длиннее 366 дней
group_bydate, week (дата понедельника) или month. По умолчанию month
{
  "date_from": "2026-08-01",
  "date_to": "2026-09-30",
  "group_by": "month",
  "rows": [
    { "month": "2026-08", "new_clients": 1950, "new_organizations": 2 },
    { "month": "2026-09", "new_clients": 1700, "new_organizations": 0 }
  ],
  "totals": { "new_clients": 3650, "new_organizations": 2 }
}

Периоды без регистраций не приходят. Точки своего бренда, заведённые организациями для перемещений между логинами, в new_organizations не входят.

Сколько клиентов и организаций купило за период — это OLAP: показатели clients_count и organizations_count в POST /reports/olap.

Посещаемость сотрудников

GET /reports/attendance?date_from=2026-09-01&date_to=2026-09-30&point_id={uuid}

Приход и уход сотрудников — те же отметки, что на странице «Посещаемость» кабинета: камера, касса, ручной ввод. Период — до 62 дней, point_id можно не передавать (тогда по всем точкам ключа) или передать несколько через запятую.

{
  "date_from": "2026-09-29",
  "date_to": "2026-09-30",
  "employees": [
    {
      "employee_id": 3873,
      "employee_login": "user3873",
      "employee_name": "Абдулазиз Каримжонов",
      "position_name": "Повар",
      "hours": 21.21,
      "open_shifts": 0,
      "worked_days": 2
    }
  ],
  "shifts": [
    {
      "employee_id": 3873,
      "employee_login": "user3873",
      "employee_name": "Абдулазиз Каримжонов",
      "position_name": "Повар",
      "point_id": "c91fdd54-a539-44ab-8a8f-103838d31388",
      "point_name": "Центральная",
      "date": "2026-09-29",
      "check_in": "2026-09-29 07:00:00",
      "check_out": "2026-09-29 15:22:11",
      "hours": 8.37
    }
  ]
}
ПолеОписание
shiftsКаждая отметка: приход, уход, часы. Смена относится к дню прихода
check_outnull — уход не отмечен: сотрудник ещё на смене или забыл отметиться. hours тогда тоже null
employeesИтог по сотруднику: часы, дни с отметками и число смен без ухода (open_shifts)

Уход раньше прихода (сбой отметки) в часы не идёт. Опоздания относительно графика отчёт не считает — только фактические отметки.

Организации и их долг

GET /reports/organizations?point_id={uuid}&only_debt=true

Организации-покупатели заведения (юрлица, которые берут в долг, агрегаторы) с текущим балансом расчётов. Без point_id баланс складывается по всем точкам ключа, only_debt=true оставляет только тех, кто должен.

{
  "count": 135,
  "totals": { "debt": 3644991883, "prepaid": 0 },
  "organizations": [
    {
      "organization_id": 667,
      "name": "EFKA kafe",
      "short_name": null,
      "tin": null,
      "phone": "998901234567",
      "address": null,
      "region_id": 3,
      "region_name": "Андижанская область",
      "district_id": 49,
      "district_name": "г. Андиджан",
      "is_own_point": false,
      "debt_limit": 2000000,
      "created_at": "2026-02-20 11:31:48",
      "balance": -250
    }
  ]
}
ПолеОписание
balanceМинус — организация должна заведению, плюс — заплатила вперёд
totals.debtСколько всего должны организации (сумма минусов, положительным числом)
totals.prepaidСколько организации заплатили вперёд
is_own_pointОрганизация — это точка своего бренда (для перемещений между логинами)
debt_limitЛимит долга из карточки, null — без лимита

Баланс — текущий, на момент запроса: date_from и date_to этот отчёт не принимает. Сколько организации купили и на какую сумму за период — это OLAP, группировка organization в POST /reports/olap, сколько заплатили — оплаты организаций.

Оплаты организаций

GET /reports/organization-payments?date_from=2026-10-01&date_to=2026-10-13
GET /reports/organization-payments?date_from=2026-10-01&date_to=2026-10-13&organization_id=456

Погашение долга организациями за период: на кассе в смену, из кабинета на счёт (сейф, расчётный счёт, карта) и переводом от точки своей сети. Период — до 92 дней, point_id необязателен, organization_id — из /reports/organizations.

Сюда не входит то, что не деньги: возврат долгового чека, корректировка долга, отгрузки. Отменённая оплата не приходит.

{
  "date_from": "2026-10-01",
  "date_to": "2026-10-13",
  "totals": {
    "count": 479,
    "amount": 2816493685,
    "by_source": { "safe": 726246300, "bank": 1142606385, "cash": 947641000 }
  },
  "payments": [
    {
      "payment_id": 319590,
      "point_id": "c91fdd54-a539-44ab-8a8f-103838d31388",
      "point_name": "Donerci Bilal",
      "business_date": "2026-10-01",
      "created_at": "2026-10-01 00:06:45",
      "organization_id": 456,
      "organization_name": "Tosh Weel food Oxangaron",
      "amount": 7700000,
      "source": "safe",
      "account_id": 7,
      "account_name": "Сейф",
      "payment_type_id": null,
      "payment_type_name": null,
      "payment_category_id": null,
      "shift_id": null,
      "is_internal": false,
      "note": null
    }
  ]
}
ПолеОписание
sourceКуда пришли деньги — те же значения, что в движении денег: cashbox, safe, cash, bank, accountable
account_*Счёт, на который пришла оплата (название — как у заведения)
payment_type_*, payment_category_idТип оплаты, если оплату приняли на кассе
shift_idСмена, если оплату приняли на кассе
is_internalОплата от точки своей сети Mison (взаиморасчёт между логинами)
totals.by_sourceСумма оплат по источникам

Поставщики и долг перед ними

GET /reports/suppliers?point_id={uuid}&only_debt=true

Поставщики заведения с текущим балансом расчётов. Параметры — как у организаций.

{
  "count": 26,
  "totals": { "debt": 2866390412.05, "prepaid": 1637952.68 },
  "suppliers": [
    {
      "supplier_id": 2690,
      "name": "Аброр Кочa Махсулотлар",
      "phone": "998901234567",
      "tin": null,
      "type_name": null,
      "is_internal": false,
      "created_at": "2026-07-29 11:18:13",
      "balance": -288003.6
    }
  ]
}
ПолеОписание
balanceМинус — заведение должно поставщику (товар принят в долг), плюс — заплатило вперёд
totals.debtСколько всего заведение должно поставщикам
totals.prepaidСколько заплачено поставщикам вперёд
is_internalВнутренний поставщик — своя точка или склад

ABC- и XYZ-анализ товаров

GET /reports/abc-xyz?date_from=2026-07-14&date_to=2026-10-13
GET /reports/abc-xyz?date_from=2026-07-14&date_to=2026-10-13&point_id={uuid}&abc_by=gross_profit
GET /reports/abc-xyz?date_from=2026-09-01&date_to=2026-10-13&bucket=day&with_series=true

Каждому товару — две буквы: вклад в продажи (ABC) и стабильность спроса (XYZ). Продажи те же, что в OLAP SALES. Период — до 92 дней.

ABC — товары по убыванию вклада в итог по abc_by: A — первые 80 %, B — следующие 15 %, C — остальное.

XYZ — коэффициент вариации проданного количества по неделям (или дням): стандартное отклонение / среднее × 100. Неделя без продаж товара считается нулём. X — до 10 %, спрос ровный; Y — до 25 %, колеблется; Z — больше, спрос нерегулярный.

ПараметрОписание
bucketweek (по умолчанию) — по неделям, day — по дням. По дням вариация у ресторанных товаров почти всегда высокая, обычно смотрят по неделям
abc_bynet_amount (по умолчанию) — выручка, gross_profit — валовая прибыль, quantity — штуки
x_max, y_maxСвои границы XYZ в процентах, по умолчанию 10 и 25
menu_ids, category_idsТолько товары из этих папок меню или категорий
with_seriestrue — у каждого товара ещё и продажи по неделям (дням) в series

Как выбирается период:

  • По неделям берутся только целые недели с понедельника по воскресенье: неполная неделя занизила бы продажи и раздула вариацию. Фактический период — в date_from и date_to ответа.
  • Анализ начинается не раньше первого чека выбранных точек: если заведение начало работать в Mison позже начала периода, дни до этого не считаются нулевыми продажами. Тогда в ответе заполнено active_from.
  • Нужно минимум 4 целые недели или 14 дней, иначе ответ 400.
{
  "date_from": "2026-09-14",
  "date_to": "2026-10-11",
  "active_from": "2026-09-10",
  "bucket": "week",
  "buckets_count": 4,
  "abc_by": "net_amount",
  "thresholds": { "abc": [80, 95], "x_max": 10, "y_max": 25 },
  "products_count": 294,
  "matrix": { "AX": 3, "AY": 27, "AZ": 42, "BY": 10, "BZ": 68, "CY": 1, "CZ": 143 },
  "data_freshness": [
    { "point_id": "0e180d32-aa78-46b0-999e-4e10f4947d03", "point_name": "Taksim Kebab С-1", "last_sync_at": "2026-10-14 12:53:36" }
  ],
  "products": [
    {
      "product_id": 256437,
      "product_name": "ISKANDER BEEF",
      "unit_name": "кг",
      "quantity": 383,
      "net_amount": 40750991.21,
      "gross_profit": 35631859.21,
      "share_percent": 7.29,
      "cumulative_percent": 7.29,
      "abc": "A",
      "buckets_with_sales": 4,
      "avg_quantity": 95.75,
      "std_quantity": 8.671,
      "cv_percent": 9.06,
      "xyz": "X",
      "class": "AX"
    }
  ]
}
ПолеОписание
share_percent, cumulative_percentДоля товара в итоге по abc_by и накопленная доля с начала списка
buckets_with_salesСколько недель (дней) из buckets_count товар продавался
avg_quantity, std_quantityСреднее и стандартное отклонение продаж за неделю (день)
cv_percentКоэффициент вариации, null — продаж не было
matrixСколько товаров в каждом классе
data_freshnessКогда точки последний раз присылали чеки — как в OLAP

Как читать: AX — главные и стабильные товары, их не должно не хватать; AZ — важные, но непредсказуемые, запас под них держать дорого; CZ — кандидаты на вывод из меню.

Список товаров

GET /reports/products?point_id={uuid}
GET /reports/products?types=prep,item&status=all
GET /reports/products?menu_ids=38261&search=burger

Справочник товаров бренда: тип, папка меню, единица, штрихкод — и по каждой точке цена продажи, себестоимость и стоп-лист. Те же цифры, что в кабинете на странице Меню → Товары.

Это не меню для заказа. Витрину для гостя берите в /menus, а этот отчёт — для аналитики и ответов на вопросы вроде «сколько стоит» и «какой фудкост»: он работает без выбранной на ключе витрины и отдаёт заготовки, сырьё и снятое с продажи.

ПараметрОписание
point_idUUID точки, можно несколько через запятую. Без него — все точки бренда
typesТипы товаров через запятую: product — продаваемый товар, prep — заготовка, item — сырьё, modifier — модификатор, service — услуга. Без параметра — все
statusactive (по умолчанию) — активные, inactive — скрытые, all — и те и другие. Удалённые не приходят
menu_idsПапки меню через запятую, вместе с вложенными. Id — из /reports/menu-folders
searchЧасть названия, штрихкода или PLU, без учёта регистра
{
  "count": 1,
  "items": [
    {
      "product_id": 205571,
      "name": "Говядина 10/90",
      "type": "product",
      "type_name": "Продукт",
      "is_active": true,
      "menu_id": 38261,
      "menu_name": "10/90 1%",
      "menu_path": "10/90 / 10/90 1%",
      "category_id": 382,
      "category_name": "Мясо",
      "unit": "кг",
      "is_divisible": true,
      "barcode": null,
      "plu": "287",
      "fiscal_code": null,
      "size_parent_id": null,
      "image": null,
      "base_price": 87000,
      "updated_at": "2026-10-12 16:15:44",
      "points": [
        {
          "point_id": "c91fdd54-a539-44ab-8a8f-103838d31388",
          "point_name": "Чиланзар",
          "price": 87000,
          "cost_price": 57873.71,
          "cost_percent": 66.52,
          "is_on_sale": true,
          "is_on_stop": false,
          "stop_quantity": null
        }
      ]
    }
  ]
}
Поле товараОписание
typeТип товара, см. параметр types
menu_id, menu_name, menu_pathПапка меню и путь до неё от верхней папки
category_id, category_nameУчётная категория — для склада и отчётов, а не раздел меню
is_divisibleПродаётся на вес (дробное количество)
size_parent_idУ размера товара — товар, к которому относится размер
base_priceЦена в карточке товара. Точка может продавать по своей — она в points[].price
Поле точкиОписание
priceЦена продажи на точке сейчас — по ней посчитает касса. Учитывает прейскурант точки и колонку цен, действующую в это время по расписанию меню
cost_priceСебестоимость на точке. null — не рассчитана
cost_percentФудкост: себестоимость в процентах от цены
is_on_salefalse — на этой точке товар снят с продажи, или его раздел меню закрыт для точки
is_on_stop, stop_quantityТовар в стоп-листе. stop_quantity = 0 — нет совсем, больше нуля — осталось столько

Ответ ограничен 50 000 строк «товар × точка». У большой сети без фильтров это может не поместиться — сузьте запрос по point_id или types.

Стоп-лист

GET /reports/stop-list?point_id={uuid}
GET /reports/stop-list?min_days=3

Что сейчас стоит на стопе по точкам и с какого времени. Удобно для вопросов «что закончилось в каждом филиале» и «что давно на стопе».

ПараметрОписание
point_idUUID точки, можно несколько через запятую. Без него — все точки бренда
min_daysТолько позиции, стоящие на стопе не меньше стольких суток. Можно дробно: 0.5 — полдня
{
  "count": 1,
  "items": [
    {
      "point_id": "c91fdd54-a539-44ab-8a8f-103838d31388",
      "point_name": "Чиланзар",
      "product_id": 49678,
      "product_name": "Фарш 50/50 5 кг",
      "category_id": null,
      "category_name": null,
      "menu_id": 1526,
      "menu_name": "Мясо",
      "quantity": 0,
      "put_at": "2026-08-02 08:47:39",
      "put_by": "user5087",
      "days_on_stop": 73.9
    }
  ]
}
ПолеОписание
quantity0 — товара нет совсем, больше нуля — осталось столько единиц
put_atКогда позицию поставили на стоп. Изменение остатка стопа время не сдвигает, повторная постановка — сдвигает
put_byКто поставил: логин сотрудника
days_on_stopСколько суток позиция на стопе

Для приложения, которое принимает заказы, есть лёгкий GET /stop-list без названий: он не требует доступа к отчётам и рассчитан на опрос раз в минуту.

Остатки на складах

GET /reports/stock?point_id={uuid}&date=2026-09-30

Остатки на конец дня по всем складам точки: количество, средняя себестоимость и сумма. Позиции с нулевым остатком не приходят. Остатки хранятся 18 месяцев.

{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "date": "2026-09-30",
  "items": [
    {
      "wms_id": 240,
      "wms_name": "Основной склад",
      "product_id": 49617,
      "product_name": "Пакет целлофановый",
      "unit_name": "кг",
      "category_id": 92,
      "category_name": "Инвентарь",
      "quantity": 2.3,
      "average_price": 29152.2,
      "amount": 67050.06
    }
  ]
}

Остаток бывает отрицательным: касса продала больше, чем было оприходовано.

Два параметра для поиска проблемных позиций:

ПараметрОписание
only_negative=trueТолько позиции, ушедшие в минус
with_last_receipt=trueВ каждой позиции — last_receipt_at, дата и время последнего проведённого прихода в эту точку. null — прихода не было. Позиции, которые давно не оприходовали, видны по старой дате

Приходы от поставщиков

GET /reports/receipts?date_from=2026-10-01&date_to=2026-10-07&point_id={uuid}
GET /reports/receipts?date_from=2026-10-01&date_to=2026-10-07&group_by=supplier
GET /reports/receipts?date_from=2026-10-01&date_to=2026-10-07&group_by=product&supplier_id=2814
GET /reports/receipts?date_from=2026-09-18&date_to=2026-10-18&group_by=price
GET /reports/receipts?date_from=2026-09-18&date_to=2026-10-18&group_by=price&product_id=47940

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

ПараметрОписание
group_bydocument (по умолчанию) — список документов; supplier — итоги по поставщикам; product — итоги по товарам; price — динамика закупочной цены (ниже)
supplier_idТолько этот поставщик (supplier_id из /reports/suppliers)
product_idТолько документы, где есть этот товар; в разрезе product и price — только этот товар
only_changedТолько для price. true по умолчанию — товары, у которых цена в приходах различалась (или была нулевая); false — все
min_change_percentТолько для price. Порог разброса цены в процентах: «где цена отличается больше чем на 5 %»
{
  "date_from": "2026-10-02",
  "date_to": "2026-10-02",
  "group_by": "document",
  "totals": { "documents_count": 12, "amount": 426250596.8 },
  "documents": [
    {
      "document_id": 194286,
      "document_number": null,
      "point_id": "c91fdd54-a539-44ab-8a8f-103838d31388",
      "point_name": "Donerci Bilal",
      "supplier_id": 2814,
      "supplier_name": "Fayzullo",
      "wms_id": 265,
      "wms_name": "Asosiy xom ashyo ombori",
      "amount": 146000000,
      "created_at": "2026-10-02 13:22:50",
      "pay_debt_at": null,
      "note": null
    }
  ]
}

С group_by=supplier вместо documents приходит suppliers: supplier_id, supplier_name, documents_count, amount, last_receipt_at. С group_by=product — products: product_id, product_name, unit_name, documents_count, quantity, amount, last_receipt_at.

Вопросы и ответы:

  • «С каких организаций сколько прихода за неделю» — group_by=supplier.
  • «Приходил ли хлеб в тот день» — group_by=product, date_from = date_to = нужный день, товар найдите по имени в строках.
  • «Что не оприходовано» — товары остатков с пустым или старым last_receipt_at в /reports/stock?with_last_receipt=true.

Движение товаров

GET /reports/stock-movements?point_id={uuid}&date_from=2026-09-01&date_to=2026-09-30

Обороты по складу за период: что пришло, продано, списано, перемещено, посчитано на инвентаризации. Период — до 31 дня, история хранится 12 месяцев.

{
  "point_id": "f40d9ea6-bb66-4d8a-9185-219916b68224",
  "date_from": "2026-09-01",
  "date_to": "2026-09-30",
  "movements": [
    {
      "wms_id": 240,
      "wms_name": "Основной склад",
      "product_id": 49787,
      "product_name": "Зубочистка",
      "unit_name": "шт",
      "movement_type_id": 2,
      "movement_type_name": "Прием от поставщика",
      "movement_kind": "income",
      "direction": "plus",
      "quantity": 5000,
      "amount": 250000
    }
  ]
}
ПолеОписание
movement_type_id / _nameОперация: приход, продажа, списание, перемещение и так далее
movement_kindincome — приход, expense — расход, inventory — инвентаризация
directionplus — остаток вырос, minus — уменьшился
quantityКоличество, всегда положительное. Знак — в direction
amountСумма по себестоимости

Удаление документа приходит отдельной операцией с обратным direction, а не исчезает из истории. Поэтому обороты за закрытый период не меняются задним числом.

Остаток на конец периода = остаток на начало + сумма plus − сумма minus.

Подписка на Mison

GET /reports/subscriptions
GET /reports/subscriptions?point_id={uuid}

Какие точки бренда оплатили Mison и какие подключённые услуги у них сейчас работают. Нужен, если ваше приложение само продаётся заведению вместе с Mison: по ответу можно закрыть доступ точке, которая не заплатила.

Решение о доступе принимает тот же код, что блокирует кассу и кабинет, — повторять расчёт на своей стороне не надо, достаточно смотреть на access_allowed.

ПараметрОписание
point_idUUID одной точки. Без него — все точки бренда

В ответ попадают и заблокированные за неоплату точки — их нет в GET /points, но здесь они есть, иначе их нельзя было бы отличить от удалённых. Удалённые точки не приходят.

{
  "count": 1,
  "points": [
    {
      "point_id": "84c231b9-5c40-4dd9-a066-bfd6989f2b6f",
      "point_name": "Эски шахар",
      "point_status": 1,
      "tariff": 500000,
      "paid_until": "2026-10-31",
      "free_until": null,
      "access_allowed": true,
      "services": [
        {
          "code": "fiscalization",
          "name": "Фискализация",
          "price": 100000,
          "is_active": true,
          "started_at": "2026-07-30",
          "ended_at": null,
          "grace_until": null,
          "access_allowed": true
        }
      ]
    }
  ]
}
Поле точкиОписание
point_status1 — работает, -1 — заблокирована за неоплату
tariffАбонентская плата за месяц
paid_untilДо какого дня оплачена абонентская плата
free_untilДо какого дня точка работает бесплатно (пробный период). null — не работает
access_allowedГлавное поле. true — точка может работать: абонентка за месяц оплачена, идёт бесплатный период, выдана отсрочка или долг в пределах лимита
servicesПодключённые платные услуги
Поле услугиОписание
codeКод услуги: fiscalization — фискализация, ai_assistant_bot — бот-ассистент, sms_notifications — SMS-уведомления
priceЦена услуги в месяц. 0 — бесплатно
is_activeУслуга подключена. false — отключена, доступа по ней нет
started_at, ended_atПериод подключения. ended_at = null — без даты окончания
grace_untilОтсрочка оплаты: до этого дня услуга работает, даже если счёт не оплачен
access_allowedУслуга работает: бесплатна, действует отсрочка или счёт за месяц оплачен

Если ваше приложение — одна из услуг Mison (например, бот-ассистент), проверяйте access_allowed именно у неё: точка может работать, а услуга — нет, если её счёт не оплачен.

Разница цен прихода

group_by=price отвечает на вопрос «по каким товарам цена прихода различается». Один товар — одна строка в products, сортировка по разбросу цены от большего к меньшему:

ПолеЗначение
first_price, last_priceЦена в первом и в последнем приходе периода
min_price, max_price, avg_priceМинимальная, максимальная и средневзвешенная (по количеству) цена
prices_countСколько разных ненулевых цен встретилось
spread_percentРазброс: на сколько максимум выше минимума, %
change_percentДинамика: на сколько последняя цена отличается от первой, %
min_price_supplier, max_price_supplierПоставщик с самой низкой и с самой высокой ценой
zero_price_documentsВ скольких документах товар оприходован по нулевой цене — это ошибка ввода, в мин/сред цену не входит

С product_id в строке товара приходит documents — цена в каждом документе по порядку (номер, дата, поставщик, количество, цена): видно, где и когда она менялась.