Назад

Обновление свойства с минимальной ценой товара при добавлении или изменении товара

Главная
Блог
Обновление свойства с минимальной ценой товара при добавлении или изменении товара

Для успешного интернет-магазина критически важно поддерживать актуальную информацию о ценах. В этой статье мы рассмотрим решение для автоматического обновления свойства с минимальной ценой товара при его добавлении или изменении в системе 1С-Битрикс.

Как работает механизм обновления цен

Основа решения - обработчик событий, который реагирует на изменения в каталоге:

AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "BXIBlockAfterSave");
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "BXIBlockAfterSave");
AddEventHandler("catalog", "OnPriceAdd", "BXIBlockAfterSave");
AddEventHandler("catalog", "OnPriceUpdate", "BXIBlockAfterSave");

Функция BXIBlockAfterSave выполняет несколько ключевых задач:

  1. Определяет тип элемента (основной товар или торговое предложение)

  2. Находит все связанные товары и предложения

  3. Вычисляет минимальную и максимальную цену

  4. Сохраняет минимальную цену в специальное свойство элемента

Особенности работы с торговыми предложениями

Система корректно обрабатывает три типа товаров:

  1. Торговые предложения - определяет основной товар и обновляет его цену

  2. Товары с предложениями - находит все предложения и вычисляет минимальную цену

  3. Обычные товары - просто обновляет цену для элемента

Техническая реализация

Основные этапы обработки:

// Получение информации о каталоге
$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");

Как это работает?

  1. Отслеживание изменений

    • Добавление/редактирование товара

    • Изменение цен

  2. Определение типа товара

    • Обычный товар

    • Товар с торговыми предложениями

    • Само торговое предложение

  3. Расчет минимальной цены

    • Сбор всех цен (включая предложения)

    • Поиск минимального значения

  4. Сохранение в свойство MINIMUM_PRICE

Как внедрить?

  1. Добавьте свойство "MINIMUM_PRICE" в инфоблок каталога

  2. Поместите код в /bitrix/php_interface/init.php

  3. Проверьте работу – измените цену товара и убедитесь, что свойство обновляется

Полный код решения


<?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. Автоматизация - исключает ручное обновление цен

  2. Гибкость - работает с разными типами товаров

  3. Производительность - использует кеширование свойств

  4. Интеграция - легко внедряется в существующие проекты

Заключение

Представленное решение значительно упрощает управление ценами в интернет-магазине на 1С-Битрикс, обеспечивая актуальность информации для покупателей. Автоматическое обновление минимальной цены улучшает пользовательский опыт и способствует увеличению конверсии.

Для реализации этого механизма в вашем проекте достаточно разместить код в файле init.php или другом подходящем месте вашей битрикс-инсталляции.

Нужен надежный исполнитель?
Разрабатываем сайты, выполняем миграцию на Битрикс, дорабатываем функционал, сопровождаем проекты, а также занимаемся поисковым продвижением и комплексным маркетингом
Получить консультацию
Читайте по теме
Все статьи
Нужен надежный исполнитель?
Разрабатываем сайты, выполняем миграцию на Битрикс, дорабатываем функционал, сопровождаем проекты, а также занимаемся поисковым продвижением и комплексным маркетингом
Получить консультацию
Все статьи