Настройка дашборда сравнения цен с конкурентами 1С-Битрикс
Категорийный менеджер не должен каждый раз открывать карточку товара, чтобы понять, где стоит ценовая проблема. Дашборд — это сводный экран, который за 30 секунд показывает: какие товары проигрывают по цене, насколько, сколько таких товаров, и позволяет принять решение прямо там. Цель дашборда — сократить время от обнаружения проблемы до действия.
Источники данных
Дашборд строится на трёх таблицах:
-
bl_competitor_prices— актуальные цены конкурентов -
bl_product_price_position— агрегаты (мин/макс/среднее конкурентов, наш ранг) -
b_catalog_price— наши текущие цены
Данные в агрегатную таблицу обновляются агентом после каждой синхронизации цен конкурентов.
Ключевые метрики дашборда
Ценовая позиция — распределение товаров по местам:
SELECT rank, COUNT(*) as product_count
FROM bl_product_price_position
WHERE updated_at > NOW() - INTERVAL '24 hours'
GROUP BY rank
ORDER BY rank;
Отображается как bar chart: «1 место — 34 товара, 2 место — 87, 3 место — 124...»
Товары, где мы дороже минимальной цены конкурента:
SELECT
ie.ID,
ie.NAME,
ppp.our_price,
ppp.min_comp as competitor_min,
ROUND((ppp.our_price - ppp.min_comp) / ppp.min_comp * 100, 1) as diff_pct,
ppp.rank
FROM bl_product_price_position ppp
JOIN b_iblock_element ie ON ie.ID = ppp.product_id
WHERE ppp.our_price > ppp.min_comp
AND ppp.min_comp > 0
ORDER BY diff_pct DESC
LIMIT 50;
Упущенная выручка (оценка):
SELECT
SUM(
(ppp.our_price - ppp.min_comp) / ppp.our_price * oe.order_count * ppp.our_price
) as estimated_lost_revenue
FROM bl_product_price_position ppp
JOIN (
SELECT product_id, COUNT(DISTINCT order_id) as order_count
FROM b_sale_basket
WHERE date_insert > NOW() - INTERVAL '30 days'
GROUP BY product_id
) oe ON oe.product_id = ppp.product_id
WHERE ppp.our_price > ppp.min_comp;
Структура страницы дашборда
Страница в /bitrix/admin/price_dashboard.php состоит из блоков:
Верхний блок — сводные KPI:
- Всего товаров под мониторингом: N
- Из них дороже конкурентов: N (XX%)
- Средняя ценовая позиция: X.X место
- Товаров на 1-м месте: N
Средний блок — тепловая карта по разделам каталога:
// Запрос агрегатов по разделам
$sectionStats = \Bitrix\Main\Application::getConnection()->query("
SELECT
s.NAME as section_name,
COUNT(*) as total_products,
COUNT(CASE WHEN ppp.rank = 1 THEN 1 END) as on_first_place,
ROUND(AVG(ppp.rank), 1) as avg_rank,
COUNT(CASE WHEN ppp.our_price > ppp.min_comp THEN 1 END) as losing_count
FROM bl_product_price_position ppp
JOIN b_iblock_element ie ON ie.ID = ppp.product_id
JOIN b_iblock_section s ON s.ID = ie.IBLOCK_SECTION_ID
GROUP BY s.ID, s.NAME
ORDER BY losing_count DESC
")->fetchAll();
Каждый раздел — строка с цветовой индикацией: зелёный (>70% товаров на 1 месте), жёлтый (50–70%), красный (<50%).
Нижний блок — таблица проблемных товаров с кнопками действий:
| Товар | Арт | Наша цена | Мин. конкурент | Разница | Rank | [Изменить цену] |
|---|
Кнопка «Изменить цену» — инлайн-редактирование с сохранением через AJAX в b_catalog_price. При сохранении — в лог bl_price_change_log записывается: кто, когда, с какой цены, на какую.
AJAX-обновление данных
Дашборд обновляется без перезагрузки страницы — кнопка «Обновить данные» инициирует синхронизацию с источником цен:
document.getElementById('refresh-btn').addEventListener('click', function() {
this.disabled = true;
fetch('/bitrix/services/main/ajax.php?action=PriceDashboard:refresh', {
method: 'POST',
headers: {'X-Bitrix-Csrf-Token': BX.bitrix_sessid()}
})
.then(r => r.json())
.then(data => {
if (data.status === 'ok') location.reload();
});
});
Экспорт в Excel
Кнопка «Выгрузить в Excel» формирует отчёт через \PhpOffice\PhpSpreadsheet: все товары с ценами конкурентов по столбцам (каждый конкурент — отдельный столбец), нашей ценой, позицией, рекомендованной ценой (если настроен репрайсер).
Сроки
| Этап | Срок |
|---|---|
| Агрегатные запросы и оптимизация | 2 дня |
| Верхний блок KPI + chart.js | 1 день |
| Тепловая карта по разделам | 1 день |
| Таблица проблемных товаров + инлайн-редактирование | 2 дня |
| Экспорт Excel | 1 день |
| Тестирование | 1 день |
| Итого | 8–9 дней |







