private function getData(array $products, array $options = array()): SaleResult
{
$context = $this->getContext();
$resultProductList = array_fill_keys(array_keys($products), false);
$result = new SaleResult();
$userId = (int)($context['USER_ID'] ?? 0);
if ($userId < 0)
{
$userId = 0;
}
$siteId = $context['SITE_ID'] ?? false;
$currency = $context['CURRENCY'] ?? false;
$currency = (is_string($currency) ? CurrencyCurrencyManager::checkCurrencyID($context['CURRENCY']) : false);
if ($currency === false)
{
$currency = SaleInternalsSiteCurrencyTable::getSiteCurrency($siteId ?: SITE_ID);
}
$adminSection = (defined('ADMIN_SECTION') && ADMIN_SECTION === true);
if (in_array('DISABLE_CACHE', $options))
{
$this->enableCache = false;
}
$catalogDataEnabled = self::isCatalogDataEnabled($options);
$outputVariable = static::getOutputVariable($options);
$productGetIdList = array();
$correctProductIds = [];
$iblockElementSelect = array('ID', 'IBLOCK_ID', 'IBLOCK_SECTION_ID', 'ACTIVE', 'ACTIVE_DATE', 'XML_ID');
if (!$catalogDataEnabled)
{
$iblockElementSelect = array_merge($iblockElementSelect, array('NAME', 'DETAIL_PAGE_URL'));
}
$resultList = array();
foreach ($products as $productId => $itemData)
{
$resultList[$productId] = false;
if (!isset($itemData['ITEM_CODE']))
{
$itemData['ITEM_CODE'] = $productId;
$products[$productId]['ITEM_CODE'] = $productId;
}
if (!isset($itemData['BASKET_CODE']))
{
$itemData['BASKET_CODE'] = $productId;
$products[$productId]['BASKET_CODE'] = $productId;
}
$hash = $productId."|".$userId;
$productCachedData = static::getHitCache(self::CACHE_ITEM_RIGHTS, $hash, $iblockElementSelect);
if ($this->enableCache && !empty($productCachedData))
{
$products[$productId]['PRODUCT_DATA'] = $productCachedData;
$correctProductIds[$productId] = true;
}
else
{
$productGetIdList[] = $productId;
}
}
if (!empty($productGetIdList))
{
$productDataList = $this->getElements(
$productGetIdList,
$iblockElementSelect,
($adminSection ? $userId : null)
);
foreach ($productDataList as $productId => $productData)
{
$products[$productId]['PRODUCT_DATA'] = $productData;
$hash = $productId."|".$userId;
static::setHitCache(self::CACHE_ITEM_RIGHTS, $hash, $productData);
$correctProductIds[$productId] = true;
}
$products = array_intersect_key(
$products,
$correctProductIds
);
if (empty($products))
{
return static::getResultProvider($result, $outputVariable, $resultList);
}
}
unset($correctProductIds);
$iblockList = array();
$iblockDataList = array();
$iblockGetIdList = array();
foreach ($products as $productId => $productData)
{
$iblockId = $productData['PRODUCT_DATA']['IBLOCK_ID'];
$iblockList[$iblockId][] = $productId;
}
foreach ($iblockList as $iblockId => $iblockProductIdList)
{
$iblockData = static::getHitCache(self::CACHE_CATALOG_IBLOCK_LIST, $iblockId);
if ($this->enableCache && !empty($iblockData))
{
$iblockDataList[$iblockId] = $iblockData;
}
else
{
$iblockGetIdList[] = $iblockId;
}
}
if (!empty($iblockGetIdList))
{
$iblockDataList = $this->getIblockData($iblockGetIdList) + $iblockDataList;
}
$iblockList = array_intersect_key(
$iblockList,
$iblockDataList
);
$iblockProductMap = static::createIblockProductMap($iblockList, $iblockDataList);
$correctProductList = static::checkSkuPermission($iblockProductMap);
$products = array_intersect_key(
$products,
array_fill_keys($correctProductList, true)
);
if (empty($products))
{
return static::getResultProvider($result, $outputVariable, $resultList);
}
$products = static::changeSubscribeProductQuantity($products, $iblockProductMap);
// catalog product
$catalogSelect = array(
'ID',
'CAN_BUY_ZERO',
'QUANTITY_TRACE',
'QUANTITY',
'QUANTITY_RESERVED',
'MEASURE',
'TYPE',
'AVAILABLE',
);
if (!$catalogDataEnabled)
{
$catalogSelect = array_merge($catalogSelect, array(
'WEIGHT',
'WIDTH',
'HEIGHT',
'LENGTH',
'BARCODE_MULTI'
));
}
$catalogSelect = array_merge($catalogSelect, CatalogProductSystemField::getProviderSelectFields());
$catalogProductDataList = static::getCatalogProducts(array_keys($products), $catalogSelect);
$products = array_intersect_key($products, $catalogProductDataList);
if (empty($products))
{
return static::getResultProvider($result, $outputVariable, $resultList);
}
// fill catalog xml id
$products = self::fillCatalogXmlId($products, $iblockProductMap);
// prepare offers xml id
$products = self::fillOfferXmlId($products, $catalogProductDataList);
// get prices and discounts
$priceDataList = self::getPriceDataList(
$products,
[
'IS_ADMIN_SECTION' => $adminSection,
'USER_ID' => $userId,
'SITE_ID' => $siteId,
'CURRENCY' => $currency,
]
);
$discountList = self::getDiscountList($priceDataList);
$productQuantityList = array();
$productPriceList = array();
$fullQuantityMode = in_array('FULL_QUANTITY', $options);
foreach ($products as $productId => $productData)
{
$catalogProductData = $catalogProductDataList[$productId];
$quantityList = array();
if (array_key_exists('QUANTITY', $productData))
{
$quantityList = array($productData['BASKET_CODE'] => $productData['QUANTITY']);
}
if (!empty($productData[Base::FLAT_QUANTITY_LIST]))
{
$quantityList = $productData[Base::FLAT_QUANTITY_LIST];
}
$productQuantityList[$productData['BASKET_CODE']]['QUANTITY_RESERVED'] = $catalogProductData['QUANTITY_RESERVED'];
$baseCatalogQuantity = (float)$catalogProductData['QUANTITY'];
$allCount = count($quantityList);
$sumQuantity = 0;
foreach ($quantityList as $quantity)
{
$sumQuantity += (float)abs($quantity);
}
$catalogQuantityForAvaialable = $baseCatalogQuantity;
$checkCatalogQuantity = $baseCatalogQuantity;
$isEnough = !($catalogProductData['CHECK_QUANTITY'] && $catalogQuantityForAvaialable < $sumQuantity);
$setQuantity = $baseCatalogQuantity;
foreach ($quantityList as $basketCode => $quantity)
{
$quantity = (float)abs($quantity);
if (!$isEnough)
{
if ($catalogQuantityForAvaialable - $quantity < 0)
{
$quantity = $catalogQuantityForAvaialable;
}
$catalogQuantityForAvaialable -= $quantity;
}
$productQuantityList[$basketCode]['AVAILABLE_QUANTITY'] = (
$baseCatalogQuantity >= $quantity || !$catalogProductData['CHECK_QUANTITY']
? $quantity
: $baseCatalogQuantity
);
if ($fullQuantityMode)
{
$checkCatalogQuantity -= $quantity;
$setQuantity = $quantity;
$allCount--;
if ($allCount == 0)
{
$setQuantity = $checkCatalogQuantity + $quantity;
}
}
else
{
if ($baseCatalogQuantity - $quantity > 0 || !$catalogProductData['CHECK_QUANTITY'])
{
$setQuantity = $quantity;
}
}
$productQuantityList[$basketCode]['QUANTITY'] = $setQuantity;
}
unset($basketCode, $quantity);
foreach (array_keys($quantityList) as $basketCode)
{
if (isset($priceDataList[$productId][$basketCode]))
{
$productPriceList[$basketCode] = $priceDataList[$productId][$basketCode];
}
}
unset($basketCode);
$measure = isset($catalogProductData['MEASURE']) ? (int)$catalogProductData['MEASURE'] : null;
$measureFields = static::getMeasure($measure);
if (!empty($measureFields))
{
$catalogProductDataList[$productId] = $measureFields + $catalogProductDataList[$productId];
}
}
unset($fullQuantityMode);
$resultData = static::setCatalogDataToProducts($products, $catalogProductDataList, $options);
$priceResultList = static::createProductPriceList($products, $productPriceList, $discountList);
$resultList = static::createProductResult($products, $resultData, $priceResultList, $productQuantityList);
$resultList = $resultList + $resultProductList;
return static::getResultProvider($result, $outputVariable, $resultList);
}