Розробка звітів по продажах 1С-Бітрікс
Штатна аналітика модуля sale у 1С-Бітриксі видає плоску таблицю замовлень з мінімальною групуванням. Для управління продажами цього мало: потрібна сегментація по менеджерам з урахуванням повернень, розбивка по категоріях товарів, динаміка середнього чеку, аналіз повторних покупок. Готові звіти не вміють зв'язувати дані з різних таблиць — замовлення, корзину, оплати, властивості замовлень — у єдину аналітичну вибірку.
Кастомні звіти по продажах — це набір SQL/ORM-запитів, візуалізація в админці та експорт в Excel для передачі керівництву або фінвідділу.
Архітектура даних: звідки беремо цифри
Усі дані про продажі розподілені по кільком таблицям модуля sale:
| Таблиця / ORM-клас | Що зберігає | Ключові поля |
|---|---|---|
b_sale_order / OrderTable |
Замовлення | ID, DATE_INSERT, PRICE, CURRENCY, STATUS_ID, USER_ID, RESPONSIBLE_ID |
b_sale_basket / BasketTable |
Позиції корзини | ORDER_ID, PRODUCT_ID, QUANTITY, PRICE, DISCOUNT_PRICE, NAME |
b_sale_payment / PaymentTable |
Оплати | ORDER_ID, PAY_SYSTEM_ID, SUM, PAID (Y/N), DATE_PAID |
b_sale_order_props_value / OrderPropsValueTable |
Властивості замовлення | ORDER_ID, ORDER_PROPS_ID, VALUE |
b_sale_shipment / ShipmentTable |
Відгрузки | ORDER_ID, DELIVERY_ID, STATUS_ID |
Зв'язок з каталогом. Поле PRODUCT_ID у корзині — це ID елемента інфоблоку (торгового пропозиції). Для групування по розділам каталогу потрібен JOIN з b_iblock_section_element та b_iblock_section. Якщо використовуються SKU — додатковий JOIN через PROPERTY_CML2_LINK для виходу на батьківський товар.
Deep-dive: звіт по виручці з аналітикою менеджерів
Найбільш затребуваний звіт — виручка по періодам з розбивкою по менеджерам. Задача: показати, скільки кожен менеджер приніс у касу, зі скількох замовлень, яків середній чек та відсоток відмін.
ORM-запит:
use Bitrix\Sale\Internals\OrderTable;
use Bitrix\Main\Entity\ExpressionField;
$result = OrderTable::getList([
'select' => [
'RESPONSIBLE_ID',
'MONTH' => new ExpressionField('MONTH', "DATE_TRUNC('month', %s)", ['DATE_INSERT']),
'REVENUE' => new ExpressionField('REVENUE', 'SUM(CASE WHEN %s NOT IN (\'F\', \'CA\') THEN %s ELSE 0 END)', ['STATUS_ID', 'PRICE']),
'CANCELLED' => new ExpressionField('CANCELLED', 'SUM(CASE WHEN %s IN (\'F\', \'CA\') THEN %s ELSE 0 END)', ['STATUS_ID', 'PRICE']),
'ORDER_COUNT' => new ExpressionField('ORDER_COUNT', 'COUNT(%s)', ['ID']),
'AVG_CHECK' => new ExpressionField('AVG_CHECK', 'AVG(CASE WHEN %s NOT IN (\'F\', \'CA\') THEN %s END)', ['STATUS_ID', 'PRICE']),
],
'filter' => [
'>=DATE_INSERT' => DateTime::createFromPhp(new \DateTime('2024-01-01')),
],
'group' => ['RESPONSIBLE_ID', 'MONTH'],
'order' => ['MONTH' => 'ASC', 'REVENUE' => 'DESC'],
]);
Цей запит видає дані для таблиці та графіку. Менеджер з RESPONSIBLE_ID зв'язується з b_user для виведення ФІО.
Метрики менеджера, які рахуємо:
- Виручка (без відмін та повернень)
- Сума відмін — показує якість роботи
- Середній чек — порівняння між менеджерами
- Кількість замовлень — навантаження
- Конверсія з «Новий» у «Виконаний» —
COUNT(status=F) / COUNT(*)по статусам - Середня швидкість обробки —
AVG(DATE_STATUS - DATE_INSERT)для переходу з початкового статусу
Звіт по товарам та категоріях
Другий по важливості звіт. Показує, які товари та категорії генерують виручку, які лежать мертвим грузом.
Структура: JOIN BasketTable з OrderTable (фільтр по оплачених замовленнях) та з інфоблоком каталогу. Групування по розділам з агрегацією: виручка, кількість проданих одиниць, середня ціна продажу, середня знижка.
ABC-аналіз вбудовується в цей звіт: товари сортуються по спаданню виручки, рахується нарощуючий підсумок, і кожному присвоюється категорія — A (80% виручки), B (15%), C (5%). Реалізується віконною функцією SUM() OVER (ORDER BY revenue DESC) або програмно після вибірки.
Візуалізація та дашборд
Звіти розміщуються на кастомній сторінці в /local/admin/. Стек візуалізації:
- Chart.js — лінійні графіки динаміки, bar chart для порівняння менеджерів
- HTML-таблиці з сортуванням — для детальних даних
- PhpSpreadsheet — експорт у xlsx з форматуванням, формулами ИТОГО, автоширина колонок
Дашборд будується як single-page з табами: «Загальна виручка», «По менеджерам», «По товарам», «ABC-аналіз». Дані підгружаються через AJAX-ендпоінт, параметри фільтра (період, менеджер, категорія) передаються у запиті.
Кешування та продуктивність
На магазині з 50 000+ замовленнями ORM-запити з групуванням виконуються 3-10 секунд. Рішення:
- Матеріалізовані представлення (PostgreSQL) або summary-таблиця, пересчитувана агентом раз на годину
-
Індекси — обов'язкові:
(DATE_INSERT, STATUS_ID)наb_sale_order,(ORDER_ID, PRODUCT_ID)наb_sale_basket -
Кеш звіту у
managed_cacheБітрікса з TTL 1 година та інвалідацією при зміні замовлення
Строки розробки
| Етап | Зміст | Строк |
|---|---|---|
| Аналітика | Визначення метрик, узгодження розрізів | 1-2 дні |
| Бекенд | ORM-запити, оптимізація, кешування | 3-5 днів |
| Фронтенд | Дашборд, графіки, фільтри | 2-3 дні |
| Експорт | Excel-шаблони, форматування | 1 день |
| Тестування | Перевірка на реальних даних, нагрузка | 1-2 дні |
Загальний строк — 1-2 тижні залежно від кількості звітів та складності метрик. Результат — дашборд в админці з експортом, що замінює ручну вивантаження та обробку в Excel.







