Ejemplo n.º 1
0
 /**
  * @param array $arParams
  * @return array|false
  */
 public static function GetProductData($arParams)
 {
     $adminSection = defined('ADMIN_SECTION') && ADMIN_SECTION === true;
     if (!isset($arParams['QUANTITY']) || (double) $arParams['QUANTITY'] <= 0) {
         $arParams['QUANTITY'] = 0;
     }
     $arParams['RENEWAL'] = isset($arParams['RENEWAL']) && $arParams['RENEWAL'] == 'Y' ? 'Y' : 'N';
     $arParams['CHECK_QUANTITY'] = isset($arParams['CHECK_QUANTITY']) && $arParams["CHECK_QUANTITY"] == 'N' ? 'N' : 'Y';
     $arParams['CHECK_PRICE'] = isset($arParams['CHECK_PRICE']) && $arParams['CHECK_PRICE'] == 'N' ? 'N' : 'Y';
     $arParams['CHECK_COUPONS'] = isset($arParams['CHECK_COUPONS']) && $arParams['CHECK_COUPONS'] == 'N' ? 'N' : 'Y';
     $arParams['CHECK_DISCOUNT'] = isset($arParams['CHECK_DISCOUNT']) && $arParams['CHECK_DISCOUNT'] == 'N' ? 'N' : 'Y';
     $arParams['SELECT_QUANTITY_TRACE'] = isset($arParams['SELECT_QUANTITY_TRACE']) && $arParams['SELECT_QUANTITY_TRACE'] == 'Y' ? 'Y' : 'N';
     $arParams['BASKET_ID'] = (string) (isset($arParams['BASKET_ID']) ? $arParams['BASKET_ID'] : '0');
     $arParams['USER_ID'] = isset($arParams['USER_ID']) ? (int) $arParams['USER_ID'] : 0;
     if ($arParams['USER_ID'] < 0) {
         $arParams['USER_ID'] = 0;
     }
     $arParams['SITE_ID'] = isset($arParams['SITE_ID']) ? $arParams['SITE_ID'] : false;
     $strSiteID = $arParams['SITE_ID'];
     $arParams['CURRENCY'] = isset($arParams['CURRENCY']) ? Currency\CurrencyManager::checkCurrencyID($arParams['CURRENCY']) : false;
     if ($arParams['CURRENCY'] === false) {
         $arParams['CURRENCY'] = CSaleLang::GetLangCurrency($strSiteID ? $strSiteID : SITE_ID);
     }
     $productID = (int) $arParams['PRODUCT_ID'];
     $quantity = (double) $arParams['QUANTITY'];
     $intUserID = (int) $arParams['USER_ID'];
     global $USER, $APPLICATION;
     $arResult = array();
     if ($adminSection) {
         if (!($userGroups = static::getHitCache('USER_GROUPS', $intUserID))) {
             $userGroups = self::getUserGroups($intUserID);
             static::setHitCache('USER_GROUPS', $intUserID, $userGroups);
         }
         if (empty($userGroups)) {
             return $arResult;
         }
         if (!($arProduct = static::getHitCache('IBLOCK_ELEMENT_PERM_N', $productID))) {
             $dbIBlockElement = CIBlockElement::GetList(array(), array('ID' => $productID, 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y', 'CHECK_PERMISSIONS' => 'N'), false, false, array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL'));
             if ($arProduct = $dbIBlockElement->GetNext()) {
                 static::setHitCache('IBLOCK_ELEMENT_PERM_N', $productID, $arProduct);
             }
             unset($dbIBlockElement);
         }
         if (empty($arProduct) || !is_array($arProduct)) {
             return $arResult;
         }
         if (!($iblockRights = static::getHitCache('IBLOCK_RIGHT', $arProduct['IBLOCK_ID']))) {
             if ($iblockRights = CIBlock::GetArrayByID($arProduct['IBLOCK_ID'], 'RIGHTS_MODE')) {
                 static::setHitCache('IBLOCK_RIGHT', $arProduct['IBLOCK_ID'], $iblockRights);
             }
         }
         $extRights = $iblockRights == 'E';
         if ($intUserID == 0) {
             if ($extRights) {
                 $elementRights = new CIBlockElementRights($arProduct['IBLOCK_ID'], $arProduct['ID']);
                 $readList = $elementRights->GetRights(array('operations' => array('element_read')));
                 $disable = true;
                 if (!empty($readList) && is_array($readList)) {
                     foreach ($readList as &$row) {
                         if ($row['GROUP_CODE'] == 'G2') {
                             $disable = false;
                             break;
                         }
                     }
                     unset($row);
                 }
                 unset($readList, $elementRights);
                 if ($disable) {
                     return $arResult;
                 }
                 unset($disable);
             } else {
                 $groupRights = CIBlock::GetGroupPermissions($arProduct['IBLOCK_ID']);
                 if (empty($groupRights) || !isset($groupRights[2]) || $groupRights[2] < 'R') {
                     return $arResult;
                 }
                 unset($groupRights);
             }
         } else {
             if ($extRights) {
                 $proxyUserPermissionKey = $productID . "|" . $intUserID;
                 if (!($arUserRights = static::getHitCache('USER_RIGHT', $proxyUserPermissionKey))) {
                     if ($arUserRights = CIBlockElementRights::GetUserOperations($productID, $intUserID)) {
                         static::setHitCache('USER_RIGHT', $proxyUserPermissionKey, $arUserRights);
                     }
                 }
                 if (empty($arUserRights) || !isset($arUserRights['element_read'])) {
                     return $arResult;
                 }
                 unset($arUserRights);
             } else {
                 static $permissions = array();
                 if (empty($permissions[$arProduct['IBLOCK_ID'] . "_" . $intUserID])) {
                     $permissions[$arProduct['IBLOCK_ID'] . "_" . $intUserID] = CIBlock::GetPermission($arProduct['IBLOCK_ID'], $intUserID);
                 }
                 if ($permissions < 'R') {
                     return $arResult;
                 }
             }
         }
         unset($extRights);
     } else {
         $userGroups = $USER->GetUserGroupArray();
         if (!($arProduct = static::getHitCache('IBLOCK_ELEMENT_PERM_Y', $productID))) {
             $dbIBlockElement = CIBlockElement::GetList(array(), array('ID' => $productID, 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y', 'CHECK_PERMISSIONS' => 'Y', 'MIN_PERMISSION' => 'R'), false, false, array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL'));
             if ($arProduct = $dbIBlockElement->GetNext()) {
                 static::setHitCache('IBLOCK_ELEMENT_PERM_Y', $productID, $arProduct);
             }
             unset($dbIBlockElement);
         }
         if (empty($arProduct) || !is_array($arProduct)) {
             return $arResult;
         }
     }
     if (!isset(self::$catalogList[$arProduct['IBLOCK_ID']])) {
         self::$catalogList[$arProduct['IBLOCK_ID']] = Catalog\CatalogIblockTable::getList(array('select' => array('IBLOCK_ID', 'SUBSCRIPTION'), 'filter' => array('=IBLOCK_ID' => $arProduct['IBLOCK_ID'])))->fetch();
     }
     if (empty(self::$catalogList[$arProduct['IBLOCK_ID']]) || !is_array(self::$catalogList[$arProduct['IBLOCK_ID']])) {
         return $arResult;
     }
     if (self::$catalogList[$arProduct['IBLOCK_ID']]['SUBSCRIPTION'] == 'Y') {
         $quantity = 1;
     }
     if (!($arCatalogProduct = static::getHitCache('CATALOG_PRODUCT', $productID))) {
         $rsProducts = CCatalogProduct::GetList(array(), array('ID' => $productID), false, false, array('ID', 'CAN_BUY_ZERO', 'QUANTITY_TRACE', 'QUANTITY', 'WEIGHT', 'WIDTH', 'HEIGHT', 'LENGTH', 'BARCODE_MULTI', 'TYPE'));
         if ($arCatalogProduct = $rsProducts->Fetch()) {
             static::setHitCache('CATALOG_PRODUCT', $productID, $arCatalogProduct);
         }
         unset($rsProducts);
     }
     if (!empty($arCatalogProduct) && is_array($arCatalogProduct)) {
         $dblQuantity = doubleval($arCatalogProduct["QUANTITY"]);
         $boolQuantity = 'Y' != $arCatalogProduct["CAN_BUY_ZERO"] && 'Y' == $arCatalogProduct["QUANTITY_TRACE"];
         if ($arParams["CHECK_QUANTITY"] == "Y" && $boolQuantity && 0 >= $dblQuantity) {
             $APPLICATION->ThrowException(Loc::getMessage("CATALOG_NO_QUANTITY_PRODUCT", array("#NAME#" => htmlspecialcharsbx($arProduct["~NAME"]))), "CATALOG_NO_QUANTITY_PRODUCT");
             return $arResult;
         }
     } else {
         $APPLICATION->ThrowException(Loc::getMessage("CATALOG_ERR_NO_PRODUCT"), "CATALOG_NO_QUANTITY_PRODUCT");
         return $arResult;
     }
     if ($arParams["CHECK_PRICE"] == "Y") {
         $productHash = array('MODULE' => 'catalog', 'PRODUCT_ID' => $productID, 'BASKET_ID' => $arParams['BASKET_ID']);
         $arCoupons = array();
         if ($arParams['CHECK_COUPONS'] == 'Y') {
             $arCoupons = DiscountCouponsManager::getForApply(array(), $productHash, true);
             if (!empty($arCoupons)) {
                 $arCoupons = array_keys($arCoupons);
             }
         }
         if ($adminSection) {
             if ($intUserID > 0) {
                 CCatalogDiscountSave::SetDiscountUserID($intUserID);
             } else {
                 CCatalogDiscountSave::Disable();
             }
         }
         $currentVatMode = CCatalogProduct::getPriceVatIncludeMode();
         $currentUseDiscount = CCatalogProduct::getUseDiscount();
         CCatalogProduct::setUseDiscount($arParams['CHECK_DISCOUNT'] == 'Y');
         CCatalogProduct::setPriceVatIncludeMode(true);
         CCatalogProduct::setUsedCurrency($arParams['CURRENCY']);
         $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $userGroups, $arParams['RENEWAL'], array(), $adminSection ? $strSiteID : false, $arCoupons);
         if (empty($arPrice)) {
             if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $userGroups)) {
                 $quantity = $nearestQuantity;
                 $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $userGroups, $arParams['RENEWAL'], array(), $adminSection ? $strSiteID : false, $arCoupons);
             }
         }
         CCatalogProduct::clearUsedCurrency();
         CCatalogProduct::setPriceVatIncludeMode($currentVatMode);
         CCatalogProduct::setUseDiscount($currentUseDiscount);
         unset($userGroups, $currentUseDiscount, $currentVatMode);
         if ($adminSection) {
             if ($intUserID > 0) {
                 CCatalogDiscountSave::ClearDiscountUserID();
             } else {
                 CCatalogDiscountSave::Enable();
             }
         }
         if (empty($arPrice)) {
             return $arResult;
         }
         $arDiscountList = array();
         if (empty($arPrice['DISCOUNT_LIST']) && !empty($arPrice['DISCOUNT']) && is_array($arPrice['DISCOUNT'])) {
             $arPrice['DISCOUNT_LIST'] = array($arPrice['DISCOUNT']);
         }
         if (!empty($arPrice['DISCOUNT_LIST'])) {
             $appliedCoupons = array();
             foreach ($arPrice['DISCOUNT_LIST'] as &$arOneDiscount) {
                 $arOneList = array('ID' => $arOneDiscount['ID'], 'NAME' => $arOneDiscount['NAME'], 'COUPON' => '', 'COUPON_TYPE' => '', 'USE_COUPONS' => isset($arOneDiscount['USE_COUPONS']) ? $arOneDiscount['USE_COUPONS'] : 'N', 'MODULE_ID' => isset($oneDiscount['MODULE_ID']) ? $oneDiscount['MODULE_ID'] : 'catalog', 'TYPE' => $arOneDiscount['TYPE'], 'VALUE' => $arOneDiscount['VALUE'], 'VALUE_TYPE' => $arOneDiscount['VALUE_TYPE'], 'MAX_VALUE' => $arOneDiscount['VALUE_TYPE'] == Catalog\DiscountTable::VALUE_TYPE_PERCENT ? $arOneDiscount['MAX_DISCOUNT'] : 0, 'CURRENCY' => $arOneDiscount['CURRENCY'], 'HANDLERS' => isset($arOneDiscount['HANDLERS']) ? $arOneDiscount['HANDLERS'] : array());
                 if (!empty($arOneDiscount['COUPON'])) {
                     $arOneList['USE_COUPONS'] = 'Y';
                     $arOneList['COUPON'] = $arOneDiscount['COUPON'];
                     $arOneList['COUPON_TYPE'] = $arOneDiscount['COUPON_ONE_TIME'];
                     $appliedCoupons[] = $arOneDiscount['COUPON'];
                 }
                 $arDiscountList[] = $arOneList;
             }
             unset($arOneList, $arOneDiscount);
             if (!empty($appliedCoupons)) {
                 $resultApply = DiscountCouponsManager::setApplyByProduct($productHash, $appliedCoupons);
             }
             unset($resultApply, $appliedCoupons);
         }
         if (empty($arPrice['PRICE']['CATALOG_GROUP_NAME'])) {
             if (!empty($arPrice['PRICE']['CATALOG_GROUP_ID'])) {
                 $priceName = self::getPriceTitle($arPrice['PRICE']['CATALOG_GROUP_ID']);
                 if ($priceName != '') {
                     $arPrice['PRICE']['CATALOG_GROUP_NAME'] = $priceName;
                 }
                 unset($priceName);
             }
         }
     } else {
         $vatRate = 0.0;
         if (!($arVAT = static::getHitCache('VAT_INFO', $productID))) {
             $rsVAT = CCatalogProduct::GetVATInfo($productID);
             if ($arVAT = $rsVAT->Fetch()) {
                 static::setHitCache('VAT_INFO', $productID, $arVAT);
             }
             unset($rsVAT);
         }
         if (!empty($arVAT) && is_array($arVAT)) {
             $vatRate = (double) $arVAT['RATE'] * 0.01;
         }
     }
     $arResult = array("NAME" => $arProduct["~NAME"], "CAN_BUY" => "Y", "DETAIL_PAGE_URL" => $arProduct['~DETAIL_PAGE_URL'], "BARCODE_MULTI" => $arCatalogProduct["BARCODE_MULTI"], "WEIGHT" => (double) $arCatalogProduct['WEIGHT'], "DIMENSIONS" => serialize(array("WIDTH" => $arCatalogProduct["WIDTH"], "HEIGHT" => $arCatalogProduct["HEIGHT"], "LENGTH" => $arCatalogProduct["LENGTH"])), "TYPE" => $arCatalogProduct["TYPE"] == CCatalogProduct::TYPE_SET ? CCatalogProductSet::TYPE_SET : null);
     if ($arParams['SELECT_QUANTITY_TRACE'] == "Y") {
         $arResult["QUANTITY_TRACE"] = $arCatalogProduct["QUANTITY_TRACE"];
     }
     if ($arParams["CHECK_QUANTITY"] == "Y") {
         $arResult["QUANTITY"] = $boolQuantity && $dblQuantity < $quantity ? $dblQuantity : $quantity;
     } else {
         $arResult["QUANTITY"] = $arParams["QUANTITY"];
     }
     if ($arParams["CHECK_QUANTITY"] == "Y" && $boolQuantity && $dblQuantity < $quantity) {
         $APPLICATION->ThrowException(Loc::getMessage("CATALOG_QUANTITY_NOT_ENOGH", array("#NAME#" => htmlspecialcharsbx($arProduct["~NAME"]), "#CATALOG_QUANTITY#" => $arCatalogProduct["QUANTITY"], "#QUANTITY#" => $quantity)), "CATALOG_QUANTITY_NOT_ENOGH");
     }
     if ($arParams['CHECK_PRICE'] == 'Y') {
         $arResult['PRODUCT_PRICE_ID'] = $arPrice['PRICE']['ID'];
         $arResult['NOTES'] = $arPrice['PRICE']['CATALOG_GROUP_NAME'];
         $arResult['VAT_RATE'] = $arPrice['PRICE']['VAT_RATE'];
         $arResult['DISCOUNT_NAME'] = '';
         $arResult['DISCOUNT_COUPON'] = '';
         $arResult['DISCOUNT_LIST'] = array();
         if (empty($arPrice['RESULT_PRICE']) || !is_array($arPrice['RESULT_PRICE'])) {
             $arPrice['RESULT_PRICE'] = CCatalogDiscount::calculateDiscountList($arPrice['PRICE'], $arParams['CURRENCY'], $arDiscountList, true);
         }
         $arResult['BASE_PRICE'] = $arPrice['RESULT_PRICE']['BASE_PRICE'];
         $arResult['PRICE'] = $arPrice['RESULT_PRICE']['DISCOUNT_PRICE'];
         $arResult['CURRENCY'] = $arPrice['RESULT_PRICE']['CURRENCY'];
         $arResult['DISCOUNT_PRICE'] = $arPrice['RESULT_PRICE']['DISCOUNT'];
         if (isset($arPrice['RESULT_PRICE']['PERCENT'])) {
             $arResult['DISCOUNT_VALUE'] = $arPrice['RESULT_PRICE']['PERCENT'] > 0 ? $arPrice['RESULT_PRICE']['PERCENT'] . '%' : 0;
         } else {
             $arResult['DISCOUNT_VALUE'] = $arPrice['RESULT_PRICE']['DISCOUNT_VALUE'];
         }
         if (!empty($arDiscountList)) {
             $arResult['DISCOUNT_LIST'] = $arDiscountList;
         }
         if (!empty($arPrice['DISCOUNT'])) {
             $arResult['DISCOUNT_NAME'] = '[' . $arPrice['DISCOUNT']['ID'] . '] ' . $arPrice['DISCOUNT']['NAME'];
             if (!empty($arPrice['DISCOUNT']['COUPON'])) {
                 $arResult['DISCOUNT_COUPON'] = $arPrice['DISCOUNT']['COUPON'];
             }
             if (empty($arResult['DISCOUNT_LIST'])) {
                 $arResult['DISCOUNT_LIST'] = array($arPrice['DISCOUNT']);
             }
         }
     } else {
         $arResult['VAT_RATE'] = $vatRate;
     }
     $arResult["VAT_INCLUDED"] = "Y";
     return $arResult;
 }
Ejemplo n.º 2
0
	/**
	 * <p>Метод возвращает параметры наименьшей цены товара productID в количестве quantity для посетителя, входящего в группы пользователей arUserGroups.</p>
	 *
	 *
	 *
	 *
	 * @param int $productID  Код товара.
	 *
	 *
	 *
	 * @param  $int  Приобретаемое количество.
	 *
	 *
	 *
	 * @param quantit $y = 1[ массив групп, которым принадлежит пользователь. Для текущего
	 * пользователя он возвращается методом $USER-&gt;GetUserGroupArray() 
	 *
	 *
	 *
	 * @param array $arUserGroups = array()[ "Y", если вычисляется для продления товара (продажа контента), "N" в
	 * остальных случаях.
	 *
	 *
	 *
	 * @param string $renewal = "N"[ Массив цен. Если он установлен, то пересчет идет не по ценам из
	 * базы данных, а по ценам из этого массива. Представляет собой
	 * массив ассоциативных массивов с ключами: <ul> <li> <b>ID</b> - код цены;</li>
	 * <li> <b>PRICE</b> - цена;</li> <li> <b>CURRENCY</b> - валюта;</li> <li> <b>CATALOG_GROUP_ID</b> - код
	 * типа цен.</li> </ul>
	 *
	 *
	 *
	 * @param array $arPrices = array()[ Сайт, для которого производится вычисление. Если парамерт равен
	 * <i>false</i>, то берется текущий сайт.
	 *
	 *
	 *
	 * @param string $siteID = false]]]]] 
	 *
	 *
	 *
	 * @return array <p>Массив вида:</p><pre class="syntax">array( "PRICE" =&gt;
	 * массив_параметров_минимальной_цены, "DISCOUNT_PRICE" =&gt;
	 * минимальная_цена_в_базовой_валюте, "DISCOUNT" =&gt;
	 * массив_параметров_максимальной_доступной_скидки )</pre><p><b>Обратите
	 * внимание, что</b> <i>DISCOUNT_PRICE</i> это минимальная цена в <b>базовой
	 * валюте</b>. Чтобы перевести эту цену в валюту товара,
	 * необходимо:</p><pre class="syntax">array( $baseCurrency = CCurrency::GetBaseCurrency();
	 * $arPrice["DISCOUNT_PRICE"] = CCurrencyRates::ConvertCurrency($arPrice['DISCOUNT_PRICE'], $baseCurrency,
	 * $arPrice["PRICE"]["CURRENCY"]); )</pre><a name="examples"></a>
	 *
	 *
	 * <h4>Example</h4> 
	 * <pre>
	 * &lt;?
	 * $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER-&gt;GetUserGroupArray(), $renewal);
	 * if (!$arPrice || count($arPrice) &lt;= 0)
	 * {
	 *     if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $USER-&gt;GetUserGroupArray()))
	 *     {
	 *         $quantity = $nearestQuantity;
	 *         $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER-&gt;GetUserGroupArray(), $renewal);
	 *     }
	 * }
	 * echo "&lt;pre&gt;";
	 * print_r($arPrice);
	 * echo "&lt;/pre&gt;";
	 * ?&gt;
	 * </pre>
	 *
	 *
	 * @static
	 * @link http://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogproduct/ccatalogproduct__getoptimalprice.7c16046d.php
	 * @author Bitrix
	 */
	public static function GetOptimalPrice($intProductID, $quantity = 1, $arUserGroups = array(), $renewal = "N", $arPrices = array(), $siteID = false, $arDiscountCoupons = false)
	{
		global $APPLICATION;

		$mxResult = true;
		foreach (GetModuleEvents("catalog", "OnGetOptimalPrice", true) as $arEvent)
		{
			$mxResult = ExecuteModuleEventEx($arEvent, array($intProductID, $quantity, $arUserGroups, $renewal, $arPrices, $siteID, $arDiscountCoupons));
			if (true !== $mxResult)
				return $mxResult;
		}

		$intProductID = intval($intProductID);
		if (0 >= $intProductID)
		{
			$APPLICATION->ThrowException(GetMessage("BT_MOD_CATALOG_PROD_ERR_PRODUCT_ID_ABSENT"), "NO_PRODUCT_ID");
			return false;
		}

		$quantity = doubleval($quantity);
		if (0 >= $quantity)
		{
			$APPLICATION->ThrowException(GetMessage("BT_MOD_CATALOG_PROD_ERR_QUANTITY_ABSENT"), "NO_QUANTITY");
			return false;
		}

		if (!is_array($arUserGroups) && intval($arUserGroups)."|" == $arUserGroups."|")
			$arUserGroups = array(intval($arUserGroups));

		if (!is_array($arUserGroups))
			$arUserGroups = array();

		if (!in_array(2, $arUserGroups))
			$arUserGroups[] = 2;

		$rsVAT = CCatalogProduct::GetVATInfo($intProductID);
		if ($arVAT = $rsVAT->Fetch())
		{
			$arVAT['RATE'] = doubleval($arVAT['RATE'] * 0.01);
		}
		else
		{
			$arVAT = array('RATE' => 0.0, 'VAT_INCLUDED' => 'N');
		}

		$renewal = (($renewal == "N") ? "N" : "Y");

		if (false === $siteID)
			$siteID = SITE_ID;

		if (false === $arDiscountCoupons)
			$arDiscountCoupons = CCatalogDiscountCoupon::GetCoupons();

		$strBaseCurrency = CCurrency::GetBaseCurrency();
		if (empty($strBaseCurrency))
		{
			$APPLICATION->ThrowException(GetMessage("BT_MOD_CATALOG_PROD_ERR_NO_BASE_CURRENCY"), "NO_BASE_CURRENCY");
			return false;
		}

		$intIBlockID = intval(CIBlockElement::GetIBlockByID($intProductID));
		if (0 >= $intIBlockID)
		{
			$APPLICATION->ThrowException(str_replace("#ID#", $intProductID, GetMessage('BT_MOD_CATALOG_PROD_ERR_ELEMENT_ID_NOT_FOUND')), "NO_ELEMENT");
			return false;
		}

		if (!isset($arPrices) || !is_array($arPrices))
			$arPrices = array();

		if (empty($arPrices))
		{
			$arPrices = array();
			$dbPriceList = CPrice::GetListEx(
				array(),
				array(
						"PRODUCT_ID" => $intProductID,
						"GROUP_GROUP_ID" => $arUserGroups,
						"GROUP_BUY" => "Y",
						"+<=QUANTITY_FROM" => $quantity,
						"+>=QUANTITY_TO" => $quantity
					),
				false,
				false,
				array("ID", "CATALOG_GROUP_ID", "PRICE", "CURRENCY")
			);
			while ($arPriceList = $dbPriceList->Fetch())
			{
				$arPriceList['ELEMENT_IBLOCK_ID'] = $intIBlockID;
				$arPrices[] = $arPriceList;
			}
		}
		else
		{
			foreach ($arPrices as &$arOnePrice)
			{
				$arOnePrice['ELEMENT_IBLOCK_ID'] = $intIBlockID;
			}
			if (isset($arOnePrice))
				unset($arOnePrice);
		}

		if (empty($arPrices))
			return false;

//		$boolDiscountVat = ('N' != COption::GetOptionString('catalog', 'discount_vat', 'Y'));
		$boolDiscountVat = true;
		$strDiscSaveApply = COption::GetOptionString('catalog', 'discsave_apply', 'R');

		$dblMinPrice = -1;
		$arMinPrice = array();
		$arMinDiscounts = array();

		foreach ($arPrices as &$arPriceList)
		{
			$arPriceList['VAT_RATE'] = $arVAT['RATE'];
			$arPriceList['VAT_INCLUDED'] = $arVAT['VAT_INCLUDED'];
			$arPriceList['ORIG_VAT_INCLUDED'] = $arPriceList['VAT_INCLUDED'];

			if ($boolDiscountVat)
			{
				if ('N' == $arPriceList['VAT_INCLUDED'])
				{
					$arPriceList['PRICE'] *= (1 + $arPriceList['VAT_RATE']);
					$arPriceList['VAT_INCLUDED'] = 'Y';
				}
			}
			else
			{
				if ('Y' == $arPriceList['VAT_INCLUDED'])
				{
					$arPriceList['PRICE'] /= (1 + $arPriceList['VAT_RATE']);
					$arPriceList['VAT_INCLUDED'] = 'N';
				}
			}

			if ($arPriceList["CURRENCY"] == $strBaseCurrency)
				$dblCurrentPrice = $arPriceList["PRICE"];
			else
				$dblCurrentPrice = CCurrencyRates::ConvertCurrency($arPriceList["PRICE"], $arPriceList["CURRENCY"], $strBaseCurrency);

			$arDiscounts = CCatalogDiscount::GetDiscount($intProductID, $intIBlockID, $arPriceList["CATALOG_GROUP_ID"], $arUserGroups, $renewal, $siteID, $arDiscountCoupons);

			$arDiscSave = array();
			$arPriceDiscount = array();

			$arResultPrice = array(
				'PRICE' => $dblCurrentPrice,
				'CURRENCY' => $strBaseCurrency,
			);
			$arDiscountApply = array();

			if (!empty($arDiscounts))
			{
				CCatalogProduct::__PrimaryDiscountFilter($arDiscounts, $arPriceDiscount, $arDiscSave, $arResultPrice);

				if (!empty($arPriceDiscount))
				{
					foreach ($arPriceDiscount as &$arOnePriority)
					{
						$boolResultPriority = CCatalogProduct::__CalcOnePriority($arOnePriority, $arDiscountApply, $arResultPrice);
						if (!$boolResultPriority)
						{
							return false;
						}
						else
						{
							if (isset($arResultPrice['LAST_DISCOUNT']) && 'Y' == $arResultPrice['LAST_DISCOUNT'])
								break;
						}
					}
					if (isset($arOnePriority))
						unset($arOnePriority);
				}

				if (!empty($arDiscSave))
				{
					switch($strDiscSaveApply)
					{
					case 'R':
						$arDiscSaveResult = array(
							'PRICE' => $dblCurrentPrice,
							'CURRENCY' => $strBaseCurrency,
						);
						$arDiscSaveApply = array();
						$boolResultDiscSave = CCatalogProduct::__CalcDiscSave($arDiscSave, $arDiscSaveApply, $arDiscSaveResult);
						if (!$boolResultDiscSave)
						{
							return false;
						}
						else
						{
							if ($arDiscSaveResult['PRICE'] < $arResultPrice['PRICE'])
							{
								$arResultPrice = $arDiscSaveResult;
								$arDiscountApply = $arDiscSaveApply;
							}
						}
						break;
					case 'A':
						$boolResultDiscSave = CCatalogProduct::__CalcDiscSave($arDiscSave, $arDiscountApply, $arResultPrice);
						if (!$boolResultDiscSave)
						{
							return false;
						}
						break;
					case 'D':
						if (empty($arDiscountApply))
						{
							$boolResultDiscSave = CCatalogProduct::__CalcDiscSave($arDiscSave, $arDiscountApply, $arResultPrice);
							if (!$boolResultDiscSave)
							{
								return false;
							}
						}
						break;
					}
				}
			}

			if (-1 == $dblMinPrice || $dblMinPrice > $arResultPrice['PRICE'])
			{
				$dblMinPrice = $arResultPrice['PRICE'];
				$arMinPrice = $arPriceList;
				$arMinDiscounts = $arDiscountApply;
			}
		}
		if (isset($arPriceList))
			unset($arPriceList);

		if ($boolDiscountVat)
		{
			if ('N' == $arMinPrice['ORIG_VAT_INCLUDED'])
			{
				$arMinPrice['PRICE'] /= (1 + $arMinPrice['VAT_RATE']);
				$arMinPrice['VAT_INCLUDED'] = $arMinPrice['ORIG_VAT_INCLUDED'];
			}
		}
		else
		{
			if ('Y' == $arMinPrice['ORIG_VAT_INCLUDED'])
			{
				$arMinPrice['PRICE'] *= (1 + $arMinPrice['VAT_RATE']);
				$arMinPrice['VAT_INCLUDED'] = $arMinPrice['ORIG_VAT_INCLUDED'];
			}
		}
		unset($arMinPrice['ORIG_VAT_INCLUDED']);

		$dblMinPrice = roundEx($dblMinPrice, CATALOG_VALUE_PRECISION);

		$arResult = array(
			'PRICE' => $arMinPrice,
			'DISCOUNT_PRICE' => $dblMinPrice,
			'DISCOUNT' => array(),
			'DISCOUNT_LIST' => array(),
		);
		if (!empty($arMinDiscounts))
		{
			reset($arMinDiscounts);
			$arResult['DISCOUNT'] = current($arMinDiscounts);
			$arResult['DISCOUNT_LIST'] = $arMinDiscounts;
		}

		foreach (GetModuleEvents("catalog", "OnGetOptimalPriceResult", true) as $arEvent)
		{
			if (ExecuteModuleEventEx($arEvent, array(&$arResult))===false)
				return false;
		}

		return $arResult;
	}
Ejemplo n.º 3
0
function CatalogGetPriceTableEx($ID, $filterQauntity = 0, $arFilterType = array(), $VAT_INCLUDE = 'Y', $arCurrencyParams = array())
{
    global $USER;
    static $arPriceTypes = array();
    $ID = (int) $ID;
    if ($ID <= 0) {
        return false;
    }
    $filterQauntity = (int) $filterQauntity;
    if (!is_array($arFilterType)) {
        $arFilterType = array($arFilterType);
    }
    $boolConvert = false;
    $strCurrencyID = '';
    $arCurrencyList = array();
    if (!empty($arCurrencyParams) && is_array($arCurrencyParams) && !empty($arCurrencyParams['CURRENCY_ID'])) {
        $boolConvert = true;
        $strCurrencyID = $arCurrencyParams['CURRENCY_ID'];
    }
    $arResult = array();
    $arResult["ROWS"] = array();
    $arResult["COLS"] = array();
    $arResult["MATRIX"] = array();
    $arResult["CAN_BUY"] = array();
    $arResult["AVAILABLE"] = "N";
    $cacheTime = CATALOG_CACHE_DEFAULT_TIME;
    if (defined("CATALOG_CACHE_TIME")) {
        $cacheTime = intval(CATALOG_CACHE_TIME);
    }
    $arUserGroups = $USER->GetUserGroupArray();
    CatalogClearArray($arUserGroups, true);
    $strCacheID = 'UG_' . implode('_', $arUserGroups);
    if (isset($arPriceTypes[$strCacheID])) {
        $arPriceGroups = $arPriceTypes[$strCacheID];
    } else {
        $arPriceGroups = CCatalogGroup::GetGroupsPerms($arUserGroups, array());
        $arPriceTypes[$strCacheID] = $arPriceGroups;
    }
    if (empty($arPriceGroups["view"])) {
        return $arResult;
    }
    $currentQuantity = -1;
    $rowsCnt = -1;
    $arFilter = array("PRODUCT_ID" => $ID);
    if ($filterQauntity > 0) {
        $arFilter["+<=QUANTITY_FROM"] = $filterQauntity;
        $arFilter["+>=QUANTITY_TO"] = $filterQauntity;
    }
    if (!empty($arFilterType)) {
        $arTmp = array();
        foreach ($arPriceGroups["view"] as &$intOneGroup) {
            if (in_array($intOneGroup, $arFilterType)) {
                $arTmp[] = $intOneGroup;
            }
        }
        if (isset($intOneGroup)) {
            unset($intOneGroup);
        }
        if (empty($arTmp)) {
            return $arResult;
        }
        $arFilter["CATALOG_GROUP_ID"] = $arTmp;
    } else {
        $arFilter["CATALOG_GROUP_ID"] = $arPriceGroups["view"];
    }
    $productQuantity = 0;
    $productQuantityTrace = "N";
    $dbRes = CCatalogProduct::GetVATInfo($ID);
    if ($arVatInfo = $dbRes->Fetch()) {
        $fVatRate = floatval($arVatInfo['RATE'] * 0.01);
        $bVatIncluded = $arVatInfo['VAT_INCLUDED'] == 'Y';
    } else {
        $fVatRate = 0.0;
        $bVatIncluded = false;
    }
    $rsProducts = CCatalogProduct::GetList(array(), array('ID' => $ID), false, false, array('ID', 'CAN_BUY_ZERO', 'QUANTITY_TRACE', 'QUANTITY'));
    if ($arProduct = $rsProducts->Fetch()) {
        $intIBlockID = CIBlockElement::GetIBlockByID($arProduct['ID']);
        if (!$intIBlockID) {
            return false;
        }
        $arProduct['IBLOCK_ID'] = $intIBlockID;
    } else {
        return false;
    }
    $dbPrice = CPrice::GetListEx(array("QUANTITY_FROM" => "ASC", "QUANTITY_TO" => "ASC"), $arFilter, false, false, array("ID", "CATALOG_GROUP_ID", "PRICE", "CURRENCY", "QUANTITY_FROM", "QUANTITY_TO"));
    while ($arPrice = $dbPrice->Fetch()) {
        if ($VAT_INCLUDE == 'N') {
            if ($bVatIncluded) {
                $arPrice['PRICE'] /= 1 + $fVatRate;
            }
        } else {
            if (!$bVatIncluded) {
                $arPrice['PRICE'] *= 1 + $fVatRate;
            }
        }
        $arPrice['VAT_RATE'] = $fVatRate;
        CCatalogDiscountSave::Disable();
        $arDiscounts = CCatalogDiscount::GetDiscount($ID, $arProduct["IBLOCK_ID"], $arPrice["CATALOG_GROUP_ID"], $arUserGroups, "N", SITE_ID, array());
        CCatalogDiscountSave::Enable();
        $discountPrice = CCatalogProduct::CountPriceWithDiscount($arPrice["PRICE"], $arPrice["CURRENCY"], $arDiscounts);
        $arPrice["DISCOUNT_PRICE"] = $discountPrice;
        $arPrice["QUANTITY_FROM"] = doubleval($arPrice["QUANTITY_FROM"]);
        if ($currentQuantity != $arPrice["QUANTITY_FROM"]) {
            $rowsCnt++;
            $arResult["ROWS"][$rowsCnt]["QUANTITY_FROM"] = $arPrice["QUANTITY_FROM"];
            $arResult["ROWS"][$rowsCnt]["QUANTITY_TO"] = doubleval($arPrice["QUANTITY_TO"]);
            $currentQuantity = $arPrice["QUANTITY_FROM"];
        }
        if ($boolConvert && $strCurrencyID != $arPrice["CURRENCY"]) {
            $arResult["MATRIX"][intval($arPrice["CATALOG_GROUP_ID"])][$rowsCnt] = array("ID" => $arPrice["ID"], "ORIG_PRICE" => $arPrice["PRICE"], "ORIG_DISCOUNT_PRICE" => $arPrice["DISCOUNT_PRICE"], "ORIG_CURRENCY" => $arPrice["CURRENCY"], "ORIG_VAT_RATE" => $arPrice["VAT_RATE"], 'PRICE' => CCurrencyRates::ConvertCurrency($arPrice["PRICE"], $arPrice["CURRENCY"], $strCurrencyID), 'DISCOUNT_PRICE' => CCurrencyRates::ConvertCurrency($arPrice["DISCOUNT_PRICE"], $arPrice["CURRENCY"], $strCurrencyID), 'CURRENCY' => $strCurrencyID, 'VAT_RATE' => CCurrencyRates::ConvertCurrency($arPrice["VAT_RATE"], $arPrice["CURRENCY"], $strCurrencyID));
            $arCurrencyList[] = $arPrice["CURRENCY"];
        } else {
            $arResult["MATRIX"][intval($arPrice["CATALOG_GROUP_ID"])][$rowsCnt] = array("ID" => $arPrice["ID"], "PRICE" => $arPrice["PRICE"], "DISCOUNT_PRICE" => $arPrice["DISCOUNT_PRICE"], "CURRENCY" => $arPrice["CURRENCY"], "VAT_RATE" => $arPrice["VAT_RATE"]);
        }
    }
    $arCatalogGroups = CCatalogGroup::GetListArray();
    foreach ($arCatalogGroups as $key => $value) {
        if (isset($arResult["MATRIX"][$key])) {
            $arResult["COLS"][$value["ID"]] = $value;
        }
    }
    $arResult["CAN_BUY"] = $arPriceGroups["buy"];
    $arResult["AVAILABLE"] = 0 >= $arProduct['QUANTITY'] && 'Y' == $arProduct['QUANTITY_TRACE'] && 'N' == $arProduct['CAN_BUY_ZERO'] ? 'N' : 'Y';
    if ($boolConvert) {
        if (!empty($arCurrencyList)) {
            $arCurrencyList[] = $strCurrencyID;
        }
        $arResult['CURRENCY_LIST'] = $arCurrencyList;
    }
    return $arResult;
}
	/**
	 * @param array $arParams
	 * @return array|false
	 */
	public static function GetProductData($arParams)
	{
		if (!isset($arParams['QUANTITY']) || (float)$arParams['QUANTITY'] <= 0)
			$arParams['QUANTITY'] = 0;

		$arParams['RENEWAL'] = (isset($arParams['RENEWAL']) && $arParams['RENEWAL'] == 'Y' ? 'Y' : 'N');
		$arParams['CHECK_QUANTITY'] = (isset($arParams['CHECK_QUANTITY']) && $arParams["CHECK_QUANTITY"] == 'N' ? 'N' : 'Y');
		$arParams['CHECK_PRICE'] = (isset($arParams['CHECK_PRICE']) && $arParams['CHECK_PRICE'] == 'N' ? 'N' : 'Y');
		$arParams['CHECK_COUPONS'] = (isset($arParams['CHECK_COUPONS']) && $arParams['CHECK_COUPONS'] == 'N' ? 'N' : 'Y');
		$arParams['CHECK_DISCOUNT'] = (isset($arParams['CHECK_DISCOUNT']) && $arParams['CHECK_DISCOUNT'] == 'N' ? 'N' : 'Y');
		$arParams['BASKET_ID'] = (string)(isset($arParams['BASKET_ID']) ? $arParams['BASKET_ID'] : '0');
		$arParams['USER_ID'] = (isset($arParams['USER_ID']) ? (int)$arParams['USER_ID'] : 0);
		if ($arParams['USER_ID'] < 0)
			$arParams['USER_ID'] = 0;
		$arParams['SITE_ID'] = (isset($arParams['SITE_ID']) ? $arParams['SITE_ID'] : false);
		$strSiteID = $arParams['SITE_ID'];

		if (isset($arParams['CURRENCY']))
			$arParams['CURRENCY'] = CCurrency::checkCurrencyID($arParams['CURRENCY']);
		if ($arParams['CURRENCY'] === false)
			$arParams['CURRENCY'] = CSaleLang::GetLangCurrency($strSiteID ? $strSiteID : SITE_ID);

		$productID = (int)$arParams['PRODUCT_ID'];
		$quantity  = (float)$arParams['QUANTITY'];
		$renewal   = $arParams['RENEWAL'];
		$intUserID = (int)$arParams['USER_ID'];

		global $USER, $APPLICATION;

		$arResult = array();

		static $arUserCache = array();
		if (0 < $intUserID)
		{
			if (!isset($arUserCache[$intUserID]))
			{
				$by = 'ID';
				$order = 'DESC';
				$rsUsers = CUser::GetList($by, $order, array("ID_EQUAL_EXACT"=>$intUserID),array('FIELDS' => array('ID')));
				if ($arUser = $rsUsers->Fetch())
				{
					$arUser['ID'] = intval($arUser['ID']);
					$arUserCache[$arUser['ID']] = CUser::GetUserGroup($arUser['ID']);
				}
				else
				{
					$intUserID = 0;
					return $arResult;
				}
			}

			$dbIBlockElement = CIBlockElement::GetList(
				array(),
				array(
					"ID" => $productID,
					"ACTIVE" => "Y",
					"ACTIVE_DATE" => "Y",
					"CHECK_PERMISSIONS" => "N",
					),
				false,
				false,
				array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL')
				);
			if(!($arProduct = $dbIBlockElement->GetNext()))
				return $arResult;
			if ('E' == CIBlock::GetArrayByID($arProduct['IBLOCK_ID'], "RIGHTS_MODE"))
			{
				$arUserRights = CIBlockElementRights::GetUserOperations($productID, $intUserID);
				if (empty($arUserRights))
				{
					return $arResult;
				}
				elseif (!is_array($arUserRights) || !array_key_exists('element_read', $arUserRights))
				{
					return $arResult;
				}
			}
			else
			{
				if ('R' > CIBlock::GetPermission($arProduct['IBLOCK_ID'], $intUserID))
				{
					return $arResult;
				}
			}
		}
		else
		{
			$dbIBlockElement = CIBlockElement::GetList(
				array(),
				array(
					"ID" => $productID,
					"ACTIVE" => "Y",
					"ACTIVE_DATE" => "Y",
					"CHECK_PERMISSIONS" => "Y",
					"MIN_PERMISSION" => "R",
					),
				false,
				false,
				array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL')
				);
			if(!($arProduct = $dbIBlockElement->GetNext()))
				return $arResult;
		}

		$rsCatalogs = CCatalog::GetList(
			array(),
			array('IBLOCK_ID' => $arProduct["IBLOCK_ID"]),
			false,
			false,
			array(
				'IBLOCK_ID',
				'SUBSCRIPTION'
			)
		);
		if (!($arCatalog = $rsCatalogs->Fetch()))
		{
			return $arResult;
		}
		if ('Y' == $arCatalog["SUBSCRIPTION"])
		{
			$quantity = 1;
		}

		$dblQuantity = 0;
		$boolQuantity = false;

		$rsProducts = CCatalogProduct::GetList(
			array(),
			array('ID' => $productID),
			false,
			false,
			array(
				'ID',
				'CAN_BUY_ZERO',
				'QUANTITY_TRACE',
				'QUANTITY',
				'WEIGHT',
				'WIDTH',
				'HEIGHT',
				'LENGTH',
				'BARCODE_MULTI',
				'TYPE'
			)
		);

		if ($arCatalogProduct = $rsProducts->Fetch())
		{
			$dblQuantity = doubleval($arCatalogProduct["QUANTITY"]);
			$boolQuantity = ('Y' != $arCatalogProduct["CAN_BUY_ZERO"] && 'Y' == $arCatalogProduct["QUANTITY_TRACE"]);

			if ($arParams["CHECK_QUANTITY"] == "Y" && $boolQuantity && 0 >= $dblQuantity)
			{
				$APPLICATION->ThrowException(Loc::getMessage("CATALOG_NO_QUANTITY_PRODUCT", array("#NAME#" => htmlspecialcharsbx($arProduct["~NAME"]))), "CATALOG_NO_QUANTITY_PRODUCT");
				return $arResult;
			}
		}
		else
		{
			$APPLICATION->ThrowException(Loc::getMessage("CATALOG_ERR_NO_PRODUCT"), "CATALOG_NO_QUANTITY_PRODUCT");
			return $arResult;
		}

		if ($arParams["CHECK_PRICE"] == "Y")
		{
			$strBasketProductID = $productID.'_'.$arParams['BASKET_ID'];
			$arCoupons = array();
			if (0 < $intUserID)
			{
				if ('Y' == $arParams['CHECK_COUPONS'])
					$arCoupons = CCatalogDiscountCoupon::GetCouponsByManage($intUserID);

				CCatalogDiscountSave::SetDiscountUserID($intUserID);
			}
			else
			{
				if ('Y' == $arParams['CHECK_COUPONS'])
					$arCoupons = CCatalogDiscountCoupon::GetCoupons();
			}


			$boolChangeCoupons = false;
			$arNewCoupons = array();
			if (!empty($arCoupons) && is_array($arCoupons) && !empty(self::$arOneTimeCoupons))
			{
				foreach ($arCoupons as $key => $coupon)
				{
					if (isset(self::$arOneTimeCoupons[$coupon]))
					{
						if (self::$arOneTimeCoupons[$coupon] == $strBasketProductID)
						{
							$boolChangeCoupons = true;
							$arNewCoupons[] = $coupon;
						}
						else
						{
							unset($arCoupons[$key]);
						}
					}
				}
			}
			if ($boolChangeCoupons)
				$arCoupons = $arNewCoupons;

			$userGroups = ($intUserID > 0 ? $arUserCache[$intUserID] : $USER->GetUserGroupArray());
			$currentVatMode = CCatalogProduct::getPriceVatIncludeMode();
			$currentUseDiscount = CCatalogProduct::getUseDiscount();
			CCatalogProduct::setUseDiscount($arParams['CHECK_DISCOUNT'] == 'Y');
			CCatalogProduct::setPriceVatIncludeMode(true);
			CCatalogProduct::setUsedCurrency($arParams['CURRENCY']);
			$arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $userGroups, $renewal, array(), (0 < $intUserID ? $strSiteID : false), $arCoupons);

			if (empty($arPrice))
			{
				if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $userGroups))
				{
					$quantity = $nearestQuantity;
					$arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $userGroups, $renewal, array(), (0 < $intUserID ? $strSiteID : false), $arCoupons);
				}
			}
			CCatalogProduct::clearUsedCurrency();
			CCatalogProduct::setPriceVatIncludeMode($currentVatMode);
			CCatalogProduct::setUseDiscount($currentUseDiscount);
			unset($userGroups, $currentUseDiscount, $currentVatMode);
			if (0 < $intUserID)
			{
				CCatalogDiscountSave::ClearDiscountUserID();
			}

			if (empty($arPrice))
			{
				return $arResult;
			}

			$arDiscountList = array();

			if (!empty($arPrice["DISCOUNT_LIST"]))
			{
				foreach ($arPrice["DISCOUNT_LIST"] as &$arOneDiscount)
				{
					$arOneList = array(
						'ID' => $arOneDiscount['ID'],
						'NAME' => $arOneDiscount['NAME'],
						'COUPON' => '',
						'COUPON_TYPE' => '',
						'MODULE_ID' => (isset($oneDiscount['MODULE_ID']) ? $oneDiscount['MODULE_ID'] : 'catalog'),
						'TYPE' => $arOneDiscount['TYPE'],
						'VALUE' => $arOneDiscount['VALUE'],
						'VALUE_TYPE' => $arOneDiscount['VALUE_TYPE'],
						'CURRENCY' => $arOneDiscount['CURRENCY'],
						'HANDLERS' => (isset($arOneDiscount['HANDLERS']) ? $arOneDiscount['HANDLERS'] : array())
					);

					if ($arOneDiscount['COUPON'])
					{
						$arOneList['COUPON'] = $arOneDiscount['COUPON'];
						$arOneList['COUPON_TYPE'] = $arOneDiscount['COUPON_ONE_TIME'];
						if ($arOneDiscount['COUPON_ONE_TIME'] == CCatalogDiscountCoupon::TYPE_ONE_TIME)
						{
							self::$arOneTimeCoupons[$arOneDiscount['COUPON']] = $strBasketProductID;
						}
					}
					$arDiscountList[] = $arOneList;
				}
				unset($arOneList, $arOneDiscount);
			}

			if (empty($arPrice["PRICE"]["CATALOG_GROUP_NAME"]))
			{
				if (!empty($arPrice["PRICE"]["CATALOG_GROUP_ID"]))
				{
					$rsCatGroups = CCatalogGroup::GetListEx(array(),array('ID' => $arPrice["PRICE"]["CATALOG_GROUP_ID"]),false,false,array('ID','NAME','NAME_LANG'));
					if ($arCatGroup = $rsCatGroups->Fetch())
					{
						$arPrice["PRICE"]["CATALOG_GROUP_NAME"] = (!empty($arCatGroup['NAME_LANG']) ? $arCatGroup['NAME_LANG'] : $arCatGroup['NAME']);
					}
				}
			}
		}
		else
		{
			$rsVAT = CCatalogProduct::GetVATInfo($productID);
			if ($arVAT = $rsVAT->Fetch())
			{
				$vatRate = doubleval($arVAT['RATE'] * 0.01);
			}
			else
			{
				$vatRate = 0.0;
			}
		}

		$arResult = array(
			"NAME" => $arProduct["~NAME"],
			"CAN_BUY" => "Y",
			"DETAIL_PAGE_URL" => $arProduct['~DETAIL_PAGE_URL'],
			"BARCODE_MULTI" => $arCatalogProduct["BARCODE_MULTI"],
			"WEIGHT" => floatval($arCatalogProduct['WEIGHT']),
			"DIMENSIONS" => serialize(array(
				"WIDTH" => $arCatalogProduct["WIDTH"],
				"HEIGHT" => $arCatalogProduct["HEIGHT"],
				"LENGTH" => $arCatalogProduct["LENGTH"]
			)),
			"TYPE" => ($arCatalogProduct["TYPE"] == CCatalogProduct::TYPE_SET) ? CCatalogProductSet::TYPE_SET : NULL
		);

		if ($arParams["CHECK_QUANTITY"] == "Y")
			$arResult["QUANTITY"] = ($boolQuantity && $dblQuantity < $quantity) ? $dblQuantity : $quantity;
		else
			$arResult["QUANTITY"] = $arParams["QUANTITY"];

		if ($arParams["CHECK_QUANTITY"] == "Y" && $boolQuantity && $dblQuantity < $quantity)
			$APPLICATION->ThrowException(Loc::getMessage("CATALOG_QUANTITY_NOT_ENOGH", array("#NAME#" => htmlspecialcharsbx($arProduct["~NAME"]), "#CATALOG_QUANTITY#" => $arCatalogProduct["QUANTITY"], "#QUANTITY#" => $quantity)), "CATALOG_QUANTITY_NOT_ENOGH");

		if ($arParams["CHECK_PRICE"] == "Y")
		{
			$arResult = array_merge($arResult, array(
				"PRODUCT_PRICE_ID" => $arPrice["PRICE"]["ID"],
				'BASE_PRICE' => $arPrice['RESULT_PRICE']['BASE_PRICE'],
				"PRICE" => $arPrice['RESULT_PRICE']['DISCOUNT_PRICE'],
				"CURRENCY" => $arPrice['RESULT_PRICE']['CURRENCY'],
				"DISCOUNT_PRICE" => $arPrice['RESULT_PRICE']['DISCOUNT'],
				"NOTES" => $arPrice["PRICE"]["CATALOG_GROUP_NAME"],
				"VAT_RATE" => $arPrice["PRICE"]["VAT_RATE"],
				"DISCOUNT_VALUE" => ($arPrice['RESULT_PRICE']['PERCENT'] > 0 ? $arPrice['RESULT_PRICE']['PERCENT'].'%' : 0),
				"DISCOUNT_NAME" => '',
				"DISCOUNT_COUPON" => '',
				"DISCOUNT_LIST" => array()
			));

			if (!empty($arDiscountList))
			{
				$arResult['DISCOUNT_LIST'] = $arDiscountList;
				$arResult["DISCOUNT_NAME"] = "[".$arPrice["DISCOUNT"]["ID"]."] ".$arPrice["DISCOUNT"]["NAME"];
				if (!empty($arPrice["DISCOUNT"]["COUPON"]))
				{
					$arResult["DISCOUNT_COUPON"] = $arPrice["DISCOUNT"]["COUPON"];
				}
			}
		}
		else
		{
			$arResult["VAT_RATE"] = $vatRate;
		}

		return $arResult;
	}
Ejemplo n.º 5
0
 /**
  * <p>Метод возвращает параметры наименьшей цены товара productID в количестве quantity для посетителя, входящего в группы пользователей arUserGroups. Метод динамичный.</p>
  *
  *
  * @param int $intProductID  Код товара.<br><br> До версии <b>12.0.0</b> параметр назывался <b>productID</b>.
  *
  * @param  $int  Приобретаемое количество.
  *
  * @param quantit $y = 1[ массив групп, которым принадлежит пользователь. Для текущего
  * пользователя он возвращается методом $USER-&gt;GetUserGroupArray() 
  *
  * @param array $arUserGroups = array()[ "Y", если вычисляется для продления товара (продажа контента), "N" в
  * остальных случаях.
  *
  * @param string $renewal = "N"[ Массив цен. Если он установлен, то пересчет идет не по ценам из
  * базы данных, а по ценам из этого массива. Представляет собой
  * массив ассоциативных массивов с ключами: <ul> <li> <b>ID</b> - код цены;</li>
  * <li> <b>PRICE</b> - цена;</li> <li> <b>CURRENCY</b> - валюта;</li> <li> <b>CATALOG_GROUP_ID</b> - код
  * типа цен.</li> </ul>
  *
  * @param array $arPrices = array()[ Сайт, для которого производится вычисление. Если парамерт равен
  * <i>false</i>, то берется текущий сайт.
  *
  * @param string $siteID = false[ Массив купонов, которые влияют на выборку скидок. Если задано
  * значение <i>false</i>, то массив купонов будет взят из
  * <b>CCatalogDiscountCoupon::GetCoupons</b>
  *
  * @param array $arDiscountCoupons = false]]]]]] 
  *
  * @return array <p>Массив вида:</p> <pre class="syntax">array( "PRICE" =&gt;
  * массив_параметров_минимальной_цены, "DISCOUNT_PRICE" =&gt;
  * минимальная_цена_в_базовой_валюте, "DISCOUNT" =&gt;
  * массив_параметров_первой_из_примененных_скидок_торгового_каталога,
  * "DISCOUNT_LIST" =&gt;
  * массив_скидок_действующих_на_товар_в_порядке_применения, "RESULT_PRICE"
  * =&gt; array( "BASE_PRICE" =&gt; полная (без скидок) цена товара, "DISCOUNT_PRICE" =&gt;
  * цена со скидками, "DISCOUNT" =&gt; итоговая скидка (разница между BASE_PRICE и
  * DISCOUNT_PRICE) "PERCENT" =&gt; итоговая скидка в процентах "CURRENCY" =&gt; валюта
  * результата ) )</pre> <p></p><div class="note"> <b>Примечание</b>. С версии 15.0.6 ключ
  * RESULT_PRICE заполняется данными и в том случае, когда использованы
  * обработчики события <a
  * href="http://dev.1c-bitrix.ru/api_help/catalog/events/ongetoptimalprice.php">OnGetOptimalPrice</a>. Параметры
  * заданные методами <a
  * href="http://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogproduct/setusedcurrency.php">CCatalogProduct::setUsedCurrency</a>
  * и <a
  * href="http://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogproduct/setpricevatincludemode.php">CCatalogProduct::setPriceVatIncludeMode</a>
  * при этом учитываются, параметры заданные методом <a
  * href="http://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogproduct/setusediscount.php">CCatalogProduct::setUseDiscount</a>
  * - нет. </div> <p></p><div class="note"> <b>Обратите внимание, что</b> <i>DISCOUNT_PRICE</i> это
  * минимальная цена в <b>базовой валюте</b>. Чтобы перевести эту цену в
  * валюту товара, необходимо: <pre class="syntax">array( $baseCurrency =
  * CCurrency::GetBaseCurrency(); $arPrice["DISCOUNT_PRICE"] = CCurrencyRates::ConvertCurrency($arPrice['DISCOUNT_PRICE'],
  * $baseCurrency, $arPrice["PRICE"]["CURRENCY"]); )</pre> </div> <a name="examples"></a>
  *
  * <h4>Example</h4> 
  * <pre>
  * &lt;?
  * $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER-&gt;GetUserGroupArray(), $renewal);
  * if (!$arPrice || count($arPrice) &lt;= 0)
  * {
  *     if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $USER-&gt;GetUserGroupArray()))
  *     {
  *         $quantity = $nearestQuantity;
  *         $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER-&gt;GetUserGroupArray(), $renewal);
  *     }
  * }
  * echo "&lt;pre&gt;";
  * print_r($arPrice);
  * echo "&lt;/pre&gt;";
  * ?&gt;
  * </pre>
  *
  *
  * @static
  * @link http://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogproduct/ccatalogproduct__getoptimalprice.7c16046d.php
  * @author Bitrix
  */
 public static function GetOptimalPrice($intProductID, $quantity = 1, $arUserGroups = array(), $renewal = "N", $arPrices = array(), $siteID = false, $arDiscountCoupons = false)
 {
     static $eventOnGetExists = null;
     static $eventOnResultExists = null;
     global $APPLICATION;
     if ($eventOnGetExists === true || $eventOnGetExists === null) {
         foreach (GetModuleEvents('catalog', 'OnGetOptimalPrice', true) as $arEvent) {
             $eventOnGetExists = true;
             $mxResult = ExecuteModuleEventEx($arEvent, array($intProductID, $quantity, $arUserGroups, $renewal, $arPrices, $siteID, $arDiscountCoupons));
             if ($mxResult !== true) {
                 self::updateUserHandlerOptimalPrice($mxResult);
                 return $mxResult;
             }
         }
         if ($eventOnGetExists === null) {
             $eventOnGetExists = false;
         }
     }
     $intProductID = (int) $intProductID;
     if ($intProductID <= 0) {
         $APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_PRODUCT_ID_ABSENT"), "NO_PRODUCT_ID");
         return false;
     }
     $quantity = (double) $quantity;
     if ($quantity <= 0) {
         $APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_QUANTITY_ABSENT"), "NO_QUANTITY");
         return false;
     }
     if (!is_array($arUserGroups) && (int) $arUserGroups . '|' == (string) $arUserGroups . '|') {
         $arUserGroups = array((int) $arUserGroups);
     }
     if (!is_array($arUserGroups)) {
         $arUserGroups = array();
     }
     if (!in_array(2, $arUserGroups)) {
         $arUserGroups[] = 2;
     }
     $renewal = $renewal == 'Y' ? 'Y' : 'N';
     if ($siteID === false) {
         $siteID = SITE_ID;
     }
     $resultCurrency = CCurrency::GetBaseCurrency();
     if (empty($resultCurrency)) {
         $APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_NO_BASE_CURRENCY"), "NO_BASE_CURRENCY");
         return false;
     }
     if (self::$usedCurrency !== null) {
         $resultCurrency = self::$usedCurrency;
     }
     $intIBlockID = (int) CIBlockElement::GetIBlockByID($intProductID);
     if ($intIBlockID <= 0) {
         $APPLICATION->ThrowException(Loc::getMessage('BT_MOD_CATALOG_PROD_ERR_ELEMENT_ID_NOT_FOUND', array('#ID#' => $intProductID)), 'NO_ELEMENT');
         return false;
     }
     if (!isset($arPrices) || !is_array($arPrices)) {
         $arPrices = array();
     }
     if (empty($arPrices)) {
         $arPrices = array();
         $dbPriceList = CPrice::GetListEx(array(), array("PRODUCT_ID" => $intProductID, "GROUP_GROUP_ID" => $arUserGroups, "GROUP_BUY" => "Y", "+<=QUANTITY_FROM" => $quantity, "+>=QUANTITY_TO" => $quantity), false, false, array("ID", "CATALOG_GROUP_ID", "PRICE", "CURRENCY"));
         while ($arPriceList = $dbPriceList->Fetch()) {
             $arPriceList['ELEMENT_IBLOCK_ID'] = $intIBlockID;
             $arPrices[] = $arPriceList;
         }
         unset($arPriceList, $dbPriceList);
     } else {
         foreach ($arPrices as &$arOnePrice) {
             $arOnePrice['ELEMENT_IBLOCK_ID'] = $intIBlockID;
         }
         unset($arOnePrice);
     }
     if (empty($arPrices)) {
         return false;
     }
     $rsVAT = CCatalogProduct::GetVATInfo($intProductID);
     if ($arVAT = $rsVAT->Fetch()) {
         $arVAT['RATE'] = (double) $arVAT['RATE'] * 0.01;
     } else {
         $arVAT = array('RATE' => 0.0, 'VAT_INCLUDED' => 'N');
     }
     unset($rsVAT);
     if (self::getUseDiscount()) {
         if ($arDiscountCoupons === false) {
             $arDiscountCoupons = CCatalogDiscountCoupon::GetCoupons();
         }
     }
     //		$boolDiscountVat = ('N' != COption::GetOptionString('catalog', 'discount_vat', 'Y'));
     $boolDiscountVat = true;
     $minPrice = false;
     $basePrice = false;
     $arMinPrice = array();
     $arMinDiscounts = array();
     foreach ($arPrices as &$arPriceList) {
         $arPriceList['VAT_RATE'] = $arVAT['RATE'];
         $arPriceList['VAT_INCLUDED'] = $arVAT['VAT_INCLUDED'];
         $dblCurrentPrice = $arPriceList['PRICE'];
         if ($boolDiscountVat) {
             if ('N' == $arPriceList['VAT_INCLUDED']) {
                 $dblCurrentPrice *= 1 + $arPriceList['VAT_RATE'];
             }
         } else {
             if ('Y' == $arPriceList['VAT_INCLUDED']) {
                 $dblCurrentPrice /= 1 + $arPriceList['VAT_RATE'];
             }
         }
         if ($arPriceList['CURRENCY'] != $resultCurrency) {
             $dblCurrentPrice = CCurrencyRates::ConvertCurrency($arPriceList['PRICE'], $arPriceList['CURRENCY'], $resultCurrency);
         }
         $dblCurrentPrice = roundEx($dblCurrentPrice, CATALOG_VALUE_PRECISION);
         $arDiscounts = array();
         if (self::getUseDiscount()) {
             $arDiscounts = CCatalogDiscount::GetDiscount($intProductID, $intIBlockID, $arPriceList["CATALOG_GROUP_ID"], $arUserGroups, $renewal, $siteID, $arDiscountCoupons);
         }
         $result = CCatalogDiscount::applyDiscountList($dblCurrentPrice, $resultCurrency, $arDiscounts);
         if ($result === false) {
             return false;
         }
         if ($minPrice === false || $minPrice > $result['PRICE']) {
             $basePrice = $dblCurrentPrice;
             $minPrice = $result['PRICE'];
             $arMinPrice = $arPriceList;
             $arMinDiscounts = $result['DISCOUNT_LIST'];
         }
     }
     unset($arPriceList);
     if ($boolDiscountVat) {
         if (!self::$optimalPriceWithVat) {
             $minPrice /= 1 + $arMinPrice['VAT_RATE'];
             $basePrice /= 1 + $arMinPrice['VAT_RATE'];
             $minPrice = roundEx($minPrice, CATALOG_VALUE_PRECISION);
             $basePrice = roundEx($basePrice, CATALOG_VALUE_PRECISION);
         }
     } else {
         if (self::$optimalPriceWithVat) {
             $minPrice *= 1 + $arMinPrice['VAT_RATE'];
             $basePrice *= 1 + $arMinPrice['VAT_RATE'];
             $minPrice = roundEx($minPrice, CATALOG_VALUE_PRECISION);
             $basePrice = roundEx($basePrice, CATALOG_VALUE_PRECISION);
         }
     }
     $arResult = array('PRICE' => $arMinPrice, 'RESULT_PRICE' => array('BASE_PRICE' => $basePrice, 'DISCOUNT_PRICE' => $minPrice, 'DISCOUNT' => $basePrice - $minPrice, 'PERCENT' => $basePrice > 0 ? 100 * ($basePrice - $minPrice) / $basePrice : 0, 'CURRENCY' => $resultCurrency, 'VAT_RATE' => $arMinPrice['VAT_RATE'], 'VAT_INCLUDED' => self::$optimalPriceWithVat ? 'Y' : 'N'), 'DISCOUNT_PRICE' => $minPrice, 'DISCOUNT' => array(), 'DISCOUNT_LIST' => array());
     if (!empty($arMinDiscounts)) {
         reset($arMinDiscounts);
         $arResult['DISCOUNT'] = current($arMinDiscounts);
         $arResult['DISCOUNT_LIST'] = $arMinDiscounts;
     }
     if ($eventOnResultExists === true || $eventOnResultExists === null) {
         foreach (GetModuleEvents('catalog', 'OnGetOptimalPriceResult', true) as $arEvent) {
             $eventOnResultExists = true;
             if (ExecuteModuleEventEx($arEvent, array(&$arResult)) === false) {
                 return false;
             }
         }
         if ($eventOnResultExists === null) {
             $eventOnResultExists = false;
         }
     }
     return $arResult;
 }
Ejemplo n.º 6
0
/**
 * 
 *
 *
 *
 *
 * @param $I $D  Код товара. (ID элемента инфоблока, для которого запрашиваются
 * цены.)
 *
 *
 *
 * @param $filterQauntit $y = 0 Если значение больше 0, то выводится диапазон цен,
 * соответствующий этому количеству. Имеет смысл только при
 * расширенном режиме управления ценами.
 *
 *
 *
 * @param $arFilterTyp $e = array() Массив ID типов цен. Если не задан, то выбираются все типы цен,
 * которые может просматривать пользователь.
 *
 *
 *
 * @param $VAT_INCLUD $E = 'Y' (Y/N) НДС включён.
 *
 *
 *
 * @param $arCurrencyParam $s = array() Массив параметров для показа цен в одной валюте. Если в
 * переданном массиве заполнено поле CURRENCY_ID, то произойдет
 * конвертация цен в валюту CURRENCY_ID по текущему курсу. Необязательный
 * параметр.
 *
 *
 *
 * @return mixed <p></p><br><br>
 *
 * @static
 * @link http://dev.1c-bitrix.ru/api_help/catalog/functions/cataloggetpricetableex.php
 * @author Bitrix
 */
function CatalogGetPriceTableEx($ID, $filterQauntity = 0, $arFilterType = array(), $VAT_INCLUDE = 'Y', $arCurrencyParams = array())
{
	global $USER;
	$ID = intval($ID);
	if ($ID <= 0)
		return False;

	$filterQauntity = intval($filterQauntity);

	if (!is_array($arFilterType))
		$arFilterType = array($arFilterType);

	$boolConvert = false;
	$strCurrencyID = '';
	$arCurrencyList = array();
	if (is_array($arCurrencyParams) && !empty($arCurrencyParams) && !empty($arCurrencyParams['CURRENCY_ID']))
	{
		$boolConvert = true;
		$strCurrencyID = $arCurrencyParams['CURRENCY_ID'];
	}

	$arResult = array();
	$arResult["ROWS"] = array();
	$arResult["COLS"] = array();
	$arResult["MATRIX"] = array();
	$arResult["CAN_BUY"] = array();
	$arResult["AVAILABLE"] = "N";

	$cacheTime = CATALOG_CACHE_DEFAULT_TIME;
	if (defined("CATALOG_CACHE_TIME"))
		$cacheTime = intval(CATALOG_CACHE_TIME);

	$arUserGroups = $USER->GetUserGroupArray();

	$arPriceGroups = CCatalogGroup::GetGroupsPerms($arUserGroups, array());

	if (empty($arPriceGroups["view"]))
		return $arResult;

	$currentQuantity = -1;
	$rowsCnt = -1;

	$arFilter = array("PRODUCT_ID" => $ID);
	if ($filterQauntity > 0)
	{
		$arFilter["+<=QUANTITY_FROM"] = $filterQauntity;
		$arFilter["+>=QUANTITY_TO"] = $filterQauntity;
	}
	if (!empty($arFilterType))
	{
		$arTmp = array();
		foreach ($arPriceGroups["view"] as &$intOneGroup)
		{
			if (in_array($intOneGroup, $arFilterType))
				$arTmp[] = $intOneGroup;
		}
		if (isset($intOneGroup))
			unset($intOneGroup);

		if (empty($arTmp))
			return $arResult;

		$arFilter["CATALOG_GROUP_ID"] = $arTmp;
	}
	else
	{
		$arFilter["CATALOG_GROUP_ID"] = $arPriceGroups["view"];
	}

	$productQuantity = 0;
	$productQuantityTrace = "N";

	$dbRes = CCatalogProduct::GetVATInfo($ID);
	if ($arVatInfo = $dbRes->Fetch())
	{
		$fVatRate = floatval($arVatInfo['RATE'] * 0.01);
		$bVatIncluded = $arVatInfo['VAT_INCLUDED'] == 'Y';
	}
	else
	{
		$fVatRate = 0.00;
		$bVatIncluded = false;
	}

	$dbPrice = CPrice::GetListEx(
		array("QUANTITY_FROM" => "ASC", "QUANTITY_TO" => "ASC"),
		$arFilter,
		false,
		false,
		array("ID", "CATALOG_GROUP_ID", "PRICE", "CURRENCY", "QUANTITY_FROM", "QUANTITY_TO", "PRODUCT_QUANTITY", "PRODUCT_QUANTITY_TRACE", "PRODUCT_CAN_BUY_ZERO", "ELEMENT_IBLOCK_ID")
	);

	while ($arPrice = $dbPrice->Fetch())
	{
		if ($VAT_INCLUDE == 'N')
		{
			if ($bVatIncluded)
				$arPrice['PRICE'] /= (1 + $fVatRate);
		}
		else
		{
			if (!$bVatIncluded)
				$arPrice['PRICE'] *= (1 + $fVatRate);
		}

		$arPrice['VAT_RATE'] = $fVatRate;

		CCatalogDiscountSave::Disable();
		$arDiscounts = CCatalogDiscount::GetDiscount($ID, $arPrice["ELEMENT_IBLOCK_ID"], $arPrice["CATALOG_GROUP_ID"], $arUserGroups, "N", SITE_ID);
		CCatalogDiscountSave::Enable();

		$discountPrice = CCatalogProduct::CountPriceWithDiscount($arPrice["PRICE"], $arPrice["CURRENCY"], $arDiscounts);
		$arPrice["DISCOUNT_PRICE"] = $discountPrice;

		$productQuantity = $arPrice["PRODUCT_QUANTITY"];
		$productQuantityTrace = $arPrice["PRODUCT_QUANTITY_TRACE"];
		$productUseStoreFlag = $arPrice["PRODUCT_CAN_BUY_ZERO"];

		$arPrice["QUANTITY_FROM"] = DoubleVal($arPrice["QUANTITY_FROM"]);
		if ($currentQuantity != $arPrice["QUANTITY_FROM"])
		{
			$rowsCnt++;
			$arResult["ROWS"][$rowsCnt]["QUANTITY_FROM"] = $arPrice["QUANTITY_FROM"];
			$arResult["ROWS"][$rowsCnt]["QUANTITY_TO"] = DoubleVal($arPrice["QUANTITY_TO"]);
			$currentQuantity = $arPrice["QUANTITY_FROM"];
		}

		if ($boolConvert && $strCurrencyID != $arPrice["CURRENCY"])
		{
			$arResult["MATRIX"][intval($arPrice["CATALOG_GROUP_ID"])][$rowsCnt] = array(
				"ID" => $arPrice["ID"],
				"ORIG_PRICE" => $arPrice["PRICE"],
				"ORIG_DISCOUNT_PRICE" => $arPrice["DISCOUNT_PRICE"],
				"ORIG_CURRENCY" => $arPrice["CURRENCY"],
				"ORIG_VAT_RATE" => $arPrice["VAT_RATE"],
				'PRICE' => CCurrencyRates::ConvertCurrency($arPrice["PRICE"], $arPrice["CURRENCY"], $strCurrencyID),
				'DISCOUNT_PRICE' => CCurrencyRates::ConvertCurrency($arPrice["DISCOUNT_PRICE"], $arPrice["CURRENCY"], $strCurrencyID),
				'CURRENCY' => $strCurrencyID,
				'VAT_RATE' => CCurrencyRates::ConvertCurrency($arPrice["VAT_RATE"], $arPrice["CURRENCY"], $strCurrencyID),
			);
			$arCurrencyList[] = $arPrice["CURRENCY"];
		}
		else
		{
			$arResult["MATRIX"][intval($arPrice["CATALOG_GROUP_ID"])][$rowsCnt] = array(
				"ID" => $arPrice["ID"],
				"PRICE" => $arPrice["PRICE"],
				"DISCOUNT_PRICE" => $arPrice["DISCOUNT_PRICE"],
				"CURRENCY" => $arPrice["CURRENCY"],
				"VAT_RATE" => $arPrice["VAT_RATE"]
			);
		}
	}

	$colsCnt = -1;
	$arCatalogGroups = CCatalogGroup::GetListArray();
	foreach ($arCatalogGroups as $key => $value)
	{
		if (array_key_exists($key, $arResult["MATRIX"]))
			$arResult["COLS"][$value["ID"]] = $value;
	}

	$arResult["CAN_BUY"] = $arPriceGroups["buy"];
	$arResult["AVAILABLE"] = (($productUseStoreFlag == 'Y' || ($productQuantityTrace == "N" || $productQuantityTrace == "Y" && $productQuantity > 0)) ? "Y" : "N");

	if ($boolConvert)
	{
		if (!empty($arCurrencyList))
			$arCurrencyList[] = $strCurrencyID;
		$arResult['CURRENCY_LIST'] = $arCurrencyList;
	}

	return $arResult;
}
Ejemplo n.º 7
0
 /**
  * <p>Метод возвращает информацию о товаре из каталога.</p>
  *
  *
  *
  *
  * @param array $arParams  Ассоциативный массив параметров товара, ключами в котором
  * являются названия параметров, а значениями - соответствующие
  * значения: <ul> <li> <b>PRODUCT_ID</b> - идентификатор товара;</li> <li> <b>QUANTITY</b> -
  * количество товара;</li> <li> <b>USER_ID</b> - идентификатор пользователя;</li>
  * <li> <b>SITE_ID</b> - код сайта;</li> <li> <b>CHECK_QUANTITY</b> - (Y|N) флаг выполнения
  * проверки доступности для покупки указанного количества
  * товара;</li> <li> <b>CHECK_PRICE</b> - (Y|N) флаг возвращения информации о цене
  * товара (флаг использовать не нужно, если для товара установлена
  * особая цена);</li> <li> <b>CHECK_COUPONS</b> - (Y|N) флаг обработки купонов;</li> <li>
  * <b>RENEWAL</b> - (Y|N) флаг продления подписки на товар.</li> </ul>
  *
  *
  *
  * @return array <p>Метод возвращает ассоциативный массив параметров товара с
  * ключами:</p> <ul> <li> <b>NAME</b> - название товара;</li> <li> <b>CAN_BUY</b> - (Y|N) флаг
  * возможности купить товар;</li> <li> <b>DETAIL_PAGE_URL</b> - ссылка на страницу с
  * информацией о товаре;</li> <li> <b>BARCODE_MULTI</b> - Y|N) определяет каждый ли
  * экземпляр товара имеет собственный штрихкод;</li> <li> <b>WEIGHT</b> - вес
  * товара;</li> <li> <b>DIMENSIONS</b> - размеры товара (ширина, высота и длина);</li>
  * <li> <b>TYPE</b> - код, обозначающий принадлежность товара к комплектам.
  * Может быть пустым;</li> <li> <b>QUANTITY</b> - количество товара.</li> </ul> <p>Если
  * в массиве <i>arParams</i> указан <i>"CHECK_PRICE" =&gt; "Y"</i>, то дополнительно
  * будут возвращены следующие ключи:</p> <ul> <li> <b>PRICE</b> - цена;</li> <li>
  * <b>PRODUCT_PRICE_ID</b> - идентификатор цены товара;</li> <li> <b>CURRENCY</b> - валюта, в
  * которой задана цена;</li> <li> <b>DISCOUNT_PRICE</b> - величина скидки;</li> <li>
  * <b>NOTES</b> - особые заметки, например, тип цены;</li> <li> <b>VAT_RATE</b> -
  * величина налога на товар.</li> </ul> <br><br>
  *
  * @static
  * @link http://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogproductprovider/getproductdata.php
  * @author Bitrix
  */
 public static function GetProductData($arParams)
 {
     if (!is_set($arParams, "QUANTITY") || doubleval($arParams["QUANTITY"]) <= 0) {
         $arParams["QUANTITY"] = 0;
     }
     if (!is_set($arParams, "RENEWAL") || $arParams["RENEWAL"] != "Y") {
         $arParams["RENEWAL"] = "N";
     }
     if (!is_set($arParams, "USER_ID") || intval($arParams["USER_ID"]) <= 0) {
         $arParams["USER_ID"] = 0;
     }
     if (!is_set($arParams["SITE_ID"])) {
         $arParams["SITE_ID"] = false;
     }
     if (!is_set($arParams["CHECK_QUANTITY"]) || $arParams["CHECK_QUANTITY"] != "N") {
         $arParams["CHECK_QUANTITY"] = "Y";
     }
     if (!is_set($arParams["CHECK_PRICE"]) || $arParams["CHECK_PRICE"] != "N") {
         $arParams["CHECK_PRICE"] = "Y";
     }
     if (!array_key_exists('CHECK_COUPONS', $arParams) || 'N' != $arParams['CHECK_COUPONS']) {
         $arParams['CHECK_COUPONS'] = 'Y';
     }
     $arParams['BASKET_ID'] = (string) (isset($arParams['BASKET_ID']) ? $arParams['BASKET_ID'] : '0');
     $productID = (int) $arParams["PRODUCT_ID"];
     $quantity = doubleval($arParams["QUANTITY"]);
     $renewal = $arParams["RENEWAL"] == "Y" ? "Y" : "N";
     $intUserID = (int) $arParams["USER_ID"];
     if (0 > $intUserID) {
         $intUserID = 0;
     }
     $strSiteID = $arParams["SITE_ID"];
     global $USER;
     global $APPLICATION;
     $arResult = array();
     static $arUserCache = array();
     if (0 < $intUserID) {
         if (!isset($arUserCache[$intUserID])) {
             $by = 'ID';
             $order = 'DESC';
             $rsUsers = CUser::GetList($by, $order, array("ID_EQUAL_EXACT" => $intUserID), array('FIELDS' => array('ID')));
             if ($arUser = $rsUsers->Fetch()) {
                 $arUser['ID'] = intval($arUser['ID']);
                 $arUserCache[$arUser['ID']] = CUser::GetUserGroup($arUser['ID']);
             } else {
                 $intUserID = 0;
                 return $arResult;
             }
         }
         $dbIBlockElement = CIBlockElement::GetList(array(), array("ID" => $productID, "ACTIVE" => "Y", "ACTIVE_DATE" => "Y", "CHECK_PERMISSIONS" => "N"), false, false, array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL'));
         if (!($arProduct = $dbIBlockElement->GetNext())) {
             return $arResult;
         }
         if ('E' == CIBlock::GetArrayByID($arProduct['IBLOCK_ID'], "RIGHTS_MODE")) {
             $arUserRights = CIBlockElementRights::GetUserOperations($productID, $intUserID);
             if (empty($arUserRights)) {
                 return $arResult;
             } elseif (!is_array($arUserRights) || !array_key_exists('element_read', $arUserRights)) {
                 return $arResult;
             }
         } else {
             if ('R' > CIBlock::GetPermission($arProduct['IBLOCK_ID'], $intUserID)) {
                 return $arResult;
             }
         }
     } else {
         $dbIBlockElement = CIBlockElement::GetList(array(), array("ID" => $productID, "ACTIVE" => "Y", "ACTIVE_DATE" => "Y", "CHECK_PERMISSIONS" => "Y", "MIN_PERMISSION" => "R"), false, false, array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL'));
         if (!($arProduct = $dbIBlockElement->GetNext())) {
             return $arResult;
         }
     }
     $rsCatalogs = CCatalog::GetList(array(), array('IBLOCK_ID' => $arProduct["IBLOCK_ID"]), false, false, array('IBLOCK_ID', 'SUBSCRIPTION'));
     if (!($arCatalog = $rsCatalogs->Fetch())) {
         return $arResult;
     }
     if ('Y' == $arCatalog["SUBSCRIPTION"]) {
         $quantity = 1;
     }
     $dblQuantity = 0;
     $boolQuantity = false;
     $rsProducts = CCatalogProduct::GetList(array(), array('ID' => $productID), false, false, array('ID', 'CAN_BUY_ZERO', 'QUANTITY_TRACE', 'QUANTITY', 'WEIGHT', 'WIDTH', 'HEIGHT', 'LENGTH', 'BARCODE_MULTI', 'TYPE'));
     if ($arCatalogProduct = $rsProducts->Fetch()) {
         $dblQuantity = doubleval($arCatalogProduct["QUANTITY"]);
         $boolQuantity = 'Y' != $arCatalogProduct["CAN_BUY_ZERO"] && 'Y' == $arCatalogProduct["QUANTITY_TRACE"];
         if ($arParams["CHECK_QUANTITY"] == "Y" && $boolQuantity && 0 >= $dblQuantity) {
             $APPLICATION->ThrowException(Loc::getMessage("CATALOG_NO_QUANTITY_PRODUCT", array("#NAME#" => htmlspecialcharsbx($arProduct["~NAME"]))), "CATALOG_NO_QUANTITY_PRODUCT");
             return $arResult;
         }
     } else {
         $APPLICATION->ThrowException(Loc::getMessage("CATALOG_ERR_NO_PRODUCT"), "CATALOG_NO_QUANTITY_PRODUCT");
         return $arResult;
     }
     if ($arParams["CHECK_PRICE"] == "Y") {
         $strBasketProductID = $productID . '_' . $arParams['BASKET_ID'];
         $arCoupons = array();
         if (0 < $intUserID) {
             if ('Y' == $arParams['CHECK_COUPONS']) {
                 $arCoupons = CCatalogDiscountCoupon::GetCouponsByManage($intUserID);
             }
             CCatalogDiscountSave::SetDiscountUserID($intUserID);
         } else {
             if ('Y' == $arParams['CHECK_COUPONS']) {
                 $arCoupons = CCatalogDiscountCoupon::GetCoupons();
             }
         }
         $boolChangeCoupons = false;
         $arNewCoupons = array();
         if (!empty($arCoupons) && is_array($arCoupons) && !empty(self::$arOneTimeCoupons)) {
             foreach ($arCoupons as $key => $coupon) {
                 if (isset(self::$arOneTimeCoupons[$coupon])) {
                     if (self::$arOneTimeCoupons[$coupon] == $strBasketProductID) {
                         $boolChangeCoupons = true;
                         $arNewCoupons[] = $coupon;
                     } else {
                         unset($arCoupons[$key]);
                     }
                 }
             }
         }
         if ($boolChangeCoupons) {
             $arCoupons = $arNewCoupons;
         }
         $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, 0 < $intUserID ? $arUserCache[$intUserID] : $USER->GetUserGroupArray(), $renewal, array(), 0 < $intUserID ? $strSiteID : false, $arCoupons);
         if (empty($arPrice)) {
             if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, 0 < $intUserID ? $arUserCache[$intUserID] : $USER->GetUserGroupArray())) {
                 $quantity = $nearestQuantity;
                 $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, 0 < $intUserID ? $arUserCache[$intUserID] : $USER->GetUserGroupArray(), $renewal, array(), 0 < $intUserID ? $strSiteID : false, $arCoupons);
             }
         }
         if (empty($arPrice)) {
             if (0 < $intUserID) {
                 CCatalogDiscountSave::ClearDiscountUserID();
             }
             return $arResult;
         }
         $boolDiscountVat = 'N' != COption::GetOptionString('catalog', 'discount_vat', 'Y');
         $currentPrice = $arPrice["PRICE"]["PRICE"];
         $currentDiscount = 0.0;
         $arPrice['PRICE']['ORIG_VAT_INCLUDED'] = $arPrice['PRICE']['VAT_INCLUDED'];
         if ($boolDiscountVat) {
             if ('N' == $arPrice['PRICE']['VAT_INCLUDED']) {
                 $currentPrice *= 1 + $arPrice['PRICE']['VAT_RATE'];
                 $arPrice['PRICE']['VAT_INCLUDED'] = 'Y';
             }
         } else {
             if ('Y' == $arPrice['PRICE']['VAT_INCLUDED']) {
                 $currentPrice /= 1 + $arPrice['PRICE']['VAT_RATE'];
                 $arPrice['PRICE']['VAT_INCLUDED'] = 'N';
             }
         }
         $arDiscountList = array();
         if (!empty($arPrice["DISCOUNT_LIST"])) {
             $dblStartPrice = $currentPrice;
             foreach ($arPrice["DISCOUNT_LIST"] as &$arOneDiscount) {
                 switch ($arOneDiscount['VALUE_TYPE']) {
                     case CCatalogDiscount::TYPE_FIX:
                         if ($arOneDiscount['CURRENCY'] == $arPrice["PRICE"]["CURRENCY"]) {
                             $currentDiscount = $arOneDiscount['VALUE'];
                         } else {
                             $currentDiscount = CCurrencyRates::ConvertCurrency($arOneDiscount["VALUE"], $arOneDiscount["CURRENCY"], $arPrice["PRICE"]["CURRENCY"]);
                         }
                         $currentPrice = $currentPrice - $currentDiscount;
                         break;
                     case CCatalogDiscount::TYPE_PERCENT:
                         $currentDiscount = $currentPrice * $arOneDiscount["VALUE"] / 100.0;
                         if (0 < $arOneDiscount['MAX_DISCOUNT']) {
                             if ($arOneDiscount['CURRENCY'] == $arPrice["PRICE"]["CURRENCY"]) {
                                 $dblMaxDiscount = $arOneDiscount['MAX_DISCOUNT'];
                             } else {
                                 $dblMaxDiscount = CCurrencyRates::ConvertCurrency($arOneDiscount['MAX_DISCOUNT'], $arOneDiscount["CURRENCY"], $arPrice["PRICE"]["CURRENCY"]);
                             }
                             if ($currentDiscount > $dblMaxDiscount) {
                                 $currentDiscount = $dblMaxDiscount;
                             }
                         }
                         $currentPrice = $currentPrice - $currentDiscount;
                         break;
                     case CCatalogDiscount::TYPE_SALE:
                         if ($arOneDiscount['CURRENCY'] == $arPrice["PRICE"]["CURRENCY"]) {
                             $currentPrice = $arOneDiscount['VALUE'];
                         } else {
                             $currentPrice = CCurrencyRates::ConvertCurrency($arOneDiscount['VALUE'], $arOneDiscount["CURRENCY"], $arPrice["PRICE"]["CURRENCY"]);
                         }
                         break;
                 }
                 $arOneList = array('ID' => $arOneDiscount['ID'], 'NAME' => $arOneDiscount['NAME'], 'COUPON' => '', 'COUPON_TYPE' => '', 'MODULE_ID' => 'catalog', 'TYPE' => $arOneDiscount['TYPE'], 'VALUE' => $arOneDiscount['VALUE'], 'VALUE_TYPE' => $arOneDiscount['VALUE_TYPE'], 'CURRENCY' => $arOneDiscount['CURRENCY'], 'HANDLERS' => isset($arOneDiscount['HANDLERS']) ? $arOneDiscount['HANDLERS'] : array());
                 if ($arOneDiscount['COUPON']) {
                     $arOneList['COUPON'] = $arOneDiscount['COUPON'];
                     $arOneList['COUPON_TYPE'] = $arOneDiscount['COUPON_ONE_TIME'];
                     if ($arOneDiscount['COUPON_ONE_TIME'] == CCatalogDiscountCoupon::TYPE_ONE_TIME) {
                         self::$arOneTimeCoupons[$arOneDiscount['COUPON']] = $strBasketProductID;
                     }
                 }
                 $arDiscountList[] = $arOneList;
             }
             if (isset($arOneDiscount)) {
                 unset($arOneDiscount);
             }
             $currentDiscount = $dblStartPrice - $currentPrice;
         }
         if (empty($arPrice["PRICE"]["CATALOG_GROUP_NAME"])) {
             if (!empty($arPrice["PRICE"]["CATALOG_GROUP_ID"])) {
                 $rsCatGroups = CCatalogGroup::GetListEx(array(), array('ID' => $arPrice["PRICE"]["CATALOG_GROUP_ID"]), false, false, array('ID', 'NAME', 'NAME_LANG'));
                 if ($arCatGroup = $rsCatGroups->Fetch()) {
                     $arPrice["PRICE"]["CATALOG_GROUP_NAME"] = !empty($arCatGroup['NAME_LANG']) ? $arCatGroup['NAME_LANG'] : $arCatGroup['NAME'];
                 }
             }
         }
         if (!$boolDiscountVat) {
             $currentPrice *= 1 + $arPrice['PRICE']['VAT_RATE'];
             $currentDiscount *= 1 + $arPrice['PRICE']['VAT_RATE'];
             $arPrice['PRICE']['VAT_INCLUDED'] = 'Y';
         }
     } else {
         $rsVAT = CCatalogProduct::GetVATInfo($productID);
         if ($arVAT = $rsVAT->Fetch()) {
             $vatRate = doubleval($arVAT['RATE'] * 0.01);
         } else {
             $vatRate = 0.0;
         }
     }
     $arResult = array("NAME" => $arProduct["~NAME"], "CAN_BUY" => "Y", "DETAIL_PAGE_URL" => $arProduct['~DETAIL_PAGE_URL'], "BARCODE_MULTI" => $arCatalogProduct["BARCODE_MULTI"], "WEIGHT" => floatval($arCatalogProduct['WEIGHT']), "DIMENSIONS" => serialize(array("WIDTH" => $arCatalogProduct["WIDTH"], "HEIGHT" => $arCatalogProduct["HEIGHT"], "LENGTH" => $arCatalogProduct["LENGTH"])), "TYPE" => $arCatalogProduct["TYPE"] == CCatalogProduct::TYPE_SET ? CCatalogProductSet::TYPE_SET : NULL);
     if ($arParams["CHECK_QUANTITY"] == "Y") {
         $arResult["QUANTITY"] = $boolQuantity && $dblQuantity < $quantity ? $dblQuantity : $quantity;
     } else {
         $arResult["QUANTITY"] = $arParams["QUANTITY"];
     }
     if ($arParams["CHECK_QUANTITY"] == "Y" && $boolQuantity && $dblQuantity < $quantity) {
         $APPLICATION->ThrowException(Loc::getMessage("CATALOG_QUANTITY_NOT_ENOGH", array("#NAME#" => htmlspecialcharsbx($arProduct["~NAME"]), "#CATALOG_QUANTITY#" => $arCatalogProduct["QUANTITY"], "#QUANTITY#" => $quantity)), "CATALOG_QUANTITY_NOT_ENOGH");
     }
     if (0 < $intUserID) {
         CCatalogDiscountSave::ClearDiscountUserID();
     }
     if ($arParams["CHECK_PRICE"] == "Y") {
         $arResult = array_merge($arResult, array("PRODUCT_PRICE_ID" => $arPrice["PRICE"]["ID"], "PRICE" => $currentPrice, "CURRENCY" => $arPrice["PRICE"]["CURRENCY"], "DISCOUNT_PRICE" => $currentDiscount, "NOTES" => $arPrice["PRICE"]["CATALOG_GROUP_NAME"], "VAT_RATE" => $arPrice["PRICE"]["VAT_RATE"], "DISCOUNT_VALUE" => 0, "DISCOUNT_NAME" => "", "DISCOUNT_COUPON" => "", "DISCOUNT_LIST" => array()));
         if (!empty($arDiscountList)) {
             $arResult['DISCOUNT_LIST'] = $arDiscountList;
             $arResult["DISCOUNT_VALUE"] = 100 * $currentDiscount / ($currentDiscount + $currentPrice) . "%";
             $arResult["DISCOUNT_NAME"] = "[" . $arPrice["DISCOUNT"]["ID"] . "] " . $arPrice["DISCOUNT"]["NAME"];
             if (!empty($arPrice["DISCOUNT"]["COUPON"])) {
                 $arResult["DISCOUNT_COUPON"] = $arPrice["DISCOUNT"]["COUPON"];
             }
         }
     } else {
         $arResult["VAT_RATE"] = $vatRate;
     }
     return $arResult;
 }