Событие перед изменением товара
[OnBeforeUpdateItemProduct] - событие перед изменением товара
Событие срабатывает перед обновлением полей товара торгового каталога через \Bitrix\Catalog\Model\Product::update(). Работает со всеми сущностями из МС кроме модификаций (variant). Для модификаций есть отдельное событие ниже.
Событие вызывается для каждого обновляемого элемента, даже если productUpdate пуст. Product::update() модуль вызывает только при непустом итоговом массиве — поэтому вернуть SUCCESS с пустым массивом значит отменить обновление товара.
Относится к обоим событиям на странице.
- Исключение из обработчика модуль не перехватывает — оно обрывает шаг импорта. Оборачивайте код в
try/catch. - Параметры последнего обработчика, вернувшего
EventResult::SUCCESS, целиком заменяютproductUpdate. Ответы не сливаются: каждый обработчик получает исходный массив модуля. EventResult::ERRORигнорируется.SUCCESSбез параметров даётnull, который модуль передаёт вcount()— на PHP 8 этоTypeError. Всегда возвращайте полный массив, а если менять нечего — не возвращайте ничего.
- Описание события
- Пример кода
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
entity | string | Сущность: product, bundle, service |
currentItem | array | Данные о текущем элементе (содержит BX и MS) |
productCurrentItem | array | Текущие поля товара в торговом каталоге |
productUpdate | array | Массив данных для передачи в Product::update() |
Структура currentItem
[
'BX' => [ // элемент инфоблока Битрикс
'ID' => 1234,
'IBLOCK_ID' => 5,
'NAME' => 'Название товара',
'XML_ID' => 'abc123externalcode',
'ACTIVE' => 'Y',
// ... другие поля элемента инфоблока
],
'MS' => $itemMs // объект из МойСклад
]
Структура productCurrentItem
[
'ID' => 1234,
'TYPE' => 1, // 1 = простой, 3 = с ТП, 6 = комплект
'QUANTITY' => 10.0,
'WEIGHT' => 500.0, // вес в граммах
'WIDTH' => 0.0,
'LENGTH' => 0.0,
'HEIGHT' => 0.0,
'MEASURE' => 5, // ID единицы измерения
'VAT_ID' => 1, // ID ставки НДС
'VAT_INCLUDED' => true, // НДС включен в цену — уже приведён к bool, не 'Y'/'N'
'UF_PRODUCT_GROUP' => 0, // маркировка — только при включённых опциях маркировки
'BARCODE_LIST' => [...] // штрихкоды (если загружены)
]
VAT_INCLUDEDмодуль приводит кboolещё до события — сравнивайте сtrue/false, а не с'Y'.UF_PRODUCT_GROUP(и другиеUF_*) есть, только если включена опция импорта типа маркировки (tracking_type) или маркировки от родителя (parent_tracking).- Если у элемента нет строки в таблице товаров каталога,
productCurrentItemсодержит только['VAT_INCLUDED' => false].
Структура productUpdate
Содержит поля, собранные по опциям обновления. Габариты, вес, тип и НДС попадают сюда, только если отличаются от текущих; единица измерения (MEASURE) — без сравнения, всегда при включённой опции и найденной единице:
[
'WEIGHT' => 750.0, // вес
'WIDTH' => 10.0, // ширина
'LENGTH' => 20.0, // длина
'HEIGHT' => 5.0, // высота
'MEASURE' => 6, // единица измерения
'TYPE' => 3, // тип товара, только для entity = product
'VAT_ID' => 2, // ставка НДС
'VAT_INCLUDED' => 'N', // НДС не включен — здесь строка 'Y'/'N'
]
TYPE меняется только для product и только если не включена опция игнорирования типа товара:
3(TYPE_SKU) — у товара в МойСклад есть модификации, а в каталоге он ещё не SKU;1(TYPE_PRODUCT) — модификаций больше нет (variantsCount <= 0), а в каталоге товар всё ещё SKU.
Возвращаемое значение
Верните EventResult::SUCCESS с полным модифицированным массивом $productUpdate. Пустой массив отменяет обновление товара каталога.
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $productUpdate);
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnBeforeUpdateItemProduct',
'OnBeforeUpdateItemProductHandler'
);
function OnBeforeUpdateItemProductHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
$entity = $eventParams['entity']; //сущность в МойСклад, которая обрабатывается (три варианта значения: product / bundle / service)
$currentItem = $eventParams['currentItem']; //данные о текущем элементе инфоблока, подробнее ниже
$itemBx = $currentItem['BX']; //текущий элемент инфоблока, доступ к полям через массив
$item = $currentItem['MS']; //этот же товар из МС, доступ к полям через поля объекта
//это массив данных, который затем передается в \Bitrix\Catalog\Model\Product::update();
$productUpdate = $eventParams['productUpdate'];
//Отправляем \Bitrix\Main\EventResult::SUCCESS только в случае, если нужно поменять данные перед отправкой
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $productUpdate);
}
[OnBeforeUpdateItemVariant] - событие перед изменением товара (для модификаций)
Аналогично OnBeforeUpdateItemProduct, но срабатывает только для модификаций (variant). Дополнительно передаёт данные о родительском товаре.
Событие вызывается не для каждой модификации. Нужно, чтобы одновременно:
- в опциях обновления модификаций была включена хотя бы одна из «родительских» опций: маркировка, вес, коэффициент, единица измерения, габариты от родителя (
parent_tracking,parent_weight,parent_ratio,parent_measure,parent_sizes) или НДС (vat,vat_inc); - у торгового предложения было заполнено свойство привязки к товару (
CML2_LINK); - родительский товар нашёлся в таблице товаров каталога.
Как и у события товара, оно вызывается и при пустом productUpdate, а Product::update() выполняется только при непустом итоговом массиве.
- Описание события
- Пример кода
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
entity | string | Всегда variant |
currentItem | array | Данные о текущем элементе (содержит BX и MS) |
parentItem | array | Данные о родительском товаре |
productCurrentItem | array | Текущие поля товара (торг. предложения) в торговом каталоге |
productUpdate | array | Массив данных для передачи в Product::update() |
Структура parentItem
[
'parentId' => 5678, // ID родительского товара в Битрикс
'parentProductParams' => [ // данные родительского товара в торговом каталоге
'ID' => 5678,
'TYPE' => 3,
'QUANTITY' => 0.0,
'WEIGHT' => 500.0,
'WIDTH' => 10.0,
'LENGTH' => 20.0,
'HEIGHT' => 5.0,
'MEASURE' => 5,
'VAT_ID' => 1,
'VAT_INCLUDED' => 'Y', // здесь строка 'Y'/'N', не bool
'UF_PRODUCT_GROUP' => 0, // только при включённой опции parent_tracking
]
]
В отличие от OnBeforeUpdateItemProduct, здесь VAT_INCLUDED и в parentProductParams, и в productCurrentItem — строка 'Y'/'N': модуль его не приводит.
Возвращаемое значение
Верните EventResult::SUCCESS с модифицированным массивом $productUpdate.
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $productUpdate);
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnBeforeUpdateItemVariant',
'OnBeforeUpdateItemVariantHandler'
);
function OnBeforeUpdateItemVariantHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
$entity = $eventParams['entity']; //сущность в МойСклад, которая обрабатывается (только variant)
$currentItem = $eventParams['currentItem']; //данные о текущем элементе инфоблока
$itemBx = $currentItem['BX']; //текущий элемент инфоблока, доступ к полям через массив
$item = $currentItem['MS']; //этот же товар из МС, доступ к полям через поля объекта
$parentItem = $eventParams['parentItem']; //данные о родительском товаре в битриксе
$parentItemId = $parentItem['parentId']; // ID родительского товара в битриксе
$parentItemProductParams = $parentItem['parentProductParams']; //данные родительского товара в торговом каталоге
//это массив данных, который затем передается в \Bitrix\Catalog\Model\Product::update();
$productUpdate = $eventParams['productUpdate'];
//Отправляем \Bitrix\Main\EventResult::SUCCESS только в случае, если нужно поменять данные перед отправкой
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $productUpdate);
}