Налаштування сповіщення про зниження ціни товара 1С-Bitrix
Ціна на товар знизилась — потрібно повідомити користувачів, які додали його до улюблених або явно підписалися на зниження ціни. Механізм складається з двох частин: відстеження змін ціни та розсилка сповіщень зацікавленим користувачам. У Bitrix обидва компоненти реалізуються без сторонніх сервісів.
Фіксація змін ціни
Ціни каталогу зберігаються в b_catalog_price. При зміні ціни через API (CCatalogProduct::SetPrice() або \Bitrix\Catalog\PriceTable::update()) спрацьовує подія OnCatalogPriceUpdate. Підписуємось на неї:
AddEventHandler('catalog', 'OnCatalogPriceUpdate', function($fields) {
$productId = $fields['PRODUCT_ID'];
$newPrice = $fields['PRICE'];
$typeId = $fields['CATALOG_GROUP_ID']; // тип ціни
// Отримуємо стару ціну з нашої таблиці снимків
$oldPrice = PriceSnapshotTable::getLastPrice($productId, $typeId);
if ($oldPrice && $newPrice < $oldPrice) {
// Ставимо завдання на розсилку сповіщень
PriceDropQueue::add($productId, $newPrice, $oldPrice);
}
// Зберігаємо новий снимок
PriceSnapshotTable::save($productId, $typeId, $newPrice);
});
Таблиця снимків bl_price_snapshot: поля product_id, catalog_group_id, price, currency, recorded_at.
Зберігання підписок користувачів
Створіть таблицю bl_price_watch з полями:
-
user_id— ID зb_user(NULL для анонімів) -
email— email для сповіщення -
product_id— ID товара -
target_price— бажана ціна (опціонально, NULL = будь-яке зниження) -
created_at -
notified_at— дата останнього сповіщення
Кнопка «Стежити за ціною» на сторінці товара відправляє AJAX-запит, який вставляє рядок в bl_price_watch. Для авторизованих користувачів email береться автоматично з b_user.
Відправка сповіщень
Агент запускається раз на 30 хвилин. Логіка:
- Читаємо очередь
bl_price_drop_queue - Для кожного товара знаходимо підписників в
bl_price_watchу якихtarget_price IS NULL OR target_price >= new_price - Сповіщення відправляється через
\Bitrix\Main\Mail\Event::send()з типомCATALOG_PRICE_DROP:
\Bitrix\Main\Mail\Event::send([
'EVENT_NAME' => 'CATALOG_PRICE_DROP',
'LID' => SITE_ID,
'C_FIELDS' => [
'USER_EMAIL' => $subscriber['email'],
'PRODUCT_NAME' => $productName,
'OLD_PRICE' => number_format($oldPrice, 0, '.', ' '),
'NEW_PRICE' => number_format($newPrice, 0, '.', ' '),
'PRODUCT_URL' => $productUrl,
'DISCOUNT_PCT' => round((1 - $newPrice / $oldPrice) * 100),
],
]);
Після відправки ставимо notified_at = NOW() та можемо додати логіку: не сповіщувати повторно по одному товару частіше ніж раз на 7 днів.
Що налаштовуємо
- Обробник
OnCatalogPriceUpdateз записом у таблицю снимків та очередь - Таблиці
bl_price_snapshotтаbl_price_watch - UI-кнопку «Стежити за ціною» в шаблоні компонента
catalog.element - Тип поштової події
CATALOG_PRICE_DROPта HTML-шаблон листа - Агент розсилки з дедубліцією за
notified_at







