/
bitrix-dev
/
Starter-kit
Обзор
Документация
Войти
/
bitrix-dev
/
Starter-kit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
main
local/php_interface/init/Handlers/PropPriceHandler.php
205 строк
7 KB
Alexey Karizhenskiy
Первая сборка (из ранее используемого)
19 янв 2026, 21:00
19 янв 2026, 21:00
d843e36
Код
Авторство
О чём код?
<?php class PropPriceHandler { /** * Обработчик изменения цены товара * @param int $ID ID цены * @param array $arFields Поля цены */ public static function OnPriceUpdateHandler($ID, $arFields): void { if (empty($arFields["PRODUCT_ID"])) return; self::UpdateProductMinPrice($arFields["PRODUCT_ID"]); } /** * Обработчик изменения скидки * @param \Bitrix\Main\Event $event Событие изменения скидки */ public static function OnDiscountUpdateHandler(\Bitrix\Main\Event $event): void { // Удаляем существующий агент $existingAgent = \CAgent::GetList( array(), array( "NAME" => "\\PropPriceHandler::UpdateProductMinPriceAgent%" ) ); while ($agent = $existingAgent->Fetch()) { \CAgent::Delete($agent["ID"]); } // Регистрируем новый агент \CAgent::AddAgent( "\\PropPriceHandler::UpdateProductMinPriceAgent();", "", "N", 30, "", "Y", "", 100 ); } /** * Агент для обновления минимальной цены товара * @param int $lastElementId ID последнего обработанного элемента * @return string */ public static function UpdateProductMinPriceAgent($lastElementId = 0) { // Получаем все активные товары из каталога $arFilter = array( "IBLOCK_ID" => \MWI\Helper\Iblock::getIblockId('catalog'), "ACTIVE" => "Y", ">ID" => $lastElementId ); $rsElements = CIBlockElement::GetList( array("ID" => "ASC"), $arFilter, false, array("nPageSize" => 200), array("ID") ); $currentElementId = 0; while ($arElement = $rsElements->Fetch()) { self::UpdateProductMinPrice($arElement["ID"]); $currentElementId = $arElement["ID"]; } if ($rsElements->SelectedRowsCount() < 200) { $currentElementId = 0; } if ($currentElementId > 0) { return "\\PropPriceHandler::UpdateProductMinPriceAgent(" . $currentElementId . ");"; } } /** * Обновление: минимальной цены товара, максимальной скидки %, признак sale * @param int $productId ID товара */ private static function UpdateProductMinPrice($productId) { $minPrice = false; $isSale = false; $maxDiscount = 0; $maxDiscountPercent = 0; // Проверяем, является ли элемент торговым предложением $mxResult = CCatalogSku::GetProductInfo($productId); if ($mxResult) { // Если это предложение, получаем ID основного товара $productId = $mxResult['ID']; } // Получить ID ИБ $iBlockId = \CIBlockElement::GetIBlockByID($productId); // Получаем все торговые предложения товара $rsOffers = CCatalogSKU::getOffersList($productId); if (!empty($rsOffers[$productId])) { // Если есть предложения, находим минимальную цену среди них foreach ($rsOffers[$productId] as $offer) { $price = self::GetItemPrice($offer["ID"]); $basePrice = self::GetItemBasePrice($offer["ID"]); if ($minPrice === false || $price < $minPrice) { $minPrice = $price; } if ($basePrice > $price) { $isSale = true; $discount = $basePrice - $price; $discountPercent = round(($discount / $basePrice) * 100); if ($discountPercent > $maxDiscountPercent) { $maxDiscount = $discount; $maxDiscountPercent = $discountPercent; } } } } else { // Если нет предложений, берем цену самого товара $minPrice = self::GetItemPrice($productId); $basePrice = self::GetItemBasePrice($productId); if ($basePrice > $minPrice) { $isSale = true; $maxDiscount = $basePrice - $minPrice; $maxDiscountPercent = round(($maxDiscount / $basePrice) * 100); } } if ($minPrice !== false) { $propertyValues = array("PRICE" => $minPrice); // Проверяем, есть ли скидка if ($isSale) { // Получаем ID значения списка по XML_ID $property_enums = CIBlockPropertyEnum::GetList( array(), array( "IBLOCK_ID" => $iBlockId, "CODE" => "SALE", "XML_ID" => "Y" ) ); if ($enum_fields = $property_enums->GetNext()) { $propertyValues["SALE"] = $enum_fields["ID"]; } $propertyValues["DISCOUNT"] = $maxDiscount; $propertyValues["DISCOUNT_PERCENT"] = $maxDiscountPercent; } else { $propertyValues["SALE"] = false; $propertyValues["DISCOUNT"] = 0; $propertyValues["DISCOUNT_PERCENT"] = 0; } // Обновляем свойства CIBlockElement::SetPropertyValuesEx( $productId, $iBlockId, $propertyValues ); // Обновить фасетный индекс \Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex($iBlockId, $productId); } } /** * Получение цены товара с учетом скидок * @param int $productId ID товара * @return float|bool */ private static function GetItemPrice($productId): float|bool { $price = CCatalogProduct::GetOptimalPrice( $productId, 1, [2], // Все пользователи (в том числе неавторизованные) 'N', [] ); return $price["DISCOUNT_PRICE"] ?? false; } /** * Получение базовой цены товара без скидок * @param int $productId ID товара * @return float|bool */ private static function GetItemBasePrice($productId): float|bool { $price = CPrice::GetBasePrice($productId); return $price ? (float)$price['PRICE'] : false; } }