Сортировка по цене в каталоге с торговыми предложениями

Сортировка по цене в каталоге с торговыми предложениями

840
17.10.2014

Столкнулся тут с проблемкой: как отсортировать все товары по цене, если каталог имеет торговые предложени?

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

Доброго времени суток. 

Столкнулся тут с проблемой: как отсортировать все товары по цене, если каталог имеет торговые предложения? 

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

Выход из данной проблемы был в 12-й версии продукта, в решении eshop. Сейчас почему-то убрали, возможно разработчики знают, почему, но особо времени разбираться нет, поэтому на одном из старых проектов нашел код, решающий данную задачу. 

Итак, привожу просто код файла init.php. Те, кто в теме - поймут, кто не в теме - обратитесь лучше к тем, кто в теме :)

AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "DoIBlockAfterSave");
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "DoIBlockAfterSave");
AddEventHandler("catalog", "OnPriceAdd", "DoIBlockAfterSave");
AddEventHandler("catalog", "OnPriceUpdate", "DoIBlockAfterSave");
function DoIBlockAfterSave($arg1, $arg2 = false)
{
 $ELEMENT_ID = false;
 $IBLOCK_ID = false;
 $OFFERS_IBLOCK_ID = false;
 $OFFERS_PROPERTY_ID = false;
 if (CModule::IncludeModule('currency'))
 $strDefaultCurrency = CCurrency::GetBaseCurrency();

 //Check for catalog event
 if(is_array($arg2) && $arg2["PRODUCT_ID"] > 0)
 {
 //Get iblock element
 $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))
 {
 //Check if it is offers iblock
 if($arCatalog["OFFERS"] == "Y")
 {
 //Find product element
 $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"];
 }
 }
 //or iblock which has offers
 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"];
 }
 //or it's regular catalog
 else
 {
 $ELEMENT_ID = $arPriceElement["ID"];
 $IBLOCK_ID = $arPriceElement["IBLOCK_ID"];
 $OFFERS_IBLOCK_ID = false;
 $OFFERS_PROPERTY_ID = false;
 }
 }
 }
 }
 //Check for iblock event
 elseif(is_array($arg1) && $arg1["ID"] > 0 && $arg1["IBLOCK_ID"] > 0)
 {
 //Check if iblock has offers
 $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))
 {
 //Check for MINIMAL_PRICE property
 $rsProperty = CIBlockProperty::GetByID("MINIMUM_PRICE", $IBLOCK_ID);
 $arProperty = $rsProperty->Fetch();
 if($arProperty)
 $arPropCache[$IBLOCK_ID] = $arProperty["ID"];
 else
 $arPropCache[$IBLOCK_ID] = false;
 }

 if($arPropCache[$IBLOCK_ID])
 {
 //Compose elements filter
 if($OFFERS_IBLOCK_ID)
 {
 $rsOffers = CIBlockElement::GetList(
 array(),
 array(
 "ACTIVE"=>"Y",
 "IBLOCK_ID" => $OFFERS_IBLOCK_ID,
 "PROPERTY_".$OFFERS_PROPERTY_ID => $ELEMENT_ID,
 ),
 false,
 false,
 array("ID")
 );
 while($arOffer = $rsOffers->Fetch())
 $arProductID[] = $arOffer["ID"];

 if (!is_array($arProductID) || empty($arProductID))
 $arProductID = array($ELEMENT_ID);
 }
 else
 $arProductID = array($ELEMENT_ID);

 $minPrice = false;
 $maxPrice = false;
 //Get prices
 $rsPrices = CPrice::GetList(
 array(),
 array(
 "PRODUCT_ID" => $arProductID,
 )
 );
 while($arPrice = $rsPrices->Fetch())
 {
 if (CModule::IncludeModule('currency') && $strDefaultCurrency != $arPrice['CURRENCY'])
 $arPrice["PRICE"] = CCurrencyRates::ConvertCurrency($arPrice["PRICE"], $arPrice["CURRENCY"], $strDefaultCurrency);

 $PRICE = $arPrice["PRICE"];

 if($minPrice === false || $minPrice > $PRICE)
 $minPrice = $PRICE;

 if($maxPrice === false || $maxPrice < $PRICE)
 $maxPrice = $PRICE;
 }

 //Save found minimal price into property
 if($minPrice !== false)
 {
 CIBlockElement::SetPropertyValuesEx(
 $ELEMENT_ID,
 $IBLOCK_ID,
 array(
 "MINIMUM_PRICE" => $minPrice,
 "MAXIMUM_PRICE" => $maxPrice,
 )
 );
 }
 }
 }
}

не забудьте в каталоге добавить числовое свойство (или добавить функцию-проверку наличия такого свойства и в случае отсутствия - создание такового):

MINIMUM_PRICE

и

MAXIMUM_PRICE

Источник: http://dev.1c-bitrix.ru/community/webdev/user/60622/blog/11900/


Благодарю за внимание! Делитесь вашими замечаниями в комментариях ниже.


P.S. Обращайтесь ко мне за приобретением лицензий и продлений на 1C-Битрикс "Управление сайтом", лицензий на облачную и коробочную версии Битрикс 24 а также за приобретением и внедрением готовых решений на базе 1С-Битрикс от партнеров. За более подробной информацией свяжитесь со мной любым удобным для вас способом


Комментарии

Еще никто не комментировал данную публикацию. Будьте первыми!

Добавить комментарий

captcha

Возврат к списку