/
bitrix-dev
/
Starter-kit
Обзор
Документация
Войти
/
bitrix-dev
/
Starter-kit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
main
local/php_interface/init/Handlers/ProductHandler.php
346 строк
11 KB
Alexey Karizhenskiy
Первая сборка (из ранее используемого)
19 янв 2026, 21:00
19 янв 2026, 21:00
d843e36
Код
Авторство
О чём код?
<?php class ProductHandler { /** * Код свойства "Наличие на складах" (в городе) * @var string */ public static $propAvailabilityInCityCode = "AVAILABILITY_IN_CITY"; /** * Обработчик события после добавления товара * * @param \Bitrix\Main\Event $event * @return void */ public static function onProductAdd(\Bitrix\Main\Event $event) { /* $id = $event->getParameter("id"); $fields = $event->getParameter("fields"); if (!empty($id) && is_array($id) && !empty($id["ID"])) { $fields["ID"] = $id["ID"]; } if (empty($fields["ID"])) return; // Получить элемент по ID товара $arElement = \CIBlockElement::GetByID($fields["ID"])->GetNext(); if (empty($arElement)) return; */ } /** * Обработчик события после обновления товара * * @param \Bitrix\Main\Event $event * @return void */ public static function onProductUpdate(\Bitrix\Main\Event $event) { /* $id = $event->getParameter("id"); $fields = $event->getParameter("fields"); if (!empty($id) && is_array($id) && !empty($id["ID"])) { $fields["ID"] = $id["ID"]; } if (empty($fields["ID"])) return; // Получить элемент по ID товара $arElement = \CIBlockElement::GetByID($fields["ID"])->GetNext(); if (empty($arElement)) return; */ } /** * При обновлении остатков товаров, * обновить свойство у товара "Наличие на складах" (в городе) * @param $id * @param $arFields * @return void */ public static function storeProductUpdate($id, $arFields) { // Если изначально переданы не все данные, то запросить if (empty($arFields['PRODUCT_ID'])) { $rsStoreProduct = \CCatalogStoreProduct::GetList( [], ["ID" => $id], false, false, ['ID', 'PRODUCT_ID'] ); if ($arStoreProduct = $rsStoreProduct->Fetch()) { $arFields['PRODUCT_ID'] = $arStoreProduct['PRODUCT_ID']; } } if (empty($arFields['PRODUCT_ID'])) { return; } // Получить остатки по всем складам для товара $rsStoreProducts = \CCatalogStore::GetList( [], ['ACTIVE' => 'Y', 'PRODUCT_ID' => $arFields['PRODUCT_ID']], false, false, ['ID', 'PRODUCT_AMOUNT', 'UF_CITY'] ); $arStoreCityProducts = []; while ($arStoreProduct = $rsStoreProducts->Fetch()) { $cityName = $arStoreProduct['UF_CITY'] ? trim($arStoreProduct['UF_CITY']) : null; if (empty($cityName)) continue; if (!isset($arStoreCityProducts[$cityName])) { $arStoreCityProducts[$cityName] = 0; } $arStoreCityProducts[$cityName] += (float)$arStoreProduct['PRODUCT_AMOUNT']; } // Получить ID инфоблока $iBlockID = \CIBlockElement::GetIBlockByID($arFields['PRODUCT_ID']); if (!$iBlockID) { return; } // Получить все значения свойства $arEnumValues = self::getPropEnumValuesByCities(array_keys($arStoreCityProducts), $iBlockID); $arValues = []; // Получить ID значений свойства для записи в свойство элемента foreach ($arEnumValues as $cityName => $enumID) { if (!empty($arStoreCityProducts[$cityName]) && $arStoreCityProducts[$cityName] > 0) { $arValues[] = $enumID; } } // Получить текущие значения свойства элемента $arOldValues = []; $resProp = \CIBlockElement::GetProperty( $iBlockID, $arFields['PRODUCT_ID'], "sort", "asc", ["CODE" => self::$propAvailabilityInCityCode] ); while ($arPropValue = $resProp->GetNext()) { if (!empty($arPropValue['VALUE'])) { $arOldValues[] = $arPropValue['VALUE']; } } sort($arOldValues); sort($arValues); if ($arOldValues !== $arValues) { // Обновить свойство элемента \CIBlockElement::SetPropertyValuesEx( $arFields['PRODUCT_ID'], $iBlockID, [self::$propAvailabilityInCityCode => (!empty($arValues) ? $arValues : false)] ); // Обновить индекс \Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex( $iBlockID, $arFields['PRODUCT_ID'] ); // Если это товарное предложение, то запустить проверку у товара if ($iBlockID == \MWI\Helper\Iblock::getIblockId('catalog_offers')) { self::storeCheckProductByOffers($arFields['PRODUCT_ID']); } } } /** * При удалении остатка на складе имитируем изменение остатка * @param $id * @return void */ public static function storeProductDelete($id) { $rsStoreProduct = \CCatalogStoreProduct::GetList( [], [ "ID" => $id, ], false, false, array('STORE_ID', 'PRODUCT_ID', 'AMOUNT') ); if ($arStoreProduct = $rsStoreProduct->Fetch()) { $arFields = [ 'STORE_ID' => $arStoreProduct['STORE_ID'], 'PRODUCT_ID' => $arStoreProduct['PRODUCT_ID'], 'AMOUNT' => 0, ]; // Вызвать метод по обновлению свойства Наличие на складах self::storeProductUpdate($id, $arFields); } } /** * Проверить наличие товара по товарным предложениям * @param $offerID * @return void */ public static function storeCheckProductByOffers($offerID) { // По товарному предложению получить товар $arProductInfo = CCatalogSku::GetProductInfo($offerID); if (is_array($arProductInfo)) { $productID = $arProductInfo['ID']; $iBlockID = $arProductInfo['IBLOCK_ID']; } else { return; } $arProductsOffers = CCatalogSKU::getOffersList( [$productID], 0, ['ACTIVE' => 'Y'], ['ID'] ); if (empty($arProductsOffers[$productID])) { return; } $arOfferIDs = []; foreach ($arProductsOffers[$productID] as $arOffer) { $arOfferIDs[] = $arOffer['ID']; if (empty($iBlockID)) { $iBlockID = $arOffer['IBLOCK_ID']; } } if (empty($iBlockID) || empty($arOfferIDs)) { return; } // Получить остатки по всем складам для товарных предложений $rsStoreProducts = \CCatalogStore::GetList( [], ['ACTIVE' => 'Y', 'PRODUCT_ID' => $arOfferIDs], false, false, ['ID', 'PRODUCT_AMOUNT', 'UF_CITY'] ); $arStoreCityProducts = []; while ($arStoreProduct = $rsStoreProducts->Fetch()) { $cityName = $arStoreProduct['UF_CITY'] ? trim($arStoreProduct['UF_CITY']) : null; if (empty($cityName)) continue; if (!isset($arStoreCityProducts[$cityName])) { $arStoreCityProducts[$cityName] = 0; } $arStoreCityProducts[$cityName] += (float)$arStoreProduct['PRODUCT_AMOUNT']; } // Получить все значения свойства $arEnumValues = self::getPropEnumValuesByCities(array_keys($arStoreCityProducts), $iBlockID); $arValues = []; // Получить ID значений свойства для записи в свойство элемента foreach ($arEnumValues as $cityName => $enumID) { if (!empty($arStoreCityProducts[$cityName]) && $arStoreCityProducts[$cityName] > 0) { $arValues[] = $enumID; } } // Получить текущие значения свойства элемента $arOldValues = []; $resProp = \CIBlockElement::GetProperty( $iBlockID, $productID, "sort", "asc", ["CODE" => self::$propAvailabilityInCityCode] ); while ($arPropValue = $resProp->GetNext()) { if (!empty($arPropValue['VALUE'])) { $arOldValues[] = $arPropValue['VALUE']; } } sort($arOldValues); sort($arValues); if ($arOldValues !== $arValues) { // Обновить свойство элемента \CIBlockElement::SetPropertyValuesEx( $productID, $iBlockID, [self::$propAvailabilityInCityCode => (!empty($arValues) ? $arValues : false)] ); // Обновить индекс \Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex( $iBlockID, $productID ); } } /** * Получить ID значений свойства "Наличие на складах" (в городе) * @param array $arCities * @param int $iBlockID * @return array */ static function getPropEnumValuesByCities(array $arCities, int $iBlockID): array { $arCities = array_unique($arCities); // Получить ID свойства $arProperty = \CIBlockProperty::GetList([], ["IBLOCK_ID" => $iBlockID, "CODE" => self::$propAvailabilityInCityCode])->Fetch(); if (empty($arProperty["ID"])) { return []; } $propertyID = $arProperty["ID"]; // Получить все значения свойства $arEnumValues = []; $rsEnumValues = \CIBlockPropertyEnum::GetList( [], ["IBLOCK_ID" => $iBlockID, "PROPERTY_ID" => $propertyID] ); while ($arEnumValue = $rsEnumValues->Fetch()) { $arEnumValues[$arEnumValue['VALUE']] = $arEnumValue['ID']; } // Проверить и добавить новые значения свойства foreach ($arCities as $cityName) { if (empty($arEnumValues[$cityName])) { $arEnumFields = [ 'PROPERTY_ID' => $propertyID, 'VALUE' => $cityName, 'XML_ID' => \CUtil::translit($cityName, "ru"), ]; $enumResult = \CIBlockPropertyEnum::Add($arEnumFields); if ($enumResult) { $arEnumValues[$cityName] = $enumResult; } } } return $arEnumValues; } }