Столкнулся тут с проблемкой: как отсортировать все товары по цене, если каталог имеет торговые предложени?
При этом проблема даже не с решением того, как это реализовать, а с логикой: по какому полю сортировать? у товара может быть много торговых предложений, каждое со своей ценой ...
Доброго времени суток.
Столкнулся тут с проблемой: как отсортировать все товары по цене, если каталог имеет торговые предложения?
При этом проблема даже не с решением того, как это реализовать, а с логикой: по какому полю сортировать? у товара может быть много торговых предложений, каждое со своей ценой ...
Выход из данной проблемы был в 12-й версии продукта, в решении eshop. Сейчас почему-то убрали, возможно разработчики знают, почему, но особо времени разбираться нет, поэтому на одном из старых проектов нашел код, решающий данную задачу.
Итак, привожу просто код файла init.php. Те, кто в теме - поймут, кто не в теме - обратитесь лучше к тем, кто в теме
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "BXIBlockAfterSave"); AddEventHandler("iblock", "OnAfterIBlockElementAdd", "BXIBlockAfterSave"); AddEventHandler("catalog", "OnPriceAdd", "BXIBlockAfterSave"); AddEventHandler("catalog", "OnPriceUpdate", "BXIBlockAfterSave"); function BXIBlockAfterSave($arg1, $arg2 = false) { global $USER; $ELEMENT_ID = false; $IBLOCK_ID = false; $OFFERS_IBLOCK_ID = false; $OFFERS_PROPERTY_ID = false; $BX_SITE_ID = "s1"; 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"]; } } elseif (is_array($arg1) && intval($arg1['ID'])>0 && isset($arg1['QUANTITY'])){ $ELEMENT_ID = intval($arg1["ID"]); $IBLOCK_ID = intval($_REQUEST['IBLOCK_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 foreach ($arProductID as $productID) { $arDiscountPrice = CCatalogProduct::GetOptimalPrice($productID, 1, $USER->GetUserGroupArray(), false, false, $BX_SITE_ID); if (CModule::IncludeModule('currency') && $strDefaultCurrency != $arDiscountPrice['RESULT_PRICE']['CURRENCY']) $arDiscountPrice['DISCOUNT_PRICE'] = CCurrencyRates::ConvertCurrency( $arDiscountPrice['DISCOUNT_PRICE'], $arDiscountPrice['RESULT_PRICE']["CURRENCY"], $strDefaultCurrency ); $PRICE = $arDiscountPrice['DISCOUNT_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
Update 2019-08-21
Была обнаружена такая особенность: если изменения происходят только по цене, то свойство с минимальной цено не обновлялось (точнее оно затиралось данными из формы товара). Внес правки в код, чтобы исправить эту ситуацию
Разработка сайта
Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин - что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки...
Сопровождение сайта
Вы можете подать заявку на сопровождение вашего сайта на базе 1С-Битрикс. Сопровождение включает в себя: проверка актуальности обновлений сайта, проверка актуальности резервной копии, консультации по сайту. Опишите в заявке, какие еще объемы планируются на сопровождении и на какой срок вы планируете заключить договор на сопровождение - мы подберем подходящий вам бюджет на сопровождение
Работы по сайту
Вы можете подать заявку на выполнение определенного объема работ по сайту. Опишите в заявке объем работ. Это может быть разработка какого-то нового функционала, доработки по имеющемуся функционалу, доработки под требования сео-специалистов. На основании заявки вам будет сформирован бюджет работ, а также названы сроки на выполнение тех или иных работ.