Схемы Что нового

Отчёты

Готовые и произвольные отчёты, аудит операций, журналы платежей и сообщений, должники. Здесь же — раздел геймификации.

Модуль «Отчёты и аналитика» — на сайте продукта
Содержание раздела

Отчёты

Раздел меню «Отчёты» объединяет аналитику для руководителя, библиотеку SQL-отчётов, аудит действий персонала и журналы.

Панель директора

Содержание раздела

Панель директора (/admin/reports/dashboard/, сайдбар «Отчёты → Панель директора») отвечает на четыре вопроса о бизнесе за выбранный период: сколько денег пришло, сколько в среднем приносит клиент, сколько людей подключилось и сколько заблокировано. Ниже — шесть графиков по тем же данным в динамике.

Панель директора: показатели «Сейчас» и «За период», пропущенные звонки (демо-данные)
Панель директора: показатели «Сейчас» и «За период», пропущенные звонки (демо-данные)

Выпуск 3.7.0: общий каркас и одно правило денег

Шапка страницы — общий каркас: название со справкой, календарь периода и кнопка фильтров в одной строке. Блоки — карточками одного вида, звонки — отдельной строкой показателей. На телефоне период и фильтры стоят в одну линию, показатели идут в две колонки.

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

flowchart LR
    OP["Финансовая операция"] --> ST{"Сторнирована?"}
    ST -- да --> X["Не считается"]
    ST -- нет --> SG{"Знак суммы
и тип операции"} SG -- "сумма > 0, тип «приход»,
не обещанный платёж" --> PAY["Поступление"] SG -- "сумма < 0, тип «расход»,
не списание обещанного" --> CH["Списание"] SG -- иначе --> X

ARPU — поступления за месяц, делённые на клиентскую базу этого месяца (не удалённые клиенты, созданные до конца месяца). Прошлый период для сравнения берётся той же длины, что выбранный. «Активных» — не удалённые клиенты без блокировки.

Панель директора на телефоне
На телефоне: период и фильтры в одну строку, показатели в две колонки

Карта раздела

- Панель директора
  - Показатели
    - Выручка за период
    - ARPU
    - Новые клиенты
    - Заблокировано за период
  - Графики
    - Популярность тарифов
    - Новые клиенты
    - Поступающие средства
    - Платящие клиенты
    - ARPU по месяцам
    - ARPPU по месяцам
  - Срезы
    - Период и пресеты
    - Сегмент физ-юр
    - Канал оплаты
    - Тариф
    - Точка подключения
    - Шаг день-неделя-месяц
    - Сравнение с прошлым или годом назад
  - Правила
    - Данные своей организации
    - Клик по показателю ведёт в список
    - Ошибка отличается от пустоты

Четыре показателя и как они считаются

Формулы важнее оформления: по этим цифрам принимают решения, поэтому каждая должна читаться однозначно.

ПоказательЧто именно считаетсяСравнение
Выручка за период Сумма приходных финансовых операций (OP_SUMMA > 0) с датой внутри периода. Верхняя граница берётся включительно, до 23:59:59 последнего дня. к предыдущему периоду такой же длины
ARPU Выручка периода ÷ база клиентов на конец периода (не удалённые, заведённые до этой даты). У прошлого периода — свой знаменатель, поэтому дельта ARPU не повторяет дельту выручки. к тому же показателю прошлого периода
Новых клиентов Клиенты с датой создания внутри периода. к предыдущему периоду
Заблокировано за период Клиенты, у которых блокировка началась внутри периода (ABONENTS_BLOCK.B_DATE). В подписи — сколько из них за неоплату и сколько клиентов активно сейчас. Рост показан красным: блокировок больше — это плохая новость. к предыдущему периоду
Почему «Заблокировано», а не «Отток». До июля 2026 карточка называлась «Отток» и показывала 2 099 на любом периоде: расчёт обращался к несуществующим полям журнала аудита, ошибка гасилась молча, и вместо оттока выводилось общее число отключённых за всю историю. Теперь метрика привязана к дате блокировки и меняется вместе с периодом.

Шесть графиков

ГрафикЧто показывает
Популярность тарифовРаспределение клиентов по тарифам (без заблокированных). Хвост сворачивается в «Прочие».
Новые клиентыСколько подключилось в каждом периоде.
Поступающие средстваПриход по периодам — та же выручка в динамике.
Платящие клиентыСколько разных клиентов платили в периоде.
ARPUВыручка периода ÷ база клиентов на его конец.
ARPPUВыручка периода ÷ число заплативших — средний чек платящего.

Если данных за период нет, карточка так и говорит: «За выбранный период данных нет». Если запрос не выполнился — это отдельное сообщение «Не удалось загрузить» с кнопкой «Повторить», чтобы сбой сервера не выглядел как «в этом месяце ничего не было».

Период и фильтры

Панель фильтров: сегмент, канал оплаты, тариф, точка подключения, шаг графиков и сравнение
Панель фильтров: сегмент, канал оплаты, тариф, точка подключения, шаг графиков и сравнение

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

ФильтрЗначенияЗачем
СегментВсе · Физлица · ЮрлицаУ юрлиц другой чек и другая сезонность — смешивать их с частниками бессмысленно
Канал оплатытипы приходных операцийВидно, через что реально идут деньги
Тарифмультивыбор, рядом число клиентовКак живёт конкретный тариф или линейка
Точка подключениямультивыбор по населённым пунктамСрез по географии: посёлок, СНТ, город
Шаг графиковМесяц · Неделя · ДеньДневной шаг показывает всплески внутри месяца
Сравнивать спредыдущим периодом · тем же периодом год назадГодовое сравнение снимает сезонность

Выбранный набор сохраняется между заходами, сбрасывается ссылкой «Сбросить фильтры». Списки тарифов и точек показывают количество клиентов — выбирать можно осознанно.

Срез по юрлицам: показатели пересчитаны только по юрлицам, на кнопке «Фильтры» — число включённых
Срез по юрлицам: показатели пересчитаны только по юрлицам, на кнопке «Фильтры» — число включённых
Про точку подключения. Срез строится по записям CONNECTION_POINTS, названным по населённому пункту. Клиенты без точки в такой срез не попадают, поэтому под фильтром показано, скольких это касается. Массово назначить точки по адресу помогает команда manage.py assign_connection_points (с предпросмотром и откатом).

Откуда берутся цифры

flowchart LR
    FO["Финансовые операции
finance_operations"] --> REV["Выручка
Поступающие средства"] FO --> PAY["Платящие клиенты
ARPPU"] AB["Клиенты
abonents"] --> BASE["База клиентов"] BASE --> ARPU["ARPU"] REV --> ARPU AB --> NEW["Новые клиенты"] AB --> TAR["Популярность тарифов"] BL["Блокировки
ABONENTS_BLOCK"] --> BLK["Заблокировано
за период"] ORG["Организация"] -.->|"фильтр"| FO ORG -.->|"фильтр"| AB ORG -.->|"фильтр"| BL

Теперь все шесть считаются из финансовых операций и карточек клиентов, то есть из тех же данных, что и KPI.

Мульти-организации

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

Фильтрация применяется ко всем шести графикам и ко всем четырём показателям, а также к спискам тарифов и точек в самих фильтрах: под чужую организацию не попадут ни её тарифы, ни её посёлки.

Переход к деталям

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

Тёмная тема и телефон

Графики перерисовываются вместе со сменой темы, перезагрузка не нужна. На телефоне показатели встают в две колонки, фильтры — в одну, горизонтальной прокрутки нет.

Фильтры на телефоне
Фильтры на телефоне

Пользовательские SQL-отчёты — назначение и роль

Содержание раздела

AdminCustomReports — таблица сохранённых SQL-запросов, доступных оператору через UI. Каждая запись = один отчёт с именем, описанием и SQL-кодом. Хранится в таблице ADMIN_CUSTOM_REPORTS, редактируется на /admin/reports/AdminCustomReports/.

Зачем нужны кастомные отчёты

Биллинг — это система с ~150 таблицами и 600+ полей. Готовых отчётов в админке всегда не хватает: бухгалтер хочет один формат, директор — другой, техподдержка — третий. Решение:

  1. Гибкость без релизов — оператор-аналитик пишет SQL прямо через UI, без ожидания deployment'а;
  2. Параметризация — встроенный синтаксис :Имя|тип$ позволяет добавлять параметры (даты, клиент, сумма) без знания Python;
  3. Экспорт — результат отчёта сразу в Excel/CSV/DBF без программирования;
  4. Историческая часть — каждый запуск сохраняется в AdminCustomReportsHistory, можно вернуться к старому результату.
Поля и связанные таблицы
Поле ADMIN_CUSTOM_REPORTSНазначение
NAMEНазвание отчёта (видно в UI)
DESCRIPTIONОписание для оператора (что отчёт показывает)
SMTPSQL-код запроса (text) — исторически поле называется SMTP, verbose «SQL запрос»; именно из него исполняется отчёт
REPORT_TYPEFK на AdminCustomReportsType — категория
ALLOW_IN_CABINETВидим ли клиенту в ЛК (раздел «Мои отчёты»)
TECH_ADMIN / FIN_ADMIN / FULL_ADMIN / CARD_ADMIN / READ_ADMINУнаследованные поля прав по ролям (int). В текущей версии доступом к разделам управляет RBAC (section_access, deny-by-default) — эти поля в гейтинге не участвуют

Связанные таблицы:

Параметры в SQL — синтаксис

Внутри SQL можно использовать спец-плейсхолдеры в формате :Имя|тип$ или :Имя|тип[аргументы]$. Когда оператор запускает отчёт — UI генерирует форму с этими параметрами, подставляет значения и выполняет SQL.

ТипПример SQLUI
dateWHERE op_date >= :Начало|date$Date-picker
sumWHERE op_summa > :Минимум|sum$Поле для рублей с конвертацией ×10^10
select[Model]WHERE abonent_id = :Клиент|select[Abonents]$Список с поиском по модели
choices[1^Янв|2^Фев|3^Мар]WHERE month = :Месяц|choices[1^Январь|2^Февраль]$Dropdown с фиксированными значениями

Парсинг — regex в AdminCustomReports._get_sql_fields(), подстановка в _execute_sql() с защитой от SQL-injection.

Типы отчётов

Справочник ADMIN_CUSTOM_REPORTS_TYPE — 7 категорий с цветными бейджами:

Один отчёт может быть без типа (NULL) или привязан к одной категории. На странице есть фильтр-вкладки по типам.

CodeMirror + AI Builder

CodeMirror 5.65.16 — встроенный SQL-редактор в модалке:

AI Builder: кнопка «✨ AI» в toolbar. Открывает чат с AI-ассистентом:

  1. Оператор описывает что нужно: «Топ-10 должников за месяц с балансом и телефоном»;
  2. Ассистент задаёт уточняющие вопросы (период, фильтры);
  3. Возвращает готовый SQL с правильными именами таблиц/полей и параметрами;
  4. Оператор проверяет, при необходимости правит, сохраняет.

Контекст БД для ассистента — schema из information_schema.columns для 15 ключевых таблиц + критические правила биллинга (DB_MONEY_KOEF, MPTT-фильтры, регистр имён).

Отчёты в ЛК клиента

Если у отчёта ALLOW_IN_CABINET=true — он показывается клиенту в ЛК (раздел «Мои отчёты»). При запуске:

Защита удаления отчёта: report_executions ссылаются на отчёт с FK NO ACTION. Если есть история запусков — удаление падает с ошибкой. Сначала очистите историю запусков. Отдельного «архивирования» отчётов нет — только удаление (hard-delete).

Библиотека отчётов

URL: /admin/reports/AdminCustomReports/

Каталог пользовательских SQL-отчётов. Отчёт — это сохранённый SQL-запрос с настраиваемыми параметрами, сгруппированный по типам (Техсервис, Бухгалтерия, Руководство, Поддержка и т.д.), который оператор запускает кликом и получает таблицу с возможностью экспорта в Excel, CSV или DBF.

Обучающее видео 2:33

Как найти готовый отчёт, запустить его с параметрами, выгрузить результат и завести свой — включая AI-помощника по SQL.

1920×1080 с озвучкой Скачать
Библиотека отчётов: вкладки по типам, показатели, быстрые фильтры, поиск и колонка «Орг.»
Библиотека отчётов: вкладки по типам, показатели, быстрые фильтры, поиск и колонка «Орг.»

Список отчётов

Запуск отчёта

URL: /admin/reports/AdminCustomReports/<id>/executesql/

Кнопка ▶ Запустить в строке списка ведёт на форму с параметрами отчёта. Параметры извлекаются из SQL-кода по синтаксису :Имя|тип$ и рендерятся в форму автоматически.

Форма запуска отчёта «Новые подключения за период»
Форма запуска отчёта «Новые подключения за период»

На снимке — форма отчёта «Новые подключения за период». Два параметра-даты (:Начало|date$ и :Конец|date$) форма объединяет в одно поле периода; по умолчанию — последний месяц. Справа — история выполнения этого отчёта.

Под формой — кнопки:

Пример: выбор периода и списка

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

Выбор периода: готовые периоды слева, календарь справа
Выбор периода: готовые периоды слева, календарь справа

Параметр-список (например, :Сотрудник|choices в отчёте «Действия сотрудника») показывается выпадающим списком. Его значения формируются на лету: SQL-генератор выбирает уникальных owner из AuditOperations и подставляет их в опции.

Пример: результат выполнения

После клика «Выполнить» срабатывает редирект на /admin/reports/AdminCustomReports/<id>/history/<run_id>/ — каждое выполнение получает свой run_id (хранится 30 дней для повторного открытия результата без перезапуска SQL):

Сохранённый результат: таблица, экспорт, печать и кнопка «Изменить и выполнить»
Сохранённый результат: таблица, экспорт, печать и кнопка «Изменить и выполнить»

На снимке — результат отчёта «Новые подключения за период»: 75 строк, колонки ID, Договор, Абонент, Тариф, Создан, Активирован, Улица, Дом, Телефон, Статус. Сверху — плашка «Сохранённый результат» с автором и периодом и кнопка «Изменить и выполнить»; под ней — экспорт, печать и «Поделиться».

Возможности страницы результата:

Модалка редактирования отчёта

Открывается кликом по имени отчёта или по карандашу. Делится на две колонки:

Live-counter под редактором обновляется на каждом change-event: «N строк · M парам.», справа от него — список найденных параметров с типами.

Синтаксис параметров

Параметры записываются в SQL как :Имя|тип$ и автоматически становятся полями формы запуска:

ТипСинтаксисUI-элементПередаётся в SQL как
date :Дата с|date$ Календарь String '2026-05-07' (ISO)
sum :Сумма|sum$ Числовое поле (₽) Float (умножается на 10^10 при необходимости)
select[Model] :Клиент|select[Abonents]$ Список с поиском по мере ввода Integer (pk выбранной записи)
choices[v^L|v^L] :Месяц|choices[1^Янв|2^Фев]$ Выпадающий список фикс. значений String (значение выбранной опции)
choices[[code^]Label] :Sotrudnik|choices[[uspeshnyy^]Aleksandr] Расширенный выпадающий с экранированными значениями String (code)
org :Организация|org$ Выбор организации (бейджи): «Все доступные» и каждая доступная сотруднику; по умолчанию — из навбара String с id через запятую: '1,3'

Параметр «Организация» (build 3085)

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

WHERE COALESCE(p."ORGANIZATION_ID", 1) = ANY(string_to_array(:Организация|org$, ',')::int[])
Запуск отчёта: выбор организации из доступных сотруднику
Запуск отчёта: выбор организации из доступных сотруднику

Если первая колонка результата называется «Организация», рассылка в чат делит сообщение на блоки по организациям (до N строк в каждом) и показывает четыре следующие колонки. Пример — отчёт «Где заявкам не хватает сети (техвозможность)».

Параметр ищется по шаблону :Имя|тип$. Незахватывающая группа регулярного выражения вида (?:ул|пер) в том же запросе похожа на начало параметра, если дальше в тексте есть $. Используйте обычную группу (ул|пер).

Пример SQL с параметрами:

SELECT a.id, a.name, a.contract_number,
       aa.ostatok / 10000000000.0 AS balance_rub
FROM abonents a
LEFT JOIN admin_accounts aa ON aa.id = a.account_id
WHERE a.is_folder = false
  AND a.deleted = false
  AND aa.ostatok < -:Долг|sum$ * 10000000000
  AND a.create_date BETWEEN :Дата с|date$ AND :Дата по|date$
ORDER BY aa.ostatok ASC
LIMIT :Лимит|sum$;

AI-помощник написания SQL

Кнопка «✨ AI» в шапке открывает чат с ИИ-ассистентом. Ассистент знает структуру 15 ключевых таблиц биллинга (abonents, admin_accounts, tarif, finance_operations, users_usluga, pay_log, users, homes, nas, connection_points и др.) и формат параметров, умеет писать SQL по словесному описанию задачи.

Типичный сценарий:

  1. Оператор пишет: «топ-10 должников за месяц с балансом и телефоном»
  2. AI задаёт уточняющие вопросы: какой период (последний месяц / произвольный), какой минимальный долг, нужен ли фильтр по тарифу
  3. Оператор отвечает свободным текстом
  4. AI возвращает готовый SQL с блоком JSON {"name": "...", "description": "...", "sql": "..."}
  5. Зелёный draft-banner с кнопкой «➡ Создать отчёт» передаёт черновик в основную модалку с предзаполненными name/description/sql
  6. Оператор проверяет SQL в CodeMirror, при необходимости правит, нажимает «Сохранить»

Каждый AI-запрос пишется в AuditOperations (table_name='ADMIN_CUSTOM_REPORTS', descr='AI-консультация: …'). Запросы идут через прокси (внешний API провайдера недоступен для RU).

Права и audit

Переработка раздела

Раздел переработан: нерабочие отчёты вычищены, редактор запросов приведён к тому же виду, что в СОРМ, у отчётов появились обложки и разделение по организациям.

- Библиотека отчётов
  - Список
    - Вкладки по отделам
    - Колонка Орг при мульти-орг
    - Обложки-миниатюры
    - Чипы и поиск Ctrl+K
  - Модалка отчёта
    - Редактор на всю высоту
    - Кнопки AI и Формат
    - Справка в popover
    - Квадратная обложка
    - Чекбоксы организаций
  - Запуск
    - Единый выбор периода
    - Выбор сотрудника с аватаром
    - История выполнения
  - Безопасность
    - Параметры связанные
    - Нормализация дат
    - Привязка к организации
Три критические находки
БылоСтало
Редактор открывался пустым (чёрный прямоугольник)Пересчёт размеров после показа окна — SQL виден сразу
Значение параметра вставлялось в запрос текстом (риск подмены, апостроф ломал фильтр молча)Значения передаются связанными параметрами; даты нормализуются — подмена невозможна
Поля периода шли «Дата конца → Дата начала» (по алфавиту)Порядок по появлению в запросе — начало перед концом
Как выполняется отчёт с параметрами
flowchart LR
    FORM["Форма запуска"] --> P["Параметры формы"]
    P --> SUB["Подстановка плейсхолдеров %s"]
    SUB --> NORM["Нормализация дат
дд.мм.гггг в дату"] NORM --> EXEC["Выполнение со связанными
значениями"] EXEC --> HIST["Запись в историю"] EXEC --> RES["Результат или ошибка"]

Значение больше не встраивается в текст запроса, поэтому апостроф или «;» внутри него не могут изменить смысл SQL. База работает в режиме, где строку «23.06.2026» она читала как «месяц 23» и падала — теперь дата передаётся отдельным типом и понимается однозначно.

Чистка: 75 → 62 отчёта
ДействиеОтчётовПричина
Удалено18Отчёты на пустых устаревших таблицах (старая телефония, старый лог RADIUS) и дубли
Починено3Выручка по организациям (был пустой запрос), расходы за период
Добавлено5Сводка по организациям, выручка по дням и по месяцам, обещанные платежи, отток
Редактор как в СОРМ + обложка
Окно отчёта: организации, название, тип, обложка, SQL-редактор с кнопками AI и «Формат»; найденные параметры — под редактором
Окно отчёта: организации, название, тип, обложка, SQL-редактор с кнопками AI и «Формат»; найденные параметры — под редактором
Разделение по организациям
flowchart TB
    R["Отчёт"] --> Q{"Привязан к организациям?"}
    Q -- "Нет" --> ALL["Общий — виден всем"]
    Q -- "Да" --> ORG["Виден отмеченным организациям"]
    ORG --> COL["Колонка «Орг.» в списке
в режиме «Все организации»"] ORG --> CHK["Чекбоксы в шапке модалки"]

Организации отмечаются чекбоксами по центру шапки модалки; пустой список означает «общий отчёт». В режиме «Все организации» в списке между «№» и названием появляется колонка «Орг.» с бейджами — как в тарифах.

Единые компоненты
ГдеЧто былоСтало
Форма запуска — датыДва отдельных поля с календарёмЕдиный выбор периода с пресетами (работает в любом отчёте с парой дат)
Форма запуска — сотрудникОбычный выпадающий списокСелектор сотрудника с аватаром
Редактор кодаСвой код в каждом разделеЕдиный компонент (каталог компонентов интерфейса)
Тёмная тема и телефон
Библиотека на телефоне
Библиотека на телефоне

Тёмная тема выдержана целиком; на телефоне список сжимается до имени и кнопки запуска, а модалки раскрываются на весь экран выдвижной панелью.

Аудит

Журнал всех значимых действий в биллинге: создание, изменение, удаление клиентов, подключение услуг, платежи, блокировки, изменения настроек, действия СОРМ.

Аудит
Аудит

Каждая запись содержит дату/время, оператора, тип события, клиента и описание. Для большинства событий есть drill-down: клик по записи открывает изменённый объект в нужной вкладке.

Возможности списка:

Журнал платежей

Сводный журнал финансовых операций по всем клиентам — приходы, списания, сторно, обещанные платежи. Это представление таблицы FinanceOperations с серверной пагинацией (поддерживает сотни тысяч записей).

Журнал платежей: период, итоги, вкладки по типам операций и поиск
Журнал платежей: период, итоги, вкладки по типам операций и поиск

Возможности:

Переработка журналов

У обоих журналов общий набор инструментов: выбор периода, показатели, цветные категории, поиск и экспорт. К ним добавлены разделение по организациям, работа с телефона и единый визуальный язык.

- Журналы: Аудит и Платежи
  - Единый вид SmitUI
    - Чистая таблица без серой шапки
    - Бейджи-таблетки с точкой
    - Тёмная тема из общего источника
    - Токены отступов и границ
  - Разделение по организациям
    - Колонка Орг в режиме Все
    - Фильтр по доступным компаниям
    - Записи без организации видны всем
  - Работа с клиентом
    - Клик открывает боковую панель
    - Панель всегда поверх меню
  - Телефон
    - Строки становятся карточками
    - Подписи полей у значений
    - Полоса прихода или расхода слева
Разделение по организациям

Теперь данные разделены. У платежа организация берётся из самой операции; у аудит-записи — из связанного объекта.

flowchart TB
    A["Аудит-запись"] --> Q{"Есть клиент?"}
    Q -- "Да" --> AB["Организация клиента"]
    Q -- "Нет" --> OBJ{"Известен объект?"}
    OBJ -- "Платёж / видеопроект /
тикет / NAS" --> OO["Организация объекта"] OBJ -- "Нет" --> ALL["Без организации —
общесистемное, видно всем"] AB --> COL["Колонка «Орг.» + фильтр
по доступным компаниям"] OO --> COL
РазделКак определяется организацияПокрытие
Журнал платежейПоле организации у самой финоперацииПрактически все записи
АудитОрганизация клиента; для системных — по объекту (платёж, видеопроект, тикет, NAS)≈ 74% записей; остальное — общесистемные события «—», видны всем
Единый вид SmitUI и работа с клиентом
Аудит в едином виде SmitUI
Аудит в едином виде SmitUI
Боковая панель клиента поверх журнала
Боковая панель клиента поверх журнала
Телефон

На телефоне строки обоих журналов становятся карточками: у каждого значения — подпись поля, ничего не обрезается. В Журнале платежей слева остаётся цветная полоса прихода/расхода.

Журнал платежей на телефоне — карточки
Журнал платежей на телефоне — карточки
Аудит на телефоне — карточки
Аудит на телефоне — карточки

Очередь чеков (54-ФЗ)

Раздел Отчёты → Очередь чеков (/admin/reports/fiscal_queue/) показывает, какие операции ждут кассового чека, по каким чек уже пробит и где ОФД вернул ошибку. Отсюда же чек отправляется вручную — по одной операции или пачкой.

Модуль фискализации, настройка «какие платежи фискализируем» и чек-лист готовности описаны в разделе Модуль фискализации 54-ФЗ; сама очередь — там же.

Журнал сообщений

Все сообщения клиентам в одном списке — SMS, почта, Telegram, push, VK и уведомления в личном кабинете: и отправленные из карточки клиента, и массовые рассылки, и служебные уведомления биллинга. Раздел: Отчёты → Журнал сообщений (/admin/reports/messages/). Отсюда же отправляют и планируют рассылки.

Журнал сообщений: сводка, каналы значками
Шапка с кнопкой «Рассылка», сводка с разбивкой по каналам, запланированные рассылки и фильтр каналов цветными значками
Обучающее видео 2:53

Кому отправить, как составить текст и посчитать SMS, запланировать отправку, согласовать и изменить рассылку, черновик от AI-помощника.

1920×1080 с озвучкой Скачать

Карта раздела

- Журнал сообщений
  - Сводка за период
    - Сообщений
    - SMS доставлено
    - SMS ждут отчёта шлюза
    - SMS с ошибкой
  - Запланированные рассылки
    - Карточка рассылки
    - Изменить
    - Согласовать
    - Получатели сейчас
    - Отменить
  - Фильтры
    - Период
    - Каналы
    - Поиск
    - SMS-статус
    - Отправитель
    - Колонки и CSV
  - Рассылка
    - Категории
    - Тарифы по линейкам
    - Папки
    - Услуги по типам
    - NAS
    - Клиенты
    - Сейчас или по расписанию
  - AI-помощник
    - Создать рассылку
    - Доставка SMS
  - Права
    - Создают четыре роли
    - Отправляют маркетолог и директор

Что на странице

Журнал сообщений на телефоне
На телефоне: кнопка «Рассылка» во всю ширину, карточка рассылки, кнопки в столбик

Рассылка: кому отправить

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

ВкладкаКому уйдёт
КатегорииГотовые группы: должники, в минусе после изменения цены, сейчас онлайн, заблокированные, с обещанным платежом, с активным IPTV, юрлица, без почты, без телефона, без платежей 30 дней.
ТарифыСначала линейка (показаны только линейки, на тарифах которых есть клиенты, и отдельно «Без линейки»), потом тарифы этой линейки с числом клиентов. Без отметок уйдёт всем клиентам выбранных линеек, с отметками — только клиентам отмеченных тарифов.
ПапкиДерево папок клиентов открывается свёрнутым; папка выбирается вместе с вложенными. Поиск по имени раскрывает ветки до найденной папки.
УслугиСначала тип услуги (Трафик, IPTV, ЧОП, Видео…) с числом клиентов, потом услуги этого типа. Считаются только действующие услуги: включены, не удалены, срок начался и не закончился.
NASКлиенты с учётками на выбранных NAS — с адресом NAS и числом клиентов.
ПоискКонкретные клиенты: поле ищет по имени, договору, телефону и адресу, выбранные показываются плашками.
Окно «Новая рассылка»: категория «С активным IPTV», число получателей и первые из них
Окно «Новая рассылка»: категория «С активным IPTV», число получателей и первые из них
Вкладка «Тарифы»: линейки и тарифы
Тарифы: сначала линейка, потом её тарифы с числом клиентов
Вкладка «Услуги»: типы услуг и услуги
Услуги: сначала тип, потом услуги этого типа; пометка IPTV — у услуг, связанных с ТВ-пакетом
Вкладка NAS
NAS: адрес узла и число клиентов на нём
Вкладка «Папки»
Папки: дерево открывается свёрнутым

Сводка «по каналам» — сколько сообщений за неделю ушло каждым каналом: SMS, почта, Telegram-бот, ВКонтакте, аккаунты агента (Telegram, ВКонтакте, MAX — значок с человечком) и только в личный кабинет. Клик по значку ставит этот канал фильтром. Фильтр каналов над таблицей — цветные значки (подпись в подсказке), отдельно — «Агент»: все сообщения аккаунтов, которые пишут первыми. В колонке «Каналы» у сообщения агента тоже значок с человечком.

Текст, каналы и время

Текст рассылки со счётчиком SMS и блок «Когда отправить»
Редактор текста со счётчиком SMS и блок «Когда отправить» в режиме «Запланировать»
Окно «Новая рассылка»: каналы переключателями
Каналы рассылки: отмечены SMS и Telegram — аккаунт
flowchart TD
    R["Рассылка: получатели + текст"] --> L["Личный кабинет — всегда"]
    R --> CH{"Отмеченные каналы"}
    CH --> SMS["SMS"] & EM["Почта"] & PU["Push"] & TB["Telegram-бот
(если привязан)"] & VC["VK-сообщество
(если привязан VK)"] CH --> AG{"Аккаунты агента"} AG --> LAST["Мессенджер, где клиент
писал последним"] LAST -- "нет такого" --> FIRST["Первый отмеченный,
где найден номер"] AG -. "паузы, лимиты, тихие часы,
согласие клиента" .-> LAST

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

Подтверждение перед планированием рассылки
Подтверждение «Запланировать рассылку?»

Запланированные рассылки

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

Карточка запланированной рассылки
Карточка: время и организация, кому, каналы, темп, предупреждение, обращение, автор и кто согласовал, текст и кнопки
stateDiagram-v2
    [*] --> Ждёт_согласования: создал сотрудник
без права отправки [*] --> Запланирована: создал маркетолог
или директор Ждёт_согласования --> Запланирована: «Согласовать» Запланирована --> Ждёт_согласования: изменил сотрудник
без права отправки Запланирована --> Отправляется: наступило время Отправляется --> Завершается: все поставлены в очередь Завершается --> Отправлена: очередь отправила Ждёт_согласования --> Не_состоялась: не согласована
за 2 часа после старта Запланирована --> Не_состоялась: не началась за 2 часа Ждёт_согласования --> Отменена Запланирована --> Отменена Отправляется --> Отменена: «Отменить» Отправлена --> [*] Отменена --> [*] Не_состоялась --> [*]

Права и согласование

РольСоздать и изменитьОтправить сразуСогласовать
Старший сэйлс, старший менеджерданетнет
Маркетолог (группа «Маркетинг»), Директордадада
Суперпользовательдадада
Остальныенет — журнал только для просмотранетнет

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

Карточка рассылки, которая ждёт согласования
Рассылка ждёт согласования — так её видит маркетолог или директор
Подтверждение согласования
Подтверждение «Согласовать рассылку?»
flowchart TD
    NEW["Рассылка → Запланировать"] --> RIGHT{"Может отправлять?
маркетолог, директор"} RIGHT -->|"да"| SCH["Запланирована"] RIGHT -->|"нет"| PEND["Ждёт согласования
сообщение в рабочий чат"] PEND --> REM["В момент предупреждения —
напоминание в чат"] PEND --> APR{"«Согласовать»
та же версия?"} APR -->|"да"| SCH APR -->|"изменили"| RELOAD["Обновить список
и проверить заново"] PEND --> LATE["Не согласована за 2 часа
после старта → не состоялась"] SCH --> WARN["Предупреждение в чат"] --> RUN["Старт: получатели
считаются заново"]

Изменить запланированную рассылку

Кнопка «Изменить» есть у рассылки, которая ещё не началась и до старта которой больше двух минут. Открывается то же окно с заполненными получателями, текстом, каналами, временем, темпом, чатом и обращением; «Сейчас» недоступно. По «Сохранить» окно показывает, что изменится — «было → стало», — и только после подтверждения записывает правку.

Изменение: поля заполнены, «Сейчас» недоступно, кнопка «Сохранить»
Изменение: поля заполнены, «Сейчас» недоступно, кнопка «Сохранить»
Подтверждение изменений рассылки
Подтверждение «Сохранить изменения?» со списком изменений
sequenceDiagram
    actor S as Сотрудник
    participant W as Окно «Рассылка»
    participant B as Биллинг
    participant C as Рабочий чат
    S->>W: Изменить
    W->>B: поля рассылки
    B-->>W: получатели, текст, время, каналы
    S->>W: правит и нажимает «Сохранить»
    W->>B: пробное сохранение
    B-->>W: что изменится: было → стало
    S->>W: подтверждает
    W->>B: сохранить
    B->>B: проверка: не началась, никто не менял
    B->>B: аудит «изменена: …»
    B-->>C: «Рассылка изменена», если предупреждение уже было

AI-помощник

Кнопка помощника в углу страницы знает группы получателей с числом клиентов, запланированные рассылки, недавние тексты, правила SMS и тихого часа. Заготовки: «Создать рассылку», «Доставка SMS», «Запланированные».

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

AI-помощник журнала: заготовки
Заготовки помощника
AI-помощник: черновик рассылки
Черновик: кому, когда, сколько SMS и кнопка «Открыть в окне рассылки»
Окно рассылки, открытое из черновика помощника
Окно, открытое из черновика: выбрана группа «С активным IPTV»

Разделение по организациям

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

flowchart TD
    REQ["Журнал, выбор получателей
или рассылка"] --> MO{"Мульти-орг
включён?"} MO -->|"нет"| ALL["Без ограничений"] MO -->|"да"| CUR{"Выбрана организация
в шапке?"} CUR -->|"да"| ONE["Только клиенты
этой организации"] CUR -->|"нет"| LIM{"Сотрудник ограничен
компаниями?"} LIM -->|"нет"| ALLORG["Все организации
+ колонка «Орг.»"] LIM -->|"да"| PERM["Только доступные
организации"] PERM --> SH["Рассылки «по всем
организациям» не видны"] ALLORG --> SYS["Системные сообщения
без клиента видны всем"] ONE --> SYS PERM --> SYS

Аудит

Всё пишется в аудит:

Адреса

URLНазначение
GET /admin/reports/messages/Страница; ?mailing=N — выделить рассылку
GET /admin/reports/messages_json/Таблица: фильтры и страницы
GET /admin/reports/messages_kpi/Сводка
GET /admin/reports/messages/export/CSV текущей выборки
POST /admin/reports/messages/broadcast/Отправить сразу или запланировать (when=later)
GET /admin/reports/messages/recipients_preview/Сколько получателей и кто
GET /admin/reports/messages/tariffs_list/Тарифы с числом клиентов и линейки
GET /admin/reports/messages/services_list/Действующие услуги с числом клиентов и типы услуг
GET /admin/reports/messages/folders_list/Дерево папок
GET /admin/reports/messages/nas_list/NAS
GET /admin/reports/messages/senders_list/Отправители для фильтра
GET /admin/reports/messages/scheduled/Запланированные и недавние рассылки, права сотрудника
POST /admin/reports/messages/scheduled/<id>/action= get · update (dry=1 — только сравнить) · approve · preview · cancel

Разработка и логи

Раздел для администратора-разработчика. Доступен только пользователям с правами root. Делится на две вкладки.

Отчёты — встроенный markdown-просмотрщик внутренних документов проекта (отчёты по разработке, планы, документация).

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

Поддерживается сортировка по дате/имени или ручной drag-and-drop, inline-переименование, создание папок, загрузка новых .md-файлов через интерфейс.

Возможности просмотрщика .md

Markdown-просмотрщик поддерживает удобную навигацию и работу с документами:

Логи — просмотр серверных логов прямо из админки.

Серверные логи: лог-файлы с размерами
Серверные логи: лог-файлы с размерами

Доступны каналы:

Всего 13 каналов (список — billing/views/dev_reports.py::LOG_FILES).

Показываются последние 500 строк, есть кнопка обновления. Файлы автоматически ротируются (10 МБ × 5 копий).

Просмотр логов с подсветкой

Страница /admin/reports/dev/logs/ (раздел «Отчёты → Разработка и логи», только root-доступ) показывает 12 каналов журналов слева с текущим размером, справа — содержимое выбранного файла.

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

Ротация логов на сервере

Часть логов пишет Django через RotatingFileHandler (error.log, radius.log, payment.log, sorm.log, staff.log — maxBytes 10 МБ, backupCount 5, в просмотрщике видны как radius.log.1….5). Но нативный freeradius.log пишет сам FreeRADIUS (C-side), и Django его не ротирует. Если FreeRADIUS запущен в trace-режиме (-xx), этот файл растёт на ~5 ГБ/сутки — он однажды вырос до 43 ГБ.

Лечение:

Уровень логирования и текущий размер каждого файла задаются и видны на вкладке «Настройки системы → Логи»; после фикса freeradius.log держится в районе десятков мегабайт.

Должники

Содержание раздела

Отдельная страница /admin/debtors/ — список клиентов с отрицательным балансом или активной блокировкой b_negbal. Раздел рассчитан на ежедневную работу бухгалтерии и операторов поддержки: KPI-блок сверху помогает быстро оценить ситуацию по компании, а drawer-панель — разобраться с конкретным клиентом без ухода на полную карточку.

KPI и статистика по периодам

Над таблицей — четыре карточки-показателя: общее количество должников, суммарный долг (в рублях), средний долг и доля должников с активным обещанным платежом. Карточки реагируют на выбранный период: переключатель chips сверху позволяет видеть динамику за сегодня / неделю / месяц / квартал / год. Цифры пересчитываются прямо в браузере без перезагрузки — у каждой карточки есть мини-индикатор изменения относительно предыдущего периода.

Фильтры и чипы
Таблица и сортировка

Колонки: ФИО, договор, тариф, точка подключения, баланс, дней без оплаты, телефон, email, статус. По умолчанию сортировка — по убыванию суммы долга. Клик на заголовок любой колонки переключает порядок (▲▼). Цветовое кодирование: красные строки — заблокированные за неуплату, жёлтые — на грани блокировки, серые — с активным обещанным платежом. В каждой строке справа — кнопка ℹ Подробнее, которая открывает drawer.

Drawer-панель клиента

Клик на ℹ открывает боковую панель справа (overlay поверх таблицы) с краткой сводкой по клиенту — без перехода на полную карточку и потери контекста списка. Внутри панели:

Массовые действия и экспорт

Миграция с других биллингов

Раздел /admin/settings/migration/ — мастер импорта данных клиентов из других биллинговых систем. Пошаговый wizard с предпросмотром и dry-run.

Импорт из биллинга на Firebird

/admin/settings/migration/cb4/ — специализированный импорт данных из биллинга на базе Firebird. Учитывает специфику:

Загрузка из CSV

/admin/settings/migration/csv_loading/ — общий импорт клиентов/услуг/платежей через CSV файлы. Поддерживается:

Авто-импорт CSV (схемы)

/admin/settings/autocsv_upload_config/ — настройка повторяющихся импортов: оператор сохраняет «схему» (маппинг колонок + способ обработки дубликатов), и потом загрузка одной кнопкой берёт CSV и применяет схему без повторной настройки. Полезно для ежемесячных выгрузок из бухгалтерии или экспорта из биллинга мобильного оператора (массовое зачисление платежей).

FrameworkFormGroupFields — назначение и роль

Содержание раздела

FrameworkFormGroupFields (FFG) — таблица настроек UI для всех админских форм биллинга. Управляет тем, какие поля видны на форме редактирования, как они сгруппированы в вкладки и в каком порядке. По сути это «генеральный настройщик» админки без правки кода.

Что это и зачем

Биллинг — это унаследованный движок с десятками моделей, у каждой по 30-100 полей. Большая часть из них — технический шум для оператора. Решения:

Это безопасный способ упростить UI без боязни сломать логику.

Ключевые поля
ПолеНазначение
TABLE_NAMEИмя модели (USERS, ABONENTS, USLUGA — UPPERCASE)
FIELD_NAMEИмя поля Django-модели (то же что в Model._meta.fields)
INTERFACE_IDFK на интерфейс (NULL = дефолт для всех ролей)
GROUP_IDНомер вкладки/группы в форме (1 = основные, 2 = доп., и т.д.)
SHOW_ON_FORM0 = скрыто, 1 = видно (главное поле управления)
VERBOSE_NAMEРусское имя поля для UI (заменяет автоматическое из модели)
ORDERПорядок в группе (для drag-and-drop)
Как работает
  1. При открытии формы редактирования модели (например /admin/Abonents/<id>/) view вызывает safe_globals.get_groups_from_model('ABONENTS');
  2. Функция читает все записи FFG где TABLE_NAME='ABONENTS' и INTERFACE_ID IS NULL;
  3. Записи группируются по GROUP_ID → каждая группа = одна вкладка формы;
  4. Внутри группы поля сортируются по ORDER, скрытые (SHOW_ON_FORM=0) исключаются;
  5. Применяются VERBOSE_NAME для русификации лейблов;
  6. Кеш Django сохраняет результат — после изменения FFG нужен cache.clear().
Опасные моменты
  1. INTERFACE_ID=NULL — это дефолт, не «отсутствие настройки». Если поле SHOW_ON_FORM=0 для INTERFACE_ID=NULL, оно скрыто во всех интерфейсах. Чтобы показать только в одном — нужны 2 записи: NULL с 0 и INTERFACE_ID=1 с 1;
  2. Дубликаты Python dict — баг был с 'Users' ключом, появлявшимся дважды в _EXCLUDE_FORMS. Второе значение тихо перезаписывало первое. Перед добавлением нового ключа всегда grep;
  3. UPPERCASE имя таблицы — критично для PostgreSQL. 'abonents' != 'ABONENTS'. Используйте Model._meta.db_table.upper() чтобы не ошибиться;
  4. FIELD_NAME — Django-имя, не SQL-имя. Поле create_date в FFG, не "CREATE_DATE".
Реальные примеры скрытия полей
BuildМодельСкрыто
Users (учётные записи)17 полей: IPV6, MASK, PHONE, EXT_ID, NAS_IP_LOCK, OPT82, IS_TEMPLATE, SNAT_PULL, SNATIP, SERVER, ALWAYS_LOGGED, HOST_IP, HOST_PULL, CREATE_DATE, OPT82_PARAM, IS_ALLOW_SEARCH, GPON_MODEM_PORT, HW_SERIAL, EQUIPMENT, SERVICE_TYPE
UslugaSERVICE_TYPE (87% услуг имели его NULL)
Users группа 325 «дополнительных»: DHCP_MASK, DHCP_ROUTE_IP, ASK_PASSWORD_LK, DEACTIVATE_STRING, ACTIVATE_STRING
Где править: UI /admin/settings/interface_settings/ (FrameworkFormGroupFieldsForm в billing/forms/framework_forms.py). После сохранения обязательно очистите кеш — иначе изменения не подхватятся: docker exec app-web-1 python manage.py shell -c "from django.core.cache import cache; cache.clear()"

Настройки интерфейса (формы)

/admin/settings/interface_settings/ — конфигурация полей форм для каждой модели. Через FrameworkFormGroupFields можно:

Пример использования: на форме Users скрыты 17 технических полей (IPV6, MASK, EXT_ID, IS_TEMPLATE, и т.д.) — оставлены только реально используемые. Изменения применяются для всех операторов одновременно после cache.clear().

Игры (Маркетинг)

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

Список игр: Pacman, Tetris, Snake, Minesweeper, 2048, Breakout, Flappy Bird, Helicopter. Доступны в админке, мобильном приложении и ЛК.

Архитектура модуля

Единый источник настроек (GAMES_* в SystemSettings) питает три точки потребления: профиль-меню админки, карточку клиента, мобильное приложение. Данные результатов хранятся в GameScore, история победителей — в GameMonthWinner.

Архитектура модуля Маркетинг → Игры
Архитектура модуля Маркетинг → Игры
КомпонентНазначение
billing/services/games_registry.pyЕдиный реестр 8 игр (admin + mobile)
billing/models/game_score.pyGameScore (результаты) + GameMonthWinner (победители)
billing/services/game_rewards.pyОпределение лидера + безопасное начисление бонуса
billing/tasks/game_rewards.pyCelery-подведение итогов 1-го числа
settings/_marketing_tab.htmlUI настроек (вкладка «Маркетинг»)
abonents_form/marketing_games.htmlВкладка результатов в карточке клиента

Настройки модуля «Маркетинг»

Настройки находятся в /admin/settings/system/ → вкладка «Маркетинг» (рядом с Брендинг / Безопасность / … / Профиль). Сейчас Маркетинг = Игры; в будущем туда добавятся другие маркетинговые механики (акции, реферальные программы, бонусы за активность).

Вкладка Маркетинг — полная страница настроек
Вкладка Маркетинг — полная страница настроек

Страница содержит 5 секций:

Вкладка Маркетинг: блоки «Общее» и «Мобильное приложение»
Вкладка Маркетинг: блоки «Общее» и «Мобильное приложение»
🌓 Тёмная тема и адаптивность. Все секции — карточки, тумблеры, таблица победителей — поддерживают тёмную тему. На мобильном вкладки раздела «Настройки системы» сворачиваются в компактный горизонтальный ряд с иконками (активная подсвечивается), а переключатели и поля увеличены под удобное касание.
Мобильный вид вкладки Маркетинг
Мобильный вид вкладки Маркетинг

«Игра месяца» — бесплатный интернет

Главная механика. Клиент с максимальным счётом за календарный месяц получает бесплатный месяц интернета — кредит-финоперацию на сумму месячной стоимости его тарифа.

Поток Игра месяца
Поток Игра месяца

Настройки розыгрыша:

Подведение итогов — Celery-задача game_of_month_finalize запускается 1-го числа в 02:00, определяет лидера прошлого месяца и (в авто-режиме) начисляет приз; в ручном — ставит «ожидает подтверждения» + Telegram-алерт оператору.

Ручное начисление. В блоке «Текущий лидер» кнопка «Начислить победителю вручную» открывает окно подтверждения с данными победителя — игра, ФИО, договор, набранные очки и сумма приза. Если для турнира заданы условия участия (см. §5.4), оператор отмечает их выполнение прямо в окне; кнопка «Начислить» становится доступной только после подтверждения всех условий.

🔒 Безопасное начисление: бонус начисляется только через FinanceOperations (как онлайн-платёж), не правит баланс напрямую — EBS-синхронизация его не затирает. Сотрудники в розыгрыше не участвуют. Заблокированный/удалённый победитель пропускается + алерт оператору. При равном максимуме побеждает достигший раньше (tie-break).

Условия участия в турнире

Для участия в турнире можно требовать действия, повышающие рейтинг компании:

УсловиеНастройка
⭐ Оценка приложения (Google Play / App Store)GAMES_OF_MONTH_REQUIRE_APP_RATING
🗺 Оценка на Яндекс КартахGAMES_OF_MONTH_REQUIRE_YANDEX_MAPS
📍 Оценка на 2ГИСGAMES_OF_MONTH_REQUIRE_2GIS
Игра месяца + условия участия
Игра месяца + условия участия

Включённые условия показываются клиенту в мобильном приложении как требования перед участием в розыгрыше. По умолчанию все выключены.

Под переключателями условий задаются ссылки, по которым клиент оставляет оценку. Источники ссылок разделены:

Источники ссылок условий участия
Источники ссылок условий участия
Проверка оценки. Мобильное приложение получает ссылки через /mobile-api/v1/game/config и показывает их клиенту. Факт того, что клиент действительно оставил оценку, подтверждает оператор вручную в окне начисления приза — автоматической проверки отзыва на стороне магазинов и карт нет.

Вкладка «Маркетинг» в карточке клиента

В карточке клиента появляется вкладка «Маркетинг» — только если модуль игр включён и у клиента есть лицевой счёт.

Вкладка Маркетинг в карточке клиента
Вкладка Маркетинг в карточке клиента

Содержимое вкладки:

Оператор видит игровую активность клиента прямо в его профиле, не переходя в раздел игр.

Профиль-меню и мобильное приложение

Профиль-меню (справа у аватара) — пункт «Игры» появляется, когда включены GAMES_ENABLED + GAMES_ADMIN_ENABLED. Управляется через context-processor — без жёсткой проверки прав, видимость определяется единым тогглом.

Пункт «Игры» в меню профиля
Пункт «Игры» в меню профиля

Мобильное приложение (/mobile-api/v1/game/config) отдаёт список доступных игр (из GAMES_MOBILE_ALLOWED) и данные текущего розыгрыша (мой счёт, счёт лидера, дни приза). Фильтрация submit_score / leaderboard по GAMES_MOBILE_ENABLED.

Ключи настроек (SystemSettings, категория games)

GAMES_ENABLED / GAMES_ADMIN_ENABLED / GAMES_MOBILE_ENABLED / GAMES_MOBILE_ALLOWED
GAMES_OF_MONTH_ENABLED / GAMES_OF_MONTH_KEY / GAMES_OF_MONTH_REWARD_DAYS
GAMES_OF_MONTH_MIN_SCORE / GAMES_OF_MONTH_AUTO_AWARD / GAMES_OF_MONTH_EXCLUDE_STAFF
GAMES_OF_MONTH_NOTIFY / GAMES_OF_MONTH_OPTYPE
GAMES_OF_MONTH_REQUIRE_APP_RATING / _YANDEX_MAPS / _2GIS
GAMES_OF_MONTH_YANDEX_URL / GAMES_OF_MONTH_2GIS_URL

Ссылка на приложение для условий участия берётся из MOBILE_FORCE_UPDATE_URL_ANDROID / _IOS (раздел ЛК → Мобильное).