Событие импорта комплекта
[OnImportBundle] Подстановка компонентов набора
Событие OnImportBundle вызывается, когда модуль собирает состав комплекта МойСклад в набор торгового каталога Битрикс (CCatalogProductSet). Обработчик может взять поиск компонентов на себя: вернуть готовый список товаров набора вместо того, что модуль нашёл бы сам.
Когда вызывается:
- комплекты импортируются как наборы (тип импорта комплектов
BUNDLE) и обрабатывается сущностьbundle; - при создании — после успешного создания товара каталога (
Product::add()); если товар создать не удалось, события нет; - при обновлении — для каждого комплекта порции на каждом прогоне, после события
OnBeforeUpdateItemProduct, независимо от того, изменилось ли что-нибудь; - только если у комплекта в МойСклад есть компоненты (
components->rows) и заполненexternalCode. Иначе модуль пишет в лог «Не найдены компоненты комплекта», и события нет.
- Исключение из обработчика модуль не перехватывает — оно обрывает шаг импорта. Оборачивайте код в
try/catch. - Модуль перебирает ответы всех обработчиков; значения берутся из последнего
EventResult::SUCCESS. Ответы не сливаются. EventResult::ERRORигнорируется.- Если ни один обработчик не вернул
SUCCESS, модуль ищет компоненты сам.
- Описание события
- Пример вызова события
- Примеры использования
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
productId | int | ID элемента комплекта в Битрикс |
itemMs | object | Объект комплекта из МойСклад |
bundleCache | object | Состав комплекта, подготовленный модулем |
currentComponentsArray | array | Текущие компоненты набора в Битрикс (ITEMS набора). При создании — всегда [] |
bundlePartIblockId | array | ID инфоблоков, в которых модуль ищет компоненты (из настроек); пустой массив — искать везде |
Структура bundleCache
(object)[
'href' => 'https://api.moysklad.ru/api/remap/1.2/entity/bundle/...',
'externalCode' => 'bundleExternalCode',
'components' => [
// ссылка на ассортимент компонента => количество
'https://api.moysklad.ru/api/remap/1.2/entity/product/...' => 2,
'https://api.moysklad.ru/api/remap/1.2/entity/variant/...' => 1,
],
]
Возвращаемое значение
Чтобы подставить свой состав, верните SUCCESS с двумя ключами:
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, [
'isAllComponentLoaded' => true, // bool: все компоненты найдены
'componentsArray' => [ // компоненты набора
['ITEM_ID' => 1001, 'QUANTITY' => 2, 'DISCOUNT_PERCENT' => 0, 'SORT' => 100],
['ITEM_ID' => 1002, 'QUANTITY' => 1, 'DISCOUNT_PERCENT' => 0, 'SORT' => 100],
],
]);
После SUCCESS собственный поиск компонентов модуль пропускает целиком.
Набор сохраняется, только если isAllComponentLoaded === true и число элементов в componentsArray равно числу компонентов в bundleCache->components. Иначе набор не трогается, а в лог пишется «Ошибка поиска компонентов для комплекта».
Дальше модуль действует как обычно: если набора у товара ещё нет — создаёт его, если есть — обновляет и пересчитывает наборы товара. Существующий набор сейчас перезаписывается на каждом прогоне, даже если состав не изменился, — это касается и штатного поиска компонентов модулем.
//Пример кода нужно вставить в файл init.php
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnImportBundle',
'OnImportBundleHandler'
);
function OnImportBundleHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
$productId = $eventParams['productId']; // ID комплекта в Битрикс
$itemMs = $eventParams['itemMs']; // комплект из МойСклад
$bundleCache = $eventParams['bundleCache']; // [href компонента => количество] в ->components
$currentComponentsArray = $eventParams['currentComponentsArray']; // текущий состав набора
$bundlePartIblockId = $eventParams['bundlePartIblockId']; // инфоблоки для поиска компонентов
#WORK_AREA#
}
Поиск компонентов по своему свойству
Компоненты хранятся в каталоге не по внешнему коду МойСклад, а по UUID в свойстве MS_UUID:
function OnImportBundleHandler(\Bitrix\Main\Event $event)
{
$bundleCache = $event->getParameter('bundleCache');
$components = [];
foreach ($bundleCache->components as $href => $qty) {
$uuid = basename((string)$href);
$element = \CIBlockElement::GetList(
[],
['=PROPERTY_MS_UUID' => $uuid],
false,
['nTopCount' => 1],
['ID']
)->Fetch();
if (!$element) {
// не нашли хоть один компонент — набор не сохранится
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, [
'isAllComponentLoaded' => false,
'componentsArray' => [],
]);
}
$components[] = [
'ITEM_ID' => (int)$element['ID'],
'QUANTITY' => $qty,
'DISCOUNT_PERCENT' => 0,
'SORT' => 100,
];
}
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, [
'isAllComponentLoaded' => true,
'componentsArray' => $components,
]);
}