линия

Главная

воскресенье, 21 августа 2016 г.

Bitrix,сортировка товаров по цене торговых предложений.

Рано или поздно, ты столкнешься с  такой проблемой: нужно отсортировать товары по цене. Казалось что может быть проще... Но нет,  цены на товар представлены в виде торговых предложений. Тут приведен один из способов решения данной задачи.

1. Создаем  новые свойства товара:



2. Заполняем свойства.
Создаем тестовую страницу, кидаем туда скрипт, который заполняет выше созданные свойства товара.

CModule::IncludeModule('iblock');
CModule::IncludeModule('catalog');
// ID инфоблока  товаров
$ID_BLOCK = 6;

$arSelect = Array("ID", "NAME", "DATE_ACTIVE_FROM");
$arFilter = Array("IBLOCK_ID"=>$ID_BLOCK,"ACTIVE"=>"Y");
$res = CIBlockElement::GetList(
                  Array('ID',"NAME"), 
      $arFilter, false, 
      Array("nPageSize"=>5000), 
      $arSelect);

while($ob = $res->GetNextElement()){
   $arFields = $ob->GetFields();
   $MIN_PRICE  = get_offer_min_price($ID_BLOCK,$arFields['ID']);
   $MAX_PRICE  = get_offer_max_price($ID_BLOCK,$arFields['ID']);
   //echo $arFields['ID'].' min= '.$MIN_PRICE.' max='.$MAX_PRICE.' - '.$arFields['NAME'];echo '
';
   //Обновляем свойства товара
   CIBlockElement::SetPropertyValuesEx($arFields['ID'], false, array('MINIMUM_PRICE' => $MIN_PRICE));
   CIBlockElement::SetPropertyValuesEx($arFields['ID'], false, array('MAXIMUM_PRICE' => $MAX_PRICE));
}

//-------------------------------
/*
Возвращает минимальную цену товара из тп
*/
function get_offer_min_price($IBLOCK_ID,$item_id){
    $ret = 0;
    $arInfo = CCatalogSKU::GetInfoByProductIBlock($IBLOCK_ID);   
    if (is_array($arInfo)) {
        $res = CIBlockElement::GetList(Array("PRICE"=>"asc"), 
                                       array('IBLOCK_ID'=>$arInfo['IBLOCK_ID'], 'ACTIVE'=>'Y', 'PROPERTY_'.$arInfo['SKU_PROPERTY_ID'] => $item_id), 
                                       false, 
                                       false, 
                                       array('ID', 'NAME'))->GetNext();
        if ($res){
            $ret = GetCatalogProductPrice($res["ID"], 1);
            if ($ret['PRICE']){
                $ret = $ret['PRICE'];
            }
        }
    }
    return $ret;
}
/*
Возвращает максимальную цену товара из тп
*/
function get_offer_max_price($IBLOCK_ID,$item_id){
    $ret = 0;
    $arInfo = CCatalogSKU::GetInfoByProductIBlock($IBLOCK_ID);   
    if (is_array($arInfo)) {
        $res = CIBlockElement::GetList(Array("PRICE"=>"desc"), 
                                       array('IBLOCK_ID'=>$arInfo['IBLOCK_ID'], 'ACTIVE'=>'Y', 'PROPERTY_'.$arInfo['SKU_PROPERTY_ID'] => $item_id), 
                                       false, 
                                       false, 
                                       array('ID', 'NAME'))->GetNext();
        if ($res){
            $ret = GetCatalogProductPrice($res["ID"], 1);
            if ($ret['PRICE']){
                $ret = $ret['PRICE'];
            }
        }
    }
    return $ret;
}


Запускаем скрипт, проверяем. Видим что свойства заполнены.

3.  Теперь редактируем страницу вывода каталога.
"ELEMENT_SORT_FIELD" => "PROPERTY_MINIMUM_PRICE",
"ELEMENT_SORT_ORDER" => "ASC"


4. Запускать каждый раз скрипт неудобно. Надо чтобы при добавлении или редактировании товара автоматически обновлялись свойства  товара. Для чего  редактируем файл /bitrix/php_interface/init.php

AddEventHandler("iblock", "OnAfterIBlockElementUpdate",  Array("MyElement", "OnBeforeIBlockElementUpdateHandler"));
AddEventHandler("iblock", "OnAfterIBlockElementAdd", Array("MyElement", "OnAfterIBlockElementAddHandler"));
class MyElement
{
    function OnAfterIBlockElementAddHandler(&$arFields){
        if($arFields["ID"]>0){
       $ID_BLOCK = 6;
       $MIN_PRICE  = get_offer_min_price($ID_BLOCK,$arFields['ID']);
                $MAX_PRICE  = get_offer_max_price($ID_BLOCK,$arFields['ID']);
      //Обновляем свойства товара
               CIBlockElement::SetPropertyValuesEx($arFields['ID'], $ID_BLOCK, array('MINIMUM_PRICE' => $MIN_PRICE));
               CIBlockElement::SetPropertyValuesEx($arFields['ID'], $ID_BLOCK, array('MAXIMUM_PRICE' => $MAX_PRICE));
  }

    }
 function OnBeforeIBlockElementUpdateHandler(&$arFields){    
              $ID_BLOCK = 6;
                 $MIN_PRICE  = get_offer_min_price($ID_BLOCK,$arFields['ID']);
                $MAX_PRICE  = get_offer_max_price($ID_BLOCK,$arFields['ID']);
      //Обновляем свойства товара
    //  global $APPLICATION;
               //$APPLICATION->throwException("Введите символьный код. (ID:".$arFields['ID'].' MAX_PRICE='.$MAX_PRICE.")");
               
               CIBlockElement::SetPropertyValuesEx($arFields['ID'], $ID_BLOCK, array('MINIMUM_PRICE' => $MIN_PRICE));
               CIBlockElement::SetPropertyValuesEx($arFields['ID'], $ID_BLOCK, array('MAXIMUM_PRICE' => $MAX_PRICE));
      //return false;
}

}

И все. Теперь сортировка работает. Пьем чай, наслаждаемся жизнью.


1 комментарий:

  1. Не будет работать если добавить торговое предложение или поменять у торгового предложения цену

    ОтветитьУдалить