Сортировка по цене в catalog.section

Недавно понадобилось сделать сортировку по цене в компоненте catalog.section. Изучив интернет я понял, что сделать малой кровью не получится, как вариант переписывать компонент. И тут помощь пришла откуда её не ждали...

Автор . Дата: 21.02.2015

При инициализации комплексного компонента catalog можно задать 2 поля, по которым будет идти сортировка. Можно и отсортировать по цене. Но проблема возникла в том, что часть товаров у нас с торговыми предложениями, часть без. А сортироваться может только по цене товара, в торговые предложения он не заглядывает. Но можно сделать сортировку по какому-нибудь свойству.

Идем в инфоблок основного каталога и добавляем новое свойство. Выбираем ему название (я назвал Минимальная цена), тип Число, кодовое имя MIN_PRICE. Вот по этому свойству мы и будем сортировать.

Дальше я написал простенькую функцию, которая заполняет это поле для всех товаров. Принцип работы её очень простой: проходимся по всем товарам, если они имеют торговое предложение, то берем первое торговое предложение и его цену, и заполняем это свойство у основного товара. Иначе просто берем цену у товара и заполняем это свойство.

function RecalculateMinPrice()
{
    global $DB;
    
    $arSelect = array(
        "ID",
        "IBLOCK_ID",
        "CODE",
        "XML_ID",
        "NAME",
        "ACTIVE",
        "DATE_ACTIVE_FROM",
        "DATE_ACTIVE_TO",
        "SORT",
        "PREVIEW_TEXT",
        "PREVIEW_TEXT_TYPE",
        "DETAIL_TEXT",
        "DETAIL_TEXT_TYPE",
        "DATE_CREATE",
        "CREATED_BY",
        "TIMESTAMP_X",
        "MODIFIED_BY",
        "TAGS",
        "IBLOCK_SECTION_ID",
        "DETAIL_PAGE_URL",
        "DETAIL_PICTURE",
        "PREVIEW_PICTURE",
        "PROPERTY_*"
    );
    
    $rsElements = CIBlockElement::GetList(array(), array('IBLOCK_ID' => 10), false, false, $arSelect);

    while ($arItem = $rsElements->GetNext())
    {
        if (CCatalogSKU::IsExistOffers($arItem['ID']))
        {
            $arElID = intval($arItem['ID']);
            $arSkuInfo = CCatalogSKU::GetInfoByProductIBlock($arItem['IBLOCK_ID']);

            $rsOffers = CIBlockElement::GetList(
                array(),
                array('IBLOCK_ID' => $arSkuInfo['IBLOCK_ID'], '=PROPERTY_'.$arSkuInfo['SKU_PROPERTY_ID'] => $arElID, 'ACTIVE' => 'Y'),
                false,
                false,
                array('ID', 'NAME')
            );
            
            $minPrice = 0;

            if ($arOffer = $rsOffers->Fetch())
            {
                $rsPrice = CPrice::GetList(
                    array(),
                    array('PRODUCT_ID' => intval($arOffer['ID']), 'CATALOG_GROUP_ID' => 1),
                    false,
                    array('nTopCount' => 1),
                    array('ID', 'PRICE')
                );
                
                if ($arPrice = $rsPrice->Fetch())
                {
                    $minPrice = $arPrice['PRICE'];
                }
            }

            CIBlockElement::SetPropertyValuesEx($arElID, 10, array('MIN_PRICE' => $minPrice), array());
        }
        else
        {
            $minPrice = 0;
            
            $rsPrice = CPrice::GetList(
                array(),
                array('PRODUCT_ID' => $arItem['ID'], 'CATALOG_GROUP_ID' => 1),
                false,
                array('nTopCount' => 1),
                array('ID', 'PRICE')
            );
            
            if ($arPrice = $rsPrice->Fetch())
            {
                $minPrice = $arPrice['PRICE'];
            }
   
            CIBlockElement::SetPropertyValuesEx($arItem['ID'], 10, array('MIN_PRICE' => $minPrice), array());
        }
    }
}

Я вызываю эту функцию после каждой выгрузки товаров из 1С:

AddEventHandler("iblock", "OnSuccessDiscountsImport1C", "OnSuccessDiscountsImport1CHandler");
function OnSuccessDiscountsImport1CHandler($arEvent)
{
    RecalculateMinPrice(); // перерасчитываем минимальную цену
}

Теперь можно спокойно сортировать товары по этому полю, и у нас всегда будут актуальные цены.


comments powered by HyperComments