Для успешного интернет-магазина критически важно поддерживать актуальную информацию о ценах. В этой статье мы рассмотрим решение для автоматического обновления свойства с минимальной ценой товара при его добавлении или изменении в системе 1С-Битрикс.
Как работает механизм обновления цен
Основа решения - обработчик событий, который реагирует на изменения в каталоге:
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "BXIBlockAfterSave");
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "BXIBlockAfterSave");
AddEventHandler("catalog", "OnPriceAdd", "BXIBlockAfterSave");
AddEventHandler("catalog", "OnPriceUpdate", "BXIBlockAfterSave");
Функция BXIBlockAfterSave выполняет несколько ключевых задач:
-
Определяет тип элемента (основной товар или торговое предложение)
-
Находит все связанные товары и предложения
-
Вычисляет минимальную и максимальную цену
-
Сохраняет минимальную цену в специальное свойство элемента
Особенности работы с торговыми предложениями
Система корректно обрабатывает три типа товаров:
-
Торговые предложения - определяет основной товар и обновляет его цену
-
Товары с предложениями - находит все предложения и вычисляет минимальную цену
-
Обычные товары - просто обновляет цену для элемента
Техническая реализация
Основные этапы обработки:
// Получение информации о каталоге
$arCatalog = CCatalog::GetByID($arPriceElement["IBLOCK_ID"]);
// Поиск торговых предложений
$rsOffers = CIBlockElement::GetList(
array(),
array(
"IBLOCK_ID" => $OFFERS_IBLOCK_ID,
"PROPERTY_" . $OFFERS_PROPERTY_ID => $ELEMENT_ID,
),
false,
false,
array("ID")
);
// Расчет минимальной цены
while ($arPrice = $rsPrices->Fetch()) {
$PRICE = $arPrice["PRICE"];
if ($minPrice === false || $minPrice > $PRICE)
$minPrice = $PRICE;
}
// Сохранение результата
CIBlockElement::SetPropertyValues($ELEMENT_ID, $IBLOCK_ID, $minPrice, "MINIMUM_PRICE");
Как это работает?
-
Отслеживание изменений
-
Добавление/редактирование товара
-
Изменение цен
-
-
Определение типа товара
-
Обычный товар
-
Товар с торговыми предложениями
-
Само торговое предложение
-
-
Расчет минимальной цены
-
Сбор всех цен (включая предложения)
-
Поиск минимального значения
-
-
Сохранение в свойство MINIMUM_PRICE
Как внедрить?
-
Добавьте свойство "MINIMUM_PRICE" в инфоблок каталога
-
Поместите код в
/bitrix/php_interface/init.php -
Проверьте работу – измените цену товара и убедитесь, что свойство обновляется
Полный код решения
<?php
// Регистрируем обработчики событий
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "BXIBlockAfterSave");
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "BXIBlockAfterSave");
AddEventHandler("catalog", "OnPriceAdd", "BXIBlockAfterSave");
AddEventHandler("catalog", "OnPriceUpdate", "BXIBlockAfterSave");
function BXIBlockAfterSave($arg1, $arg2 = false) {
$ELEMENT_ID = false;
$IBLOCK_ID = false;
$OFFERS_IBLOCK_ID = false;
$OFFERS_PROPERTY_ID = false;
// Обработка событий из каталога
if (is_array($arg2) && $arg2["PRODUCT_ID"] > 0) {
$rsPriceElement = CIBlockElement::GetList(
array(),
array("ID" => $arg2["PRODUCT_ID"]),
false,
false,
array("ID", "IBLOCK_ID")
);
if ($arPriceElement = $rsPriceElement->Fetch()) {
$arCatalog = CCatalog::GetByID($arPriceElement["IBLOCK_ID"]);
if (is_array($arCatalog)) {
if ($arCatalog["OFFERS"] == "Y") {
$rsElement = CIBlockElement::GetProperty(
$arPriceElement["IBLOCK_ID"],
$arPriceElement["ID"],
"sort",
"asc",
array("ID" => $arCatalog["SKU_PROPERTY_ID"])
);
$arElement = $rsElement->Fetch();
if ($arElement && $arElement["VALUE"] > 0) {
$ELEMENT_ID = $arElement["VALUE"];
$IBLOCK_ID = $arCatalog["PRODUCT_IBLOCK_ID"];
$OFFERS_IBLOCK_ID = $arCatalog["IBLOCK_ID"];
$OFFERS_PROPERTY_ID = $arCatalog["SKU_PROPERTY_ID"];
}
} elseif ($arCatalog["OFFERS_IBLOCK_ID"] > 0) {
$ELEMENT_ID = $arPriceElement["ID"];
$IBLOCK_ID = $arPriceElement["IBLOCK_ID"];
$OFFERS_IBLOCK_ID = $arCatalog["OFFERS_IBLOCK_ID"];
$OFFERS_PROPERTY_ID = $arCatalog["OFFERS_PROPERTY_ID"];
} else {
$ELEMENT_ID = $arPriceElement["ID"];
$IBLOCK_ID = $arPriceElement["IBLOCK_ID"];
}
}
}
} elseif (is_array($arg1) && $arg1["ID"] > 0 && $arg1["IBLOCK_ID"] > 0) {
$arOffers = CIBlockPriceTools::GetOffersIBlock($arg1["IBLOCK_ID"]);
if (is_array($arOffers)) {
$ELEMENT_ID = $arg1["ID"];
$IBLOCK_ID = $arg1["IBLOCK_ID"];
$OFFERS_IBLOCK_ID = $arOffers["OFFERS_IBLOCK_ID"];
$OFFERS_PROPERTY_ID = $arOffers["OFFERS_PROPERTY_ID"];
}
}
if ($ELEMENT_ID) {
static $arPropCache = array();
if (!array_key_exists($IBLOCK_ID, $arPropCache)) {
$rsProperty = CIBlockProperty::GetByID("MINIMUM_PRICE", $IBLOCK_ID);
$arProperty = $rsProperty->Fetch();
$arPropCache[$IBLOCK_ID] = $arProperty ? $arProperty["ID"] : false;
}
if ($arPropCache[$IBLOCK_ID]) {
$arProductID = array($ELEMENT_ID);
if ($OFFERS_IBLOCK_ID) {
$rsOffers = CIBlockElement::GetList(
array(),
array(
"IBLOCK_ID" => $OFFERS_IBLOCK_ID,
"PROPERTY_" . $OFFERS_PROPERTY_ID => $ELEMENT_ID,
),
false,
false,
array("ID")
);
while ($arOffer = $rsOffers->Fetch()) {
$arProductID[] = $arOffer["ID"];
}
}
$minPrice = false;
$rsPrices = CPrice::GetList(
array(),
array("BASE" => "Y", "PRODUCT_ID" => $arProductID)
);
while ($arPrice = $rsPrices->Fetch()) {
$PRICE = $arPrice["PRICE"];
if ($minPrice === false || $minPrice > $PRICE) {
$minPrice = $PRICE;
}
}
if ($minPrice !== false) {
CIBlockElement::SetPropertyValues($ELEMENT_ID, $IBLOCK_ID, $minPrice, "MINIMUM_PRICE");
}
}
}
}
?>
Преимущества решения
-
Автоматизация - исключает ручное обновление цен
-
Гибкость - работает с разными типами товаров
-
Производительность - использует кеширование свойств
-
Интеграция - легко внедряется в существующие проекты
Заключение
Представленное решение значительно упрощает управление ценами в интернет-магазине на 1С-Битрикс, обеспечивая актуальность информации для покупателей. Автоматическое обновление минимальной цены улучшает пользовательский опыт и способствует увеличению конверсии.
Для реализации этого механизма в вашем проекте достаточно разместить код в файле init.php или другом подходящем месте вашей битрикс-инсталляции.