Налаштування динамічного ціноутворення на 1С-Bitrix
Динамічне ціноутворення — це коли ціна змінюється автоматично за заданими правилами: залежно від попиту, залишків, конкурентів, часу доби або поведінки користувача. На відміну від знижок та акцій, тут ціна в b_catalog_price може змінюватися кілька разів на день. Реалізація вимагає розуміння того, як Bitrix застосовує ціни, та чіткої архітектури правил.
Як Bitrix розраховує підсумкову ціну
Ланцюжок розрахунку: базова ціна (b_catalog_price) → знижки каталогу (b_catalog_discount) → правила кошика (b_sale_discount) → результат. Динамічне ціноутворення працює на першому рівні — змінює базову ціну, або перехоплює через подію OnGetOptimalPrice та повертає іншу вартість.
Другий варіант (через подію) переважний: не забруднює історію цін у b_catalog_price, не впливає на індексацію цін, легше відкатити.
Правила динамічного ціноутворення
Правила зберігаються у користувацькій таблиці bl_dynamic_pricing_rules:
| Поле | Опис |
|---|---|
rule_type |
stock / demand / competitor / time |
iblock_id |
інфоблок або NULL (усі) |
product_id |
конкретний товар або NULL (усі в розділі) |
condition_json |
параметри умови (залишок, година, коефіцієнт) |
price_modifier |
коефіцієнт (1.15 = +15%, 0.9 = -10%) |
priority |
порядок застосування при конфлікті правил |
active |
включено/виключено |
Обробник події
AddEventHandler('catalog', 'OnGetOptimalPrice', function(&$fields) {
$productId = $fields['PRODUCT_ID'];
$basePrice = $fields['PRICE']['PRICE'] ?? null;
if (!$basePrice) return;
$modifier = DynamicPricingEngine::getModifier($productId);
if ($modifier && $modifier != 1.0) {
$fields['PRICE']['PRICE'] = round($basePrice * $modifier, 2);
$fields['PRICE']['BASE_PRICE'] = $basePrice; // оригінал для відображення знижки
}
});
DynamicPricingEngine::getModifier() завантажує застосовні правила з кешу (\Bitrix\Main\Data\Cache, TTL 300 сек) та обчислює результуючий коефіцієнт. При кількох правилах — множимо або беремо мінімальний/максимальний залежно від бізнес-логіки.
Правило за залишками склада
Якщо залишок товара впадає нижче порога — підвищуємо ціну (спонукаємо купити раніше або обмежуємо ажіотаж). Залишки беремо з b_catalog_store_product через \Bitrix\Catalog\StoreProductTable:
$stock = \Bitrix\Catalog\StoreProductTable::getList([
'filter' => ['PRODUCT_ID' => $productId],
'select' => ['AMOUNT'],
'runtime' => [new \Bitrix\Main\ORM\Fields\ExpressionField('TOTAL', 'SUM(%s)', 'AMOUNT')],
])->fetch()['TOTAL'] ?? 0;
if ($stock < 5) return 1.2; // +20% при залишку < 5 шт
if ($stock < 20) return 1.1; // +10% при залишку < 20 шт
return 1.0;
Кешування та продуктивність
Подія OnGetOptimalPrice викликається при кожному рендері ціни — у каталозі, на деталях, у кошику. Без кешу одна сторінка каталогу з 48 товарами зробить 48 викликів до БД. Кешуйте модифікатор за PRODUCT_ID з TTL 5 хвилин. При зміні залишків або правил — скидайте кеш за тегом dynamic_price_{productId}.
Що налаштовуємо
- Таблицю
bl_dynamic_pricing_rulesз набором правил - Клас
DynamicPricingEngineз кешуванням та логікою застосування правил - Обробник події
OnGetOptimalPriceвinit.phpабо модулі - Інтерфейс адміністратора для управління правилами
- Логування змін цін у
bl_dynamic_pricing_logдля аудиту







