Настройка отслеживания цен конкурентов для 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка отслеживания цен конкурентов для 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка отслеживания цен конкурентов для 1С-Битрикс

Отслеживание цен конкурентов строится одним из двух способов: через готовый сервис мониторинга (Competera, Metacommerce, Priceva) или через собственный парсер. Готовый сервис — проще, надёжнее, но дорого при большом каталоге. Собственный парсер — гибко, дёшево в эксплуатации, но требует регулярного обслуживания при изменениях на сайтах конкурентов. Задача настройки в обоих случаях одинакова: собрать данные, сохранить в Битрикс, показать менеджеру в удобном виде.

Архитектура хранения данных

Независимо от источника данных (сервис или парсер), структура хранения одинакова:

Конкуренты bl_price_competitors:

CREATE TABLE bl_price_competitors (
    id       SERIAL PRIMARY KEY,
    name     VARCHAR(255) NOT NULL,
    domain   VARCHAR(255) UNIQUE,
    active   BOOLEAN DEFAULT true,
    logo_url VARCHAR(512)
);

Цены конкурентов bl_competitor_prices:

CREATE TABLE bl_competitor_prices (
    id             SERIAL PRIMARY KEY,
    product_id     INT NOT NULL,               -- b_iblock_element.ID
    competitor_id  INT REFERENCES bl_price_competitors(id),
    price          NUMERIC(12,2) NOT NULL,
    url            VARCHAR(512),               -- URL страницы конкурента
    in_stock       BOOLEAN DEFAULT true,
    checked_at     TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE (product_id, competitor_id)         -- одна актуальная цена
);
CREATE INDEX idx_comp_prices_product ON bl_competitor_prices(product_id, checked_at DESC);

История bl_competitor_prices_history — партиционированная по месяцам таблица для хранения изменений без раздувания основной.

Интеграция через API сервиса мониторинга

При использовании готового сервиса агент запрашивает данные и записывает в bl_competitor_prices:

function SyncCompetitorPrices(): string
{
    $client = new PriceMonitoringClient(MONITORING_API_KEY);
    $data   = $client->getPrices(['date' => date('Y-m-d')]);

    foreach ($data['products'] as $item) {
        $productId = ProductMapper::findBySku($item['sku']);
        if (!$productId) continue;

        foreach ($item['competitors'] as $comp) {
            $competitorId = CompetitorTable::getOrCreateByDomain($comp['domain']);

            // Сохраняем в историю перед обновлением
            $current = CompetitorPriceTable::getByProductAndCompetitor($productId, $competitorId);
            if ($current && $current['PRICE'] != $comp['price']) {
                CompetitorPriceHistoryTable::add([
                    'PRODUCT_ID'    => $productId,
                    'COMPETITOR_ID' => $competitorId,
                    'PRICE'         => $current['PRICE'],
                    'RECORDED_AT'   => $current['CHECKED_AT'],
                ]);
            }

            CompetitorPriceTable::addOrUpdate([
                'PRODUCT_ID'    => $productId,
                'COMPETITOR_ID' => $competitorId,
                'PRICE'         => $comp['price'],
                'URL'           => $comp['url'],
                'IN_STOCK'      => $comp['in_stock'],
                'CHECKED_AT'    => new \Bitrix\Main\Type\DateTime(),
            ]);
        }
    }

    return __FUNCTION__ . '();';
}

Вычисление ценовой позиции

При каждом обновлении считаем агрегаты и позицию в bl_product_price_position:

-- Обновляется триггером или агентом после синхронизации
INSERT INTO bl_product_price_position (product_id, our_price, min_comp, avg_comp, max_comp, rank, updated_at)
SELECT
    cp.product_id,
    bcp.PRICE as our_price,
    MIN(cp.price) as min_comp,
    ROUND(AVG(cp.price), 2) as avg_comp,
    MAX(cp.price) as max_comp,
    (SELECT COUNT(*) + 1 FROM bl_competitor_prices cp2
     WHERE cp2.product_id = cp.product_id AND cp2.price < bcp.PRICE) as rank,
    NOW()
FROM bl_competitor_prices cp
JOIN b_catalog_price bcp ON bcp.PRODUCT_ID = cp.product_id AND bcp.CATALOG_GROUP_ID = 1
GROUP BY cp.product_id, bcp.PRICE
ON CONFLICT (product_id) DO UPDATE SET
    our_price = EXCLUDED.our_price, min_comp = EXCLUDED.min_comp,
    avg_comp = EXCLUDED.avg_comp, rank = EXCLUDED.rank, updated_at = NOW();

Оповещения при изменении цен конкурентов

Агент сравнивает новые цены с предыдущими и отправляет уведомление менеджерам при значимых изменениях (конкурент снизил цену ниже нашей):

foreach ($priceChanges as $change) {
    if ($change['new_price'] < $change['our_price'] && $change['old_price'] >= $change['our_price']) {
        // Конкурент только что стал дешевле нас
        $message = sprintf(
            'Конкурент %s снизил цену на %s до %s руб. (наша: %s руб.)',
            $change['competitor_name'],
            $change['product_name'],
            number_format($change['new_price'], 2, ',', ' '),
            number_format($change['our_price'], 2, ',', ' ')
        );
        \Bitrix\Main\Mail\Event::send([
            'EVENT_NAME' => 'COMPETITOR_PRICE_ALERT',
            'LID'        => SITE_ID,
            'C_FIELDS'   => ['MESSAGE' => $message],
        ]);
    }
}

Сроки

Этап Срок
Схема БД и репозитории 2 дня
Агент синхронизации с источником данных 2 дня
Расчёт позиции и агрегатов 1 день
Отображение в карточке товара (админка) 2 дня
Оповещения при изменениях 1 день
Тестирование 1 день
Итого 9–10 дней