<?php
namespace App\BitrixCatalogProviders;
use Bitrix\Catalog;
use Bitrix\Catalog\Product\Price;
use Bitrix\Currency;
use Bitrix\Iblock;
use Bitrix\Main;
use Bitrix\Main\Localization\Loc;
use Bitrix\Sale;
use Bitrix\Sale\DiscountCouponsManager;
use CCatalogDiscount;
use CCatalogDiscountSave;
use CCatalogMeasure;
use CCatalogProduct;
use CCatalogProductProvider;
use CIBlockElement;
use CModule;
use CSaleLang;
use CUser;
if (!CModule::IncludeModule("sale") || !CModule::IncludeModule("catalog")) {
return false;
}
IncludeModuleLangFile(__FILE__);
class IdolCatalogProductProvider extends CCatalogProductProvider
{
/**
* @param array $arParams
* @return array|false
*/
public static function GetProductData($arParams)
{
$adminSection = (defined('ADMIN_SECTION') && ADMIN_SECTION === true);
$useSaleDiscountOnly = CCatalogDiscount::isUsedSaleDiscountOnly();
if (!isset($arParams['QUANTITY']) || (float)$arParams['QUANTITY'] <= 0) {
$arParams['QUANTITY'] = 0;
}
if ($useSaleDiscountOnly && !isset($arParams['CHECK_DISCOUNT'])) {
$arParams['CHECK_DISCOUNT'] = 'N';
}
$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_DISCOUNT'] = (isset($arParams['CHECK_DISCOUNT']) && $arParams['CHECK_DISCOUNT'] == 'N' ? 'N' : 'Y');
$arParams['CHECK_COUPONS'] = (isset($arParams['CHECK_COUPONS']) && $arParams['CHECK_COUPONS'] == 'N' ? 'N' : 'Y');
if (!$useSaleDiscountOnly) {
if ($arParams['CHECK_DISCOUNT'] == 'N') {
$arParams['CHECK_COUPONS'] = 'N';
}
}
$arParams['AVAILABLE_QUANTITY'] = (isset($arParams['AVAILABLE_QUANTITY']) && $arParams['AVAILABLE_QUANTITY'] == 'Y' ? 'Y' : 'N');
$arParams['SELECT_QUANTITY_TRACE'] = (isset($arParams['SELECT_QUANTITY_TRACE']) && $arParams['SELECT_QUANTITY_TRACE'] == 'Y' ? 'Y' : 'N');
$arParams['SELECT_CHECK_MAX_QUANTITY'] = (isset($arParams['SELECT_CHECK_MAX_QUANTITY']) && $arParams['SELECT_CHECK_MAX_QUANTITY'] == '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 = (float)$arParams['QUANTITY'];
$intUserID = (int)$arParams['USER_ID'];
global $USER, $APPLICATION;
$emptyResult = [];
if ($adminSection) {
if (!$userGroups = static::getHitCache(self::CACHE_USER_GROUPS, $intUserID)) {
$userGroups = self::getUserGroups($intUserID);
static::setHitCache(self::CACHE_USER_GROUPS, $intUserID, $userGroups);
}
if (empty($userGroups)) {
return $emptyResult;
}
} else {
//TODO: fix for crm
$userGroups = [2];
if (isset($USER) && $USER instanceof CUser) {
$userGroups = $USER->GetUserGroupArray();
}
}
if (!$arProduct = static::getHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID)) {
$elementFilter = [
'ID' => $productID,
'ACTIVE' => 'Y',
'ACTIVE_DATE' => 'Y',
'CHECK_PERMISSIONS' => 'Y',
'MIN_PERMISSION' => 'R',
];
if ($adminSection) {
$elementFilter['PERMISSIONS_BY'] = $intUserID;
}
$iterator = CIBlockElement::GetList(
[],
$elementFilter,
false,
false,
['ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL', 'XML_ID']
);
if ($arProduct = $iterator->GetNext()) {
static::setHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID, $arProduct);
}
unset($dbIBlockElement, $elementFilter);
}
if (empty($arProduct) || !is_array($arProduct)) {
return $emptyResult;
}
if (!isset(self::$catalogList[$arProduct['IBLOCK_ID']])) {
self::$catalogList[$arProduct['IBLOCK_ID']] = Catalog\CatalogIblockTable::getList([
'select' => ['IBLOCK_ID', 'SUBSCRIPTION', 'PRODUCT_IBLOCK_ID', 'CATALOG_XML_ID' => 'IBLOCK.XML_ID'],
'filter' => ['=IBLOCK_ID' => $arProduct['IBLOCK_ID']],
])->fetch();
}
if (empty(self::$catalogList[$arProduct['IBLOCK_ID']]) || !is_array(self::$catalogList[$arProduct['IBLOCK_ID']])) {
return $emptyResult;
}
if (self::$catalogList[$arProduct['IBLOCK_ID']]['SUBSCRIPTION'] == 'Y') {
$quantity = 1;
}
if (self::$catalogList[$arProduct['IBLOCK_ID']]['PRODUCT_IBLOCK_ID'] > 0) {
if (!static::checkParentActivity($arProduct['ID'], $arProduct['IBLOCK_ID'])) {
return $emptyResult;
}
}
if (!$arCatalogProduct = static::getHitCache(self::CACHE_PRODUCT, $productID)) {
$select = ['ID', 'TYPE', 'AVAILABLE',
'QUANTITY', 'QUANTITY_TRACE', 'CAN_BUY_ZERO',
'QUANTITY_RESERVED',
'WEIGHT', 'WIDTH', 'HEIGHT', 'LENGTH',
'BARCODE_MULTI',
'MEASURE',
];
$select = array_merge($select, Catalog\Product\SystemField::getProviderSelectFields());
$arCatalogProduct = Catalog\ProductTable::getList([
'select' => $select,
'filter' => ['=ID' => $productID],
])->fetch();
if (!empty($arCatalogProduct)) {
$arCatalogProduct['ID'] = (int)$arCatalogProduct['ID'];
$arCatalogProduct['TYPE'] = (int)$arCatalogProduct['TYPE'];
$arCatalogProduct['QUANTITY'] = (float)$arCatalogProduct['QUANTITY'];
$arCatalogProduct['QUANTITY_RESERVED'] = (float)$arCatalogProduct['QUANTITY_RESERVED'];
Catalog\Product\SystemField::prepareRow($arCatalogProduct, Catalog\Product\SystemField::OPERATION_PROVIDER);
static::setHitCache(self::CACHE_PRODUCT, $productID, $arCatalogProduct);
}
}
if (empty($arCatalogProduct) || !is_array($arCatalogProduct)) {
$APPLICATION->ThrowException(Loc::getMessage("CATALOG_ERR_NO_PRODUCT"), "CATALOG_NO_QUANTITY_PRODUCT");
return $emptyResult;
}
if (
($arCatalogProduct['TYPE'] == Catalog\ProductTable::TYPE_SKU || $arCatalogProduct['TYPE'] == Catalog\ProductTable::TYPE_EMPTY_SKU)
&& (string)Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') != 'Y'
) {
$APPLICATION->ThrowException(Loc::getMessage("CATALOG_ERR_SKU_PRODUCT"), 'CATALOG_SKU_PRODUCT');
return $emptyResult;
}
if (
$arParams["CHECK_QUANTITY"] == "Y"
&& $arCatalogProduct['AVAILABLE'] != Catalog\ProductTable::STATUS_YES
) {
$APPLICATION->ThrowException(
Loc::getMessage("CATALOG_NO_QUANTITY_PRODUCT", ["#NAME#" => $arProduct["NAME"]]),
"CATALOG_NO_QUANTITY_PRODUCT"
);
return $emptyResult;
}
if ($arCatalogProduct['TYPE'] == Catalog\ProductTable::TYPE_SET) {
static::$errors = [];
if (!static::checkProductSet($productID)) {
$APPLICATION->ThrowException(implode(', ', static::$errors), 'NO_PRODUCT');
static::$errors = [];
return $emptyResult;
}
}
if ($arCatalogProduct['TYPE'] == Catalog\ProductTable::TYPE_OFFER) {
if (mb_strpos($arProduct["~XML_ID"], '#') === false) {
$parent = \CCatalogSku::GetProductInfo($arProduct['ID'], $arProduct['IBLOCK_ID']);
if (!empty($parent)) {
$parentIterator = Iblock\ElementTable::getList([
'select' => ['ID', 'XML_ID'],
'filter' => ['=ID' => $parent['ID']],
]);
$parentData = $parentIterator->fetch();
if (!empty($parentData)) {
$arProduct['~XML_ID'] = $parentData['XML_ID'] . '#' . $arProduct['~XML_ID'];
}
unset($parentData, $parentIterator);
}
unset($parent);
}
}
$dblQuantity = $arCatalogProduct['QUANTITY'];
$quantityLimited = ($arCatalogProduct['QUANTITY_TRACE'] == Catalog\ProductTable::STATUS_YES
&& $arCatalogProduct['CAN_BUY_ZERO'] == Catalog\ProductTable::STATUS_NO);
$quantityLimitExceeded = ($quantityLimited && $dblQuantity < $quantity);
$arCatalogProduct['MEASURE'] = (int)$arCatalogProduct['MEASURE'];
$arCatalogProduct['MEASURE_NAME'] = '';
$arCatalogProduct['MEASURE_CODE'] = 0;
if ($arCatalogProduct['MEASURE'] <= 0) {
$arMeasure = CCatalogMeasure::getDefaultMeasure(true, true);
$arCatalogProduct['MEASURE_NAME'] = $arMeasure['~SYMBOL_RUS'];
$arCatalogProduct['MEASURE_CODE'] = $arMeasure['CODE'];
} else {
$rsMeasures = CCatalogMeasure::getList(
[],
['ID' => $arCatalogProduct['MEASURE']],
false,
false,
['ID', 'SYMBOL_RUS', 'CODE']
);
if ($arMeasure = $rsMeasures->Fetch()) {
$arCatalogProduct['MEASURE_NAME'] = $arMeasure['SYMBOL_RUS'];
$arCatalogProduct['MEASURE_CODE'] = $arMeasure['CODE'];
}
}
$arResult = [
// "NAME" => $arProduct["~NAME"],
"CAN_BUY" => "Y",
"DETAIL_PAGE_URL" => $arProduct['~DETAIL_PAGE_URL'],
"BARCODE_MULTI" => $arCatalogProduct["BARCODE_MULTI"],
"WEIGHT" => (float)$arCatalogProduct['WEIGHT'],
"DIMENSIONS" => serialize([
"WIDTH" => $arCatalogProduct["WIDTH"],
"HEIGHT" => $arCatalogProduct["HEIGHT"],
"LENGTH" => $arCatalogProduct["LENGTH"],
]),
"VAT_INCLUDED" => "Y",
"MEASURE_ID" => $arCatalogProduct['MEASURE'],
"MEASURE_NAME" => $arCatalogProduct['MEASURE_NAME'],
"MEASURE_CODE" => $arCatalogProduct['MEASURE_CODE'],
"CATALOG_XML_ID" => self::$catalogList[$arProduct['IBLOCK_ID']]['CATALOG_XML_ID'],
"PRODUCT_XML_ID" => $arProduct['~XML_ID'],
];
switch ($arCatalogProduct['TYPE']) {
case Catalog\ProductTable::TYPE_SET:
$arResult['TYPE'] = Sale\BasketItem::TYPE_SET;
break;
case Catalog\ProductTable::TYPE_SERVICE:
$arResult['TYPE'] = Sale\BasketItem::TYPE_SERVICE;
break;
default:
$arResult['TYPE'] = null;
break;
}
foreach (Catalog\Product\SystemField::getProviderSelectFields() as $index => $value) {
$field = is_string($index) ? $index : $value;
$arResult[$field] = $arCatalogProduct[$field];
}
if ($arParams['SELECT_QUANTITY_TRACE'] == "Y") {
$arResult["QUANTITY_TRACE"] = $arCatalogProduct["QUANTITY_TRACE"];
}
if ($arParams['SELECT_CHECK_MAX_QUANTITY'] == 'Y') {
$arResult['CHECK_MAX_QUANTITY'] = ($quantityLimited ? 'Y' : 'N');
}
if ($arParams["CHECK_QUANTITY"] == "Y") {
$arResult["QUANTITY"] = ($quantityLimitExceeded ? $dblQuantity : $quantity);
if ($quantityLimitExceeded) {
$APPLICATION->ThrowException(
Loc::getMessage(
"CATALOG_QUANTITY_NOT_ENOGH",
[
"#NAME#" => $arProduct["NAME"],
"#CATALOG_QUANTITY#" => $dblQuantity,
"#QUANTITY#" => $quantity,
'#MEASURE_NAME#' => $arCatalogProduct['MEASURE_NAME'],
]
),
"CATALOG_QUANTITY_NOT_ENOGH"
);
}
} else {
$arResult["QUANTITY"] = $arParams["QUANTITY"];
}
if ($arParams["AVAILABLE_QUANTITY"] == "Y") {
$arResult["AVAILABLE_QUANTITY"] = ($quantityLimitExceeded ? $dblQuantity : $quantity);
}
if ($arParams["CHECK_PRICE"] == "Y") {
$productHash = [
'MODULE_ID' => ($useSaleDiscountOnly ? 'sale' : 'catalog'),
'PRODUCT_ID' => $productID,
'BASKET_ID' => $arParams['BASKET_ID'],
];
$arCoupons = [];
if ($arParams['CHECK_COUPONS'] == 'Y') {
if ($useSaleDiscountOnly) {
$arCoupons = DiscountCouponsManager::getForApply(['MODULE_ID' => 'sale'], $productHash, true);
} else {
$arCoupons = DiscountCouponsManager::getForApply(['MODULE_ID' => 'catalog'], $productHash, true);
}
if (!empty($arCoupons)) {
$arCoupons = array_keys($arCoupons);
}
}
if ($adminSection) {
if ($intUserID > 0) {
CCatalogDiscountSave::SetDiscountUserID($intUserID);
} else {
CCatalogDiscountSave::Disable();
}
}
Price\Calculation::pushConfig();
Price\Calculation::setConfig([
'CURRENCY' => $arParams['CURRENCY'],
'PRECISION' => (int)Main\Config\Option::get('sale', 'value_precision'),
'USE_DISCOUNTS' => $arParams['CHECK_DISCOUNT'] == 'Y',
'RESULT_WITH_VAT' => true,
'RESULT_MODE' => Catalog\Product\Price\Calculation::RESULT_MODE_RAW,
]);
$arPrice = CCatalogProduct::GetOptimalPrice(
$productID,
$quantity,
$userGroups,
$arParams['RENEWAL'],
[],
($adminSection ? $strSiteID : false),
$arCoupons
);
if (empty($arPrice)) {
if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $userGroups)) {
$quantity = $nearestQuantity;
$arPrice = CCatalogProduct::GetOptimalPrice(
$productID,
$quantity,
$userGroups,
$arParams['RENEWAL'],
[],
($adminSection ? $strSiteID : false),
$arCoupons
);
}
}
Price\Calculation::popConfig();
unset($userGroups);
if ($adminSection) {
if ($intUserID > 0) {
CCatalogDiscountSave::ClearDiscountUserID();
} else {
CCatalogDiscountSave::Enable();
}
}
if (empty($arPrice)) {
return $emptyResult;
}
$arDiscountList = [];
if (empty($arPrice['DISCOUNT_LIST']) && !empty($arPrice['DISCOUNT']) && is_array($arPrice['DISCOUNT'])) {
$arPrice['DISCOUNT_LIST'] = [$arPrice['DISCOUNT']];
}
if (!empty($arPrice['DISCOUNT_LIST'])) {
$appliedCoupons = [];
foreach ($arPrice['DISCOUNT_LIST'] as &$arOneDiscount) {
$arDiscountList[] = CCatalogDiscount::getDiscountDescription($arOneDiscount);
if (!empty($arOneDiscount['COUPON'])) {
$appliedCoupons[] = $arOneDiscount['COUPON'];
}
}
unset($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);
}
}
$arResult['PRODUCT_PRICE_ID'] = $arPrice['RESULT_PRICE']['ID'];
$arResult['NOTES'] = $arPrice['PRICE']['CATALOG_GROUP_NAME'];
$arResult['VAT_RATE'] = $arPrice['RESULT_PRICE']['VAT_RATE'];
$arResult['VAT_INCLUDED'] = $arPrice['RESULT_PRICE']['VAT_INCLUDED'];
$arResult['DISCOUNT_NAME'] = null;
$arResult['DISCOUNT_COUPON'] = null;
$arResult['DISCOUNT_VALUE'] = null;
$arResult['DISCOUNT_LIST'] = [];
if (empty($arPrice['RESULT_PRICE']) || !is_array($arPrice['RESULT_PRICE'])) {
$arPrice['RESULT_PRICE'] = CCatalogDiscount::calculateDiscountList($arPrice['PRICE'], $arParams['CURRENCY'], $arDiscountList, true);
}
$arResult['PRICE_TYPE_ID'] = $arPrice['RESULT_PRICE']['PRICE_TYPE_ID'];
$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 ($arParams['CHECK_DISCOUNT'] == 'Y') {
if (isset($arPrice['RESULT_PRICE']['PERCENT'])) {
$arResult['DISCOUNT_VALUE'] = ($arPrice['RESULT_PRICE']['PERCENT'] > 0 ? $arPrice['RESULT_PRICE']['PERCENT'] . '%' : null);
}
}
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'] = [$arPrice['DISCOUNT']];
}
}
} else {
$vatRate = null;
if (!$arVAT = static::getHitCache(self::CACHE_VAT, $productID)) {
$arVat = CCatalogProduct::GetVATDataByID($productID);
if (!empty($arVAT)) {
static::setHitCache(self::CACHE_VAT, $productID, $arVAT);
}
}
if (isset($arVAT) && is_array($arVAT)) {
if ($arVat['EXCLUDE_VAT'] === 'N') {
$vatRate = $arVAT['RATE'] * 0.01;
}
}
$arResult['VAT_RATE'] = $vatRate;
}
return $arResult;
}
/**
* @param array $arParams
* @return array|false
*/
public static function OrderProduct($arParams)
{
$adminSection = (defined('ADMIN_SECTION') && ADMIN_SECTION === true);
$useSaleDiscountOnly = CCatalogDiscount::isUsedSaleDiscountOnly();
if ($useSaleDiscountOnly && !isset($arParams['CHECK_DISCOUNT'])) {
$arParams['CHECK_DISCOUNT'] = 'N';
}
$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_DISCOUNT'] = (isset($arParams['CHECK_DISCOUNT']) && $arParams['CHECK_DISCOUNT'] == 'N' ? 'N' : 'Y');
$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['BASKET_ID'] = (string)(isset($arParams['BASKET_ID']) ? $arParams['BASKET_ID'] : '0');
$arParams['CURRENCY'] = (isset($arParams['CURRENCY']) ? Currency\CurrencyManager::checkCurrencyID($arParams['CURRENCY']) : false);
if ($arParams['CURRENCY'] === false) {
$arParams['CURRENCY'] = CSaleLang::GetLangCurrency($strSiteID ? $strSiteID : SITE_ID);
}
global $USER;
$productID = (int)$arParams['PRODUCT_ID'];
$quantity = (float)$arParams['QUANTITY'];
$intUserID = (int)$arParams['USER_ID'];
$arResult = [];
if ($adminSection) {
if ($intUserID == 0) {
return $arResult;
}
if (!$userGroups = static::getHitCache(self::CACHE_USER_GROUPS, $intUserID)) {
$userGroups = self::getUserGroups($intUserID);
static::setHitCache(self::CACHE_USER_GROUPS, $intUserID, $userGroups);
}
if (empty($userGroups)) {
return $arResult;
}
} else {
$userGroups = [2];
if (isset($USER) && $USER instanceof CUser) {
$userGroups = $USER->GetUserGroupArray();
}
}
if (!$arProduct = static::getHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID)) {
$elementFilter = [
'ID' => $productID,
'ACTIVE' => 'Y',
'ACTIVE_DATE' => 'Y',
'CHECK_PERMISSIONS' => 'Y',
'MIN_PERMISSION' => 'R',
];
if ($adminSection) {
$elementFilter['PERMISSIONS_BY'] = $intUserID;
}
$iterator = CIBlockElement::GetList(
[],
$elementFilter,
false,
false,
['ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL']
);
if ($arProduct = $iterator->GetNext()) {
static::setHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID, $arProduct);
}
unset($dbIBlockElement, $elementFilter);
}
if (empty($arProduct) || !is_array($arProduct)) {
return $arResult;
}
if (!static::checkParentActivity($arProduct['ID'], $arProduct['IBLOCK_ID'])) {
return $arResult;
}
if (!$arCatalogProduct = static::getHitCache(self::CACHE_PRODUCT, $productID)) {
$select = ['ID', 'TYPE', 'AVAILABLE',
'QUANTITY', 'QUANTITY_TRACE', 'CAN_BUY_ZERO',
'WEIGHT', 'WIDTH', 'HEIGHT', 'LENGTH',
'BARCODE_MULTI',
'MEASURE',
];
$select = array_merge($select, Catalog\Product\SystemField::getProviderSelectFields());
$arCatalogProduct = Catalog\ProductTable::getList([
'select' => $select,
'filter' => ['=ID' => $productID],
])->fetch();
if (!empty($arCatalogProduct)) {
Catalog\Product\SystemField::prepareRow($arCatalogProduct, Catalog\Product\SystemField::OPERATION_PROVIDER);
$arCatalogProduct['QUANTITY'] = (float)$arCatalogProduct['QUANTITY'];
static::setHitCache(self::CACHE_PRODUCT, $productID, $arCatalogProduct);
}
}
if (empty($arCatalogProduct) || !is_array($arCatalogProduct)) {
return $arResult;
}
if (
($arCatalogProduct['TYPE'] == Catalog\ProductTable::TYPE_SKU || $arCatalogProduct['TYPE'] == Catalog\ProductTable::TYPE_EMPTY_SKU)
&& (string)Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') != 'Y'
) {
return $arResult;
}
if (
$arParams["CHECK_QUANTITY"] == "Y"
&& $arCatalogProduct['AVAILABLE'] != Catalog\ProductTable::STATUS_YES
) {
return $arResult;
}
if ($arCatalogProduct['TYPE'] == Catalog\ProductTable::TYPE_SET) {
static::$errors = [];
if (!static::checkProductSet($productID)) {
static::$errors = [];
return $arResult;
}
}
if ($adminSection) {
CCatalogDiscountSave::SetDiscountUserID($intUserID);
}
$productHash = [
'MODULE' => ($useSaleDiscountOnly ? 'sale' : 'catalog'),
'PRODUCT_ID' => $productID,
'BASKET_ID' => $arParams['BASKET_ID'],
];
$arCoupons = DiscountCouponsManager::getForApply([], $productHash, true);
if (!empty($arCoupons)) {
$arCoupons = array_keys($arCoupons);
}
Price\Calculation::pushConfig();
Price\Calculation::setConfig([
'CURRENCY' => $arParams['CURRENCY'],
'PRECISION' => (int)Main\Config\Option::get('sale', 'value_precision'),
'USE_DISCOUNTS' => $arParams['CHECK_DISCOUNT'] == 'Y',
'RESULT_WITH_VAT' => true,
'RESULT_MODE' => Catalog\Product\Price\Calculation::RESULT_MODE_RAW,
]);
$arPrice = CCatalogProduct::GetOptimalPrice(
$productID,
$quantity,
$userGroups,
$arParams['RENEWAL'],
[],
($adminSection ? $strSiteID : false),
$arCoupons
);
if (empty($arPrice)) {
if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $userGroups)) {
$quantity = $nearestQuantity;
$arPrice = CCatalogProduct::GetOptimalPrice(
$productID,
$quantity,
$userGroups,
$arParams['RENEWAL'],
[],
($adminSection ? $strSiteID : false),
$arCoupons
);
}
}
Price\Calculation::popConfig();
unset($userGroups);
if ($adminSection) {
CCatalogDiscountSave::ClearDiscountUserID();
}
if (empty($arPrice)) {
return $arResult;
}
$arDiscountList = [];
if (empty($arPrice['DISCOUNT_LIST']) && !empty($arPrice['DISCOUNT']) && is_array($arPrice['DISCOUNT'])) {
$arPrice['DISCOUNT_LIST'] = [$arPrice['DISCOUNT']];
}
if (!empty($arPrice['DISCOUNT_LIST'])) {
$appliedCoupons = [];
foreach ($arPrice['DISCOUNT_LIST'] as &$arOneDiscount) {
$arDiscountList[] = CCatalogDiscount::getDiscountDescription($arOneDiscount);
if (!empty($arOneDiscount['COUPON'])) {
$appliedCoupons[] = $arOneDiscount['COUPON'];
}
}
unset($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);
}
}
if (empty($arPrice['RESULT_PRICE']) || !is_array($arPrice['RESULT_PRICE'])) {
$arPrice['RESULT_PRICE'] = CCatalogDiscount::calculateDiscountList($arPrice['PRICE'], $arParams['CURRENCY'], $arDiscountList, true);
}
$arResult = [
'PRODUCT_PRICE_ID' => $arPrice['RESULT_PRICE']['ID'],
// "AVAILABLE_QUANTITY" => $arCatalogProduct["QUANTITY"],
'PRICE_TYPE_ID' => $arPrice['RESULT_PRICE']['PRICE_TYPE_ID'],
// 'BASE_PRICE' => $arPrice['RESULT_PRICE']['BASE_PRICE'],
'PRICE' => $arPrice['RESULT_PRICE']['DISCOUNT_PRICE'],
'VAT_RATE' => $arPrice['RESULT_PRICE']['VAT_RATE'],
'VAT_INCLUDED' => $arPrice['RESULT_PRICE']['VAT_INCLUDED'],
"CURRENCY" => $arPrice['RESULT_PRICE']['CURRENCY'],
"WEIGHT" => (float)$arCatalogProduct["WEIGHT"],
"DIMENSIONS" => serialize([
"WIDTH" => $arCatalogProduct["WIDTH"],
"HEIGHT" => $arCatalogProduct["HEIGHT"],
"LENGTH" => $arCatalogProduct["LENGTH"],
]),
"NAME" => $arProduct["~NAME"],
"CAN_BUY" => "Y",
"DETAIL_PAGE_URL" => $arProduct['~DETAIL_PAGE_URL'],
"NOTES" => $arPrice["PRICE"]["CATALOG_GROUP_NAME"],
"DISCOUNT_PRICE" => $arPrice['RESULT_PRICE']['DISCOUNT'],
"DISCOUNT_VALUE" => ($arPrice['RESULT_PRICE']['PERCENT'] > 0 ? $arPrice['RESULT_PRICE']['PERCENT'] . '%' : null),
"DISCOUNT_NAME" => null,
"DISCOUNT_COUPON" => null,
"DISCOUNT_LIST" => [],
];
switch ($arCatalogProduct['TYPE']) {
case Catalog\ProductTable::TYPE_SET:
$arResult['TYPE'] = Sale\BasketItem::TYPE_SET;
break;
case Catalog\ProductTable::TYPE_SERVICE:
$arResult['TYPE'] = Sale\BasketItem::TYPE_SERVICE;
break;
default:
$arResult['TYPE'] = null;
break;
}
foreach (Catalog\Product\SystemField::getProviderSelectFields() as $index => $value) {
$field = is_string($index) ? $index : $value;
$arResult[$field] = $arCatalogProduct[$field];
}
if ($arParams["CHECK_QUANTITY"] == "Y") {
$arResult["QUANTITY"] = $quantity;
} else {
$arResult["QUANTITY"] = $arParams["QUANTITY"];
}
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'] = [$arPrice['DISCOUNT']];
}
}
return $arResult;
}
}