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

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

1539
17.10.2014
18.12.2018

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

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

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

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

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

Выход из данной проблемы был в 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)
{
	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"];
		}
	}

	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

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


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


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


Комментарии

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

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

captcha

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