Настройка уведомления о снижении цены товара 1С-Битрикс
Цена на товар снизилась — нужно оповестить пользователей, которые добавили его в избранное или явно подписались на снижение цены. Механизм состоит из двух частей: отслеживание изменений цены и рассылка уведомлений заинтересованным пользователям. В Битрикс оба компонента реализуются без сторонних сервисов.
Фиксация изменений цены
Цены каталога хранятся в 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







