Настройка триггера поступления товара на склад: автоматическое уведомление в 1С-Битрикс
Представьте: товар закончился, десятки пользователей нажали «Уведомить о поступлении», склад пополнился, но никто не получил письма. Причина — отсутствие связи между событием пополнения склада и списком ожидающих. В этой статье разберём, как настроить триггер поступления товара на склад в 1С-Битрикс: от простого каталога до многоскладского учёта с интеграцией 1С. Мы реализовали такие механизмы на 30+ проектах — расскажем о типичных ошибках и оптимальных решениях. По данным официальной документации Битрикс, событие OnProductUpdate — ключевой инструмент для отслеживания изменений остатков. Но его одного недостаточно: нужно грамотно обработать подписки и многоскладскую логику. Наш опыт показывает: правильная реализация сокращает время реакции на поступление товара в 3 раза по сравнению с ручной проверкой.
Как работает складской учёт в Битрикс?
В Битрикс остатки товаров живут в двух местах в зависимости от конфигурации. В простом каталоге (без складского учёта) используется поле CATALOG_QUANTITY в таблице b_catalog_product. Обновляется напрямую через CCatalogProduct::Update() или через обмен с 1С. В многоскладском учёте (модуль catalog + склады) данные хранятся в таблице b_catalog_store_product с полями PRODUCT_ID, STORE_ID, AMOUNT. Общий остаток агрегируется. При обмене с 1С через CommerceML данные пишутся в b_catalog_store_product. Стандартный обработчик изменения остатка — OnProductUpdate в модуле catalog. Он срабатывает при любом изменении записи в b_catalog_product, включая количество. Однако для многоскладского учёта этого недостаточно — событие не отслеживает изменения по отдельным складам. Сравнение простое: обработчик OnProductUpdate работает мгновенно, но только для общего остатка, а агент (проверка каждые 5 минут) охватывает все склады, но с задержкой.
Вот пример базового обработчика:
AddEventHandler('catalog', 'OnProductUpdate', function($id, $fields) {
if (isset($fields['QUANTITY']) && $fields['QUANTITY'] > 0) {
// Товар поступил на склад — была нулевая позиция
checkAndNotifyWaitlist($id);
}
});
Проблема: OnProductUpdate срабатывает при любом изменении продукта, не только при пополнении склада. Чтобы отфильтровать именно событие «появился из нуля», нужно сравнивать предыдущее значение. До PHP-события данные ещё в БД, поэтому читаем старое значение в OnBeforeProductUpdate:
AddEventHandler('catalog', 'OnBeforeProductUpdate', function($id, &$fields) {
$old = \Bitrix\Catalog\ProductTable::getByPrimary($id, ['select' => ['QUANTITY']])->fetch();
$fields['_OLD_QUANTITY'] = (float)($old['QUANTITY'] ?? 0);
});
Почему стандартный обработчик не подходит для многоскладского учёта?
При многоскладском учёте событие OnProductUpdate не срабатывает при изменении b_catalog_store_product. Для складских операций нужно подписаться на события модуля catalog более глубокого уровня — либо использовать хук после записи документа складского учёта через \Bitrix\Catalog\Document\DocumentTable. Альтернативный подход: агент, который каждые 5 минут проверяет b_catalog_store_product на появление ненулевых остатков по товарам из листа ожидания. Менее элегантно, но работает стабильнее при нестандартных схемах обновления остатков (например, при прямом UPDATE через 1С-коннектор). По нашему опыту, агент справляется с нагрузкой в 90% случаев, а обработчик документов реагирует в 10 раз быстрее, но требует более аккуратной реализации.
Сравнение подходов: агент vs обработчик документов
| Параметр | Агент | Обработчик документов |
|---|---|---|
| Реакция на изменения | Задержка до 5 минут | Мгновенная |
| Нагрузка на БД | Периодические запросы | Только при изменениях |
| Сложность реализации | Низкая | Средняя |
| Надёжность при массовых обновлениях | Высокая | Высокая |
| Рекомендация | Для нестандартных обновлений | Для стандартных операций |
Как хранить подписки на поступление?
Модуль catalog не имеет встроенного механизма «уведомить о поступлении». Нужна собственная таблица:
CREATE TABLE bl_stock_notify (
id SERIAL PRIMARY KEY,
product_id INT NOT NULL,
user_id INT,
email VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
notified_at TIMESTAMP,
UNIQUE (product_id, email)
);
Форма на сайте пишет в эту таблицу. Уникальный ключ (product_id, email) защищает от дублей при повторных подписках.
Обработчик пополнения
function checkAndNotifyWaitlist(int $productId): void
{
$connection = \Bitrix\Main\Application::getConnection();
$waitlist = $connection->query(
"SELECT * FROM bl_stock_notify WHERE product_id = {$productId} AND notified_at IS NULL"
)->fetchAll();
if (empty($waitlist)) {
return;
}
$product = \CIBlockElement::GetByID($productId)->GetNextElement();
$name = $product->GetField('NAME');
$url = $product->GetField('DETAIL_PAGE_URL');
foreach ($waitlist as $row) {
\Bitrix\Main\Mail\Event::send([
'EVENT_NAME' => 'STOCK_ARRIVED',
'LID' => SITE_ID,
'C_FIELDS' => [
'EMAIL' => $row['email'],
'PRODUCT_NAME' => $name,
'PRODUCT_URL' => 'https://' . $_SERVER['SERVER_NAME'] . $url,
],
]);
$connection->queryExecute(
"UPDATE bl_stock_notify SET notified_at = NOW() WHERE id = {$row['id']}"
);
}
}
Сравнение подходов: простой каталог vs многоскладской учёт
| Параметр | Простой каталог | Многоскладской учёт |
|---|---|---|
| Событие изменения остатка | OnProductUpdate |
Требуется агент или обработчик документов |
| Таблица остатков | b_catalog_product |
b_catalog_store_product |
| Сложность реализации | Низкая | Средняя |
| Время настройки | 1-2 дня | 3-5 дней |
| Надёжность при массовых обновлениях | Высокая | Требует дополнительной синхронизации |
Что входит в работу: deliverables
- Разработка и установка обработчиков
OnBeforeProductUpdateиOnProductUpdateс проверкой перехода «0 → N». - Создание таблицы
bl_stock_notifyи интеграция формы подписки на сайте. - Настройка почтового шаблона
STOCK_ARRIVEDв административном разделе. - Для многоскладской конфигурации — реализация агента или обработчика документов склада.
- Логика частичного поступления: выбор стратегии (уведомить всех или по очереди).
- Документация по доступам и тестирование на staging-окружении.
- Поддержка в течение 14 дней после запуска.
Процесс работы
- Аналитика: изучаем текущую конфигурацию Битрикс, схему обмена с 1С, нагрузку на базу.
- Проектирование: выбираем оптимальный метод (обработчики или агент), согласуем логику очереди уведомлений.
- Реализация: пишем код, создаём SQL-таблицу, настраиваем почтовые события.
- Тестирование: проверяем на копии каталога, имитируем поступление товара, отслеживаем отправку писем.
- Деплой и мониторинг: переносим на боевой сервер, логируем первые срабатывания.
Типичные ошибки при самостоятельной настройке
- Неправильная фильтрация события: отправка уведомлений при любом изменении товара, а не только при появлении из нуля.
- Отсутствие уникального ключа в таблице подписок — дубли писем.
- Игнорирование многоскладской архитектуры — уведомления не приходят при пополнении на конкретном складе.
- Отсутствие обработки частичного поступления: если пришло меньше единиц, чем подписчиков.
Эти проблемы легко избежать, следуя описанной методике.
Сроки и стоимость
Ориентировочные сроки — от 2 до 10 рабочих дней в зависимости от сложности. Стоимость рассчитывается индивидуально после анализа вашей конфигурации. Свяжитесь с нами для предварительной оценки — мы гарантируем прозрачный результат и поддержку после внедрения. Получите консультацию — мы подберём оптимальное решение под вашу схему учёта. Наш опыт в этой области — более 30 проектов по автоматизации уведомлений на Битрикс.







