Дилер получает каталог с ценами, которые не совпадают с опубликованными. Скидки на группу товаров не дают нужной гибкости: каждый оптовик требует персональную стоимость по договору. Стандартный механизм CCatalogDiscount завязан на типы цен и проценты — невозможно зафиксировать абсолютное значение, которое не меняется при пересчёте базовой цены. Контрактные цены решают эту задачу: фиксированная запись в отдельном хранилище перекрывает любые скидки, но только для конкретного контрагента на срок действия договора.
Наша реализация на Highload-блоках и кастомном провайдере цен обрабатывает до 100 000 контрактных записей за 50 мс на заказ. Опираемся на собственный опыт: более 7 лет работы с Битрикс, 50+ проектов для дилерских сетей. Гарантируем приоритет контрактной цены над любыми акциями. Кэширование в Redis с инвалидацией при изменении договора обеспечивает минимальное время отклика для 500 одновременных пользователей. Первая демонстрация работы — через 3 дня после начала проекта.
Почему стандартные скидки не подходят
Модуль catalog предоставляет скидки (CCatalogDiscount) и типы цен (b_catalog_group). Скидки задаются в процентах или сумме, привязаны к типу цены. Для контрактных цен это не годится: если базовая цена изменилась, контрактная должна остаться на прежнем уровне. Кроме того, скидки применяются ко всей группе — невозможно задать персональную цену одному дилеру без влияния на других. Подробнее о типах цен можно прочитать в документации 1С-Битрикс.
Как устроено хранение контрактных цен
Создаём Highload-блок dealer_contract_prices. Таблица генерируется автоматически по имени блока. Поля:
| Поле | Тип | Описание |
|---|---|---|
UF_DEALER_ID |
Integer | ID дилерской компании |
UF_PRODUCT_ID |
Integer | ID товара |
UF_XML_ID |
String | Артикул (для синхронизации с 1С) |
UF_PRICE |
Double | Контрактная цена |
UF_CURRENCY |
String | Валюта |
UF_DATE_FROM |
DateTime | Начало действия |
UF_DATE_TO |
DateTime | Конец действия |
UF_ACTIVE |
Boolean | Активность |
Индекс по (UF_DEALER_ID, UF_PRODUCT_ID, UF_ACTIVE) — обязателен: без него выборка при 100 000+ записей деградирует в десятки раз. Используем композитный индекс, чтобы покрыть основной сценарий: WHERE dealer=... AND product=... AND active=1.
Как работает логика применения
Реализуем кастомный провайдер цен, подключаемый к событию OnSaleBasketBeforeSaved или через расширение Bitrix\Catalog\v2\Price. Алгоритм:
- Определяем компанию текущего пользователя из сессии.
- Ищем в
dealer_contract_pricesзапись с совпадением дилера, товара, даты и активности. - Если запись найдена — используем
UF_PRICEкак финальную, игнорируя стандартный тип цены. - Если нет — откатываемся к типу цены дилера по его группе.
Результат кэшируется в Redis по ключу contract_price_{dealerId}_{productId} на 1 час. Инвалидация — при обновлении записи в Highload-блоке через OnAfterHLBlockElementUpdate. Такой подход в 5 раз быстрее, чем перебор всех скидок модуля catalog при 50 000 товаров.
Как загружать цены из 1С
Контрактные цены ведутся в 1С. Синхронизация через агент:
- 1С выгружает XML с дилером (код в 1С), артикулом, ценой и периодом.
- Агент находит дилера по
UF_1C_IDв Highload-блоке компаний, товар — поXML_ID. - Создаёт или обновляет запись в
dealer_contract_prices. - Истёкшие записи помечает
UF_ACTIVE= false.
Частота — событийно при обновлении прайсов или по крону 2 раза в сутки. Ошибки синхронизации логируем: если контрактная цена отсутствует, дилер видит базовую цену с предупреждением.
Почему Redis лучше файлового кэша для контрактных цен?
Файловый кэш в Битрикс (BXCache) работает на уровне страниц и компонентов. Для контрактных цен нужен кэш, который быстро отдаёт одиночные записи. Redis в памяти обеспечивает время отклика <1 мс. Важно настроить тегированное кэширование: инвалидация по тегу contract:dealer:{id} при изменении договора. Это избавляет от полного сброса кэша и экономит ресурсы сервера.
Как тестировать нагрузку контрактных цен?
Перед запуском проводим нагрузочное тестирование. Условия: 500 одновременных пользователей, 100 000 контрактных записей, запрос к корзине с 20-30 товарами. Ожидаемый отклик — не более 100 мс. Используем ab или locust. При проблемах добавляем мидлвару для сглаживания пиков. Результаты фиксируем в отчёте.
Что входит в настройку контрактных цен
| Компонент | Описание |
|---|---|
| Highload-блок | Поля под вашу номенклатуру, индексы, настройка кэширования |
| Провайдер цен | Кастомный с поддержкой Redis, событие OnSaleBasketBeforeSaved |
| Агент синхронизации | Чтение XML из 1С, обновление записей, логирование ошибок |
| Отображение в каталоге | Метка «Контрактная» в result_modifier.php |
| Тестирование | Нагрузочное: 500 одновременных заказов, отклик <100 мс |
| Обучение | Документация, туториал по обновлению справочников |
Сроки и опыт команды
Настройка хранилища и логики — 1-2 недели. С интеграцией выгрузки из 1С — 2-3 недели. Оценку проекта проводим бесплатно, присылаем смету с этапами. В штате сертифицированные специалисты 1С-Битрикс с опытом от 5 лет.
Получите консультацию по вашему проекту — рассчитаем срок и стоимость для вашего каталога. Свяжитесь с нами, чтобы обсудить детали.







