События массовой обработки очередного шага импорта
События вызываются после того, как модуль провел очередной шаг массового импорта товаров (модификаций, услуг и комплектов).
[OnAfterImportItems] - вызывается после массового импорта новых сущностей
[OnAfterUpdateItems] - вызывается после массового импорта существующих сущностей (после их обновления)
[OnAfterImportItems] Событие после импорта новых элементов
Срабатывает один раз после обработки порции новых элементов. ID созданных элементов приходят в createdIds (с версии 3.9.0), на старых версиях элемент ищется по внешнему коду.
Событие вызывается, только если в порции были новые элементы и для сущности не включён режим «только обновление».
Событие не требует возврата значения. Используется для выполнения действий после создания элементов (уведомления, дополнительная обработка и т.д.).
items — это не список созданных элементовВ items лежат все новые элементы порции, переданные на создание: и отклонённые обработчиком OnBeforeAddItem, и пропущенные архивные, и модификации без найденного родителя, и упавшие с ошибкой. Что реально создано — смотрите по createdIds.
- Описание события
- Пример кода
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
entity | string | Сущность: product, variant, bundle, service |
items | array | Все новые объекты МС порции, переданные на создание (ключ — внешний код) |
createdIds | array | ID созданных элементов инфоблока (ключ — внешний код). С версии 3.9.0 |
paramList | array | Параметры шага импорта: инфоблок, раздел, группы товаров. С версии 3.9.0 |
«Внешний код» в ключах — это значение, по которому модуль идентифицирует товары: externalCode МойСклад, а в режиме идентификации по идентификатору МойСклад — id сущности.
Структура items
[
'externalCode1' => $itemMs, // объект МойСклад
'externalCode2' => $itemMs,
// ...
]
// Для модификаций внешний код будет без символа #
// Доступ к полям объекта МС:
$itemMs->name // 'Название товара'
$itemMs->externalCode // 'externalCode1'
$itemMs->archived // false
$itemMs->description // 'Описание'
$itemMs->article // 'ART-001'
$itemMs->meta->type // 'product' | 'variant' | 'bundle' | 'service'
$itemMs->meta->href // 'https://api.moysklad.ru/api/remap/1.2/entity/product/...'
Структура createdIds
Вместе с ним в 3.9.0 добавлен paramList. До этой версии событие передавало только entity и items.
[
'externalCode1' => 1234, // ID созданного элемента инфоблока
'externalCode2' => 1235,
// ...
]
createdIds избавляет от повторного поиска элементов по XML_ID после импорта. В массиве только те сущности, для которых был создан элемент инфоблока: отклонённые событием OnBeforeAddItem, пропущенные и те, у которых упал CIBlockElement::Add(), сюда не попадают. Ключи те же, что и в items, поэтому массивы сопоставляются напрямую.
ID пишется в createdIds сразу после успешного CIBlockElement::Add(). Если после этого не удалось создать товар торгового каталога (\Bitrix\Catalog\Model\Product::add()), элемент инфоблока остаётся, и его ID в createdIds есть — а ошибка уходит в лог импорта.
Структура paramList
[
'IBLOCK_ID' => 5, // инфоблок каталога
'SECTION_ID' => 10, // раздел по умолчанию, если задан в настройках
'GROUP_ITEMS' => [...], // выбранные группы товаров МойСклад, если фильтр по группам включён
'GROUP_ITEM' => {...}, // первая из выбранных групп
'IS_SKU' => true, // импортируются торговые предложения (true только для variant)
// только для variant:
'PRODUCT_IBLOCK_ID' => 4, // инфоблок товаров — родителей торговых предложений
'SKU_PROPERTY_ID' => 25, // свойство привязки ТП к товару (CML2_LINK)
'PARENT_XML_ID' => '...', // внешний код родителя и
'PARENT_ID' => 1200, // его ID — остаток от последней обработанной модификации, не используйте
]
SECTION_ID есть, только если раздел задан в настройках; GROUP_ITEMS и GROUP_ITEM — только если включён фильтр по группам товаров.
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnAfterImportItems',
'OnAfterImportItemsHandler'
);
function OnAfterImportItemsHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
$entity = $eventParams['entity']; //сущность в МойСклад, которая обрабатывается (четыре варианта значения: product / variant / bundle / service)
$items = $eventParams['items']; //массив обрабатываемых объектов (ниже пример их обработки)
$createdIds = $eventParams['createdIds']; //ID созданных элементов инфоблока, ключ — внешний код
$paramList = $eventParams['paramList']; //параметры шага импорта
foreach ($items as $xmlId => $itemMs) {
// $xmlId -- внешний код элемента, для модификаций это значение будет без решетки # во внешнем коде
// $itemMs -- сущность в МС, доступ к полям идет через свойства объекта
// ID созданного элемента доступен сразу, искать его по XML_ID не нужно
$elementId = isset($createdIds[$xmlId]) ? (int)$createdIds[$xmlId] : 0;
if ($elementId <= 0) {
// элемент не создан: отклонён обработчиком OnBeforeAddItem, пропущен или упал с ошибкой
continue;
}
}
}
[OnAfterUpdateItems] Событие после импорта существующих элементов
Срабатывает после обновления порции существующих элементов на очередном шаге импорта. Передаёт данные как из Битрикс, так и из МойСклад для каждого обработанного элемента.
Событие не требует возврата значения. Считается устаревшим — предпочтительнее использовать события на уровне отдельных элементов (OnBeforeUpdateItem, OnBeforeUpdateItemProduct и т.д.).
- Описание события
- Пример кода
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
entity | string | Сущность: product, variant, bundle, service |
items | array | Массив обработанных элементов (ключ — внешний код) |
products | array | Массив данных товаров торгового каталога (ключ — ID элемента) |
Структура items
[
'externalCode1' => [
'BX' => [ // элемент инфоблока Битрикс
'ID' => 1234,
'IBLOCK_ID' => 5,
'NAME' => 'Название товара',
'XML_ID' => 'externalCode1',
'ACTIVE' => 'Y',
// ... и CODE, SORT, PREVIEW_TEXT, DETAIL_TEXT, PREVIEW_PICTURE, DETAIL_PICTURE
],
'MS' => $itemMs // объект из МойСклад
],
'externalCode2' => [
'BX' => [...],
'MS' => $itemMs
],
// ...
]
BXМодуль выбирает только ID, IBLOCK_ID, NAME, CODE, XML_ID, DETAIL_TEXT, PREVIEW_TEXT, ACTIVE, PREVIEW_PICTURE, DETAIL_PICTURE, SORT (Битрикс добавляет к ним PREVIEW_TEXT_TYPE и DETAIL_TEXT_TYPE) — других полей элемента (например, IBLOCK_SECTION_ID) в массиве нет. Строки получены через GetNext(): значения HTML-экранированы, исходные лежат под ключами с тильдой (~NAME, ~DETAIL_TEXT и т.д.).
Структура products
[
1234 => [ // ID элемента Битрикс
'ID' => 1234,
'TYPE' => 1,
'QUANTITY' => 10.0,
'WEIGHT' => 500.0,
'WIDTH' => 0.0,
'LENGTH' => 0.0,
'HEIGHT' => 0.0,
'MEASURE' => 5,
'VAT_ID' => 1,
'VAT_INCLUDED' => true, // для variant — строка 'Y'/'N', см. ниже
'UF_PRODUCT_GROUP' => 0, // только при включённых опциях маркировки
'BARCODE_LIST' => [...], // если загружены штрихкоды
// ... остальные поля таблицы товаров каталога
],
// ... другие товары
]
- Для
product,bundleиserviceмодуль ещё до события приводитVAT_INCLUDEDкbool(true/false). Дляvariantзначение остаётся строкой'Y'/'N'. UF_PRODUCT_GROUP(и другиеUF_*) есть, только если включена опция импорта типа маркировки (tracking_type) или маркировки от родителя (parent_tracking).
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnAfterUpdateItems',
'OnAfterUpdateItemsHandler'
);
function OnAfterUpdateItemsHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
$entity = $eventParams['entity']; //сущность в МойСклад, которая обрабатывается (четыре варианта значения: product / variant / bundle / service)
$items = $eventParams['items']; //массив обрабатываемых объектов (ниже пример их обработки)
$productsBxArray = $eventParams['products']; //массив полей товара
foreach ($items as $xmlId => $currentItem) {
// $xmlId -- внешний код элемента, для модификаций это значение будет без решетки # во внешнем коде
$itemBx = $currentItem['BX']; //сущность в битриксе, доступ к полям идет через ассоциативный массив
$item = $currentItem['MS']; //сущность в МС, доступ к полям идет через свойства объекта
//поля товара в торговом каталоге
$productBxArray = isset($productsBxArray[$itemBx['ID']]) ? $productsBxArray[$itemBx['ID']] : [];
}
}