События перед записью поля "Доступное количество"
События позволяют менять поля товара после полного рассчета остатков для него. В модуле используется для смены поля QUANTITY у товара. Фактически результат события записывается в товар следующим методом:
\Bitrix\Catalog\Model\Product::update($productId, $arUpdateProductFields);
Оба события вызываются для каждого товара, даже если QUANTITY не изменился — тогда arUpdateProductFields приходит пустым массивом []. Если после обработчиков массив остался пустым, запись товара пропускается.
- Ответы обработчиков читаются по порядку, и последний ответ
EventResult::SUCCESSцеликом заменяет массив полей — поля не сливаются. ОтветыERRORигнорируются. - Всегда возвращайте полный массив полей.
SUCCESSбез параметров даётnull, и на PHP 8 запись товара падает с ошибкой. - Событие отправляется без перехвата исключений: исключение в обработчике прерывает текущий шаг импорта, и оставшиеся товары шага не обрабатываются. Ловите исключения внутри обработчика.
[OnBeforeUpdateProductInStockRow] Для вкладки "Остатки"
Это событие стоит применять если используете вкладку "Остатки".
- Описание события
- Пример вызова события
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
arUpdateProductFields | array | Поля товара для обновления: ['QUANTITY' => …], если количество изменилось, иначе [] |
productBx | int | ID товара в Битрикс |
currentStocks | array | Остатки на складах Битрикс ПОСЛЕ записи новых значений, ключи — ID склада |
productInfoStocks | array | Полный массив данных, влияющих на изменение остатков; BX_STOCKS в нём — остатки ДО изменения |
qtyByStocks | array | Рассчитанные количества по складам |
Возвращаемое значение
Верните EventResult::SUCCESS с модифицированным массивом $arUpdateProductFields. Этот массив заменит тот, что передаёт модуль в \Bitrix\Catalog\Model\Product::update().
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $arUpdateProductFields);
Ключи ALL, ALL_MS, ALL_BX и ID складов присутствуют в зависимости от настроек синхронизации. qtyByStocks содержит рассчитанные значения, одно из которых выбирается для записи в QUANTITY.
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnBeforeUpdateProductInStockRow',
'OnBeforeUpdateProductInStockRowHandler'
);
function OnBeforeUpdateProductInStockRowHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
// $arUpdateProductFields — поля товара, можно изменять любые поля,
// но модуль здесь передает только рассчитанное доступное количество
// [
// 'QUANTITY' => 15.0 // рассчитанное доступное количество
// ]
// Если QUANTITY не изменился, приходит пустой массив [] — событие всё равно вызывается
$arUpdateProductFields = $eventParams['arUpdateProductFields'];
$productId = $eventParams['productBx']; //передается ID товара
// $currentStocks — остатки на складах Битрикс ПОСЛЕ записи новых значений,
// ключи массива — это ID склада
// [
// 1 => [ // ID склада Битрикс, запись уже была: AMOUNT — новое значение
// 'ID' => 456,
// 'PRODUCT_ID' => 1234,
// 'STORE_ID' => 1,
// 'AMOUNT' => 8.0
// ],
// 2 => [ // склад, по которому записи не было: только новое AMOUNT, без ID/PRODUCT_ID/STORE_ID
// 'AMOUNT' => 7.0
// ],
// // ... другие склады
// ]
$currentStocks = $eventParams['currentStocks'];
// $productInfoStocks — полный массив данных которые влияют на изменения остатков
// [
// 'MS_STOCKS' => [
// 'msStoreUUID1' => [ // UUID склада в МойСклад
// 's' => 10.0, // остаток (stock)
// 'q' => 8.0, // доступно: stock + inTransit - reserve
// 't' => 8.0, // stock - reserve
// ],
// 'msStoreUUID2' => [
// 's' => 5.0,
// 'q' => 7.0,
// 't' => 5.0,
// ],
// 'all' => [ // суммы по всем складам МС, те же ключи
// 's' => 15.0,
// 'q' => 15.0,
// 't' => 13.0,
// ]
// ],
// 'BX_QUANTITY' => 12.0, // поле "доступное количество" ДО изменения
// 'BX_STOCKS' => [ // остатки на складах Битрикс ДО изменения
// 1 => ['ID' => 456, 'PRODUCT_ID' => 1234, 'STORE_ID' => 1, 'AMOUNT' => 10.0],
// ]
// ]
// Какой ключ MS_STOCKS берётся в расчёт, задаёт настройка "Тип импорта остатков на складах":
// [A] Доступное количество — 'q', [S] Остатки на складах — 's', [T] Доступное количество на складе — 't'
$productInfoStocks = $eventParams['productInfoStocks'];
// $qtyByStocks — рассчитанные количества по складам
// [
// 'ALL' => 15.0, // сумма по всем сопоставленным складам
// 'ALL_MS' => 15.0, // сумма из МС по всем складам (поле 'all')
// 'ALL_BX' => 15.0, // сумма по всем складам Битрикс (когда выбрана эта опция)
// 1 => 10.0, // количество для склада Битрикс с ID=1
// 2 => 5.0, // количество для склада Битрикс с ID=2
// ]
$qtyByStocks = $eventParams['qtyByStocks'];
$msStocks = $productInfoStocks['MS_STOCKS']; //актуальные остатки из МС
$bxQuantity = $productInfoStocks['BX_QUANTITY']; //поле "доступное количество" ДО изменения
$bxStocks = $productInfoStocks['BX_STOCKS']; //остатки на складах Битрикс ДО изменения (в $currentStocks — уже ПОСЛЕ)
//возвращаем SUCCESS с полным массивом полей: он целиком заменит то, что модуль передает в товар
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $arUpdateProductFields);
}
OnBeforeUpdateProductInStockRow также вызывается устаревшим ImportStocksClass::updateRow — только если ваш код сам зовёт устаревшие публичные методы Rbs\MoyskladStocks\Import\Type\Stocks::updateRow() или Stocks::updateAll(); штатный импорт модуля этот путь не использует. В этом вызове другой набор параметров:
productBx— массив['ID' => …, 'QUANTITY' => …], а неint;currentStocks— нумерованный список записейStoreProductTableпо сопоставленным складам, а в режимеALL_BX— все записи складов товара;- параметров
productInfoStocksиqtyByStocksнет.
Если обработчик должен работать в обоих случаях, проверяйте тип productBx.
[OnBeforeUpdateProductInCurrentStockRow] для вкладки "Быстрые остатки"
Событие полностью аналогично событию выше, но работает при передаче быстрых остатков.
- Описание события
- Пример вызова события
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
arUpdateProductFields | array | Поля товара для обновления: ['QUANTITY' => …], если количество изменилось, иначе [] |
productBx | int | ID товара в Битрикс |
currentStocks | array | Остатки на складах Битрикс ПОСЛЕ записи новых значений, ключи — ID склада |
productInfoStocks | array | Полный массив данных, влияющих на изменение остатков; BX_STOCKS в нём — остатки ДО изменения |
В данном событии не передаётся параметр qtyByStocks. BX_QUANTITY и BX_STOCKS в productInfoStocks устроены так же, а MS_STOCKS — иначе: [UUID склада МС => [<тип> => значение], 'all_stocks' => [<тип> => сумма]], где <тип> — stock или quantity по настройке «Тип импорта остатков» вкладки.
Возвращаемое значение
Верните EventResult::SUCCESS с модифицированным массивом $arUpdateProductFields.
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $arUpdateProductFields);
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnBeforeUpdateProductInCurrentStockRow',
'OnBeforeUpdateProductInCurrentStockRowHandler'
);
function OnBeforeUpdateProductInCurrentStockRowHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
// $arUpdateProductFields — поля товара, можно изменять любые поля,
// но модуль здесь передает только рассчитанное доступное количество
// [
// 'QUANTITY' => 15.0 // рассчитанное доступное количество
// ]
// Если QUANTITY не изменился, приходит пустой массив [] — событие всё равно вызывается
$arUpdateProductFields = $eventParams['arUpdateProductFields'];
$productId = $eventParams['productBx']; //передается ID товара
// $currentStocks — остатки на складах Битрикс ПОСЛЕ записи новых значений,
// ключи массива — это ID склада
// [
// 1 => [ // ID склада Битрикс, запись уже была: AMOUNT — новое значение
// 'ID' => 456,
// 'PRODUCT_ID' => 1234,
// 'STORE_ID' => 1,
// 'AMOUNT' => 8.0
// ],
// 2 => [ // склад, по которому записи не было: только новое AMOUNT, без ID/PRODUCT_ID/STORE_ID
// 'AMOUNT' => 7.0
// ],
// // ... другие склады
// ]
$currentStocks = $eventParams['currentStocks'];
// $productInfoStocks — полный массив данных которые влияют на изменения остатков
// [
// 'MS_STOCKS' => [
// 'msStoreUUID1' => [ // UUID склада в МойСклад
// 'quantity' => 8.0, // ключ — выбранный тип остатков: 'quantity' или 'stock'
// ],
// 'msStoreUUID2' => [
// 'quantity' => 7.0,
// ],
// 'all_stocks' => [ // сумма по всем складам МС
// 'quantity' => 15.0,
// ]
// ],
// 'BX_QUANTITY' => 12.0, // поле "доступное количество" ДО изменения
// 'BX_STOCKS' => [ // остатки на складах Битрикс ДО изменения
// 1 => ['ID' => 456, 'PRODUCT_ID' => 1234, 'STORE_ID' => 1, 'AMOUNT' => 10.0],
// ]
// ]
$productInfoStocks = $eventParams['productInfoStocks'];
$msStocks = $productInfoStocks['MS_STOCKS']; //актуальные остатки из МС
$bxQuantity = $productInfoStocks['BX_QUANTITY']; //поле "доступное количество" ДО изменения
$bxStocks = $productInfoStocks['BX_STOCKS']; //остатки на складах Битрикс ДО изменения (в $currentStocks — уже ПОСЛЕ)
//возвращаем SUCCESS с полным массивом полей: он целиком заменит то, что модуль передает в товар
return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $arUpdateProductFields);
}