/** * @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; }
/** * <p>Метод возвращает параметры наименьшей цены товара productID в количестве quantity для посетителя, входящего в группы пользователей arUserGroups.</p> * * * * * @param int $productID Код товара. * * * * @param $int Приобретаемое количество. * * * * @param quantit $y = 1[ массив групп, которым принадлежит пользователь. Для текущего * пользователя он возвращается методом $USER->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" => * массив_параметров_минимальной_цены, "DISCOUNT_PRICE" => * минимальная_цена_в_базовой_валюте, "DISCOUNT" => * массив_параметров_максимальной_доступной_скидки )</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> * <? * $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER->GetUserGroupArray(), $renewal); * if (!$arPrice || count($arPrice) <= 0) * { * if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $USER->GetUserGroupArray())) * { * $quantity = $nearestQuantity; * $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER->GetUserGroupArray(), $renewal); * } * } * echo "<pre>"; * print_r($arPrice); * echo "</pre>"; * ?> * </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; }
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; }
/** * <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->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" => * массив_параметров_минимальной_цены, "DISCOUNT_PRICE" => * минимальная_цена_в_базовой_валюте, "DISCOUNT" => * массив_параметров_первой_из_примененных_скидок_торгового_каталога, * "DISCOUNT_LIST" => * массив_скидок_действующих_на_товар_в_порядке_применения, "RESULT_PRICE" * => array( "BASE_PRICE" => полная (без скидок) цена товара, "DISCOUNT_PRICE" => * цена со скидками, "DISCOUNT" => итоговая скидка (разница между BASE_PRICE и * DISCOUNT_PRICE) "PERCENT" => итоговая скидка в процентах "CURRENCY" => валюта * результата ) )</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> * <? * $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER->GetUserGroupArray(), $renewal); * if (!$arPrice || count($arPrice) <= 0) * { * if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $USER->GetUserGroupArray())) * { * $quantity = $nearestQuantity; * $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $USER->GetUserGroupArray(), $renewal); * } * } * echo "<pre>"; * print_r($arPrice); * echo "</pre>"; * ?> * </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; }
/** * * * * * * @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; }
/** * <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" => "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; }