• Модуль: catalog
  • Путь к файлу: ~/bitrix/modules/catalog/lib/discount/discountmanager.php
  • Класс: BitrixCatalogDiscountDiscountManager
  • Вызов: DiscountManager::calculateApplyCoupons
static function calculateApplyCoupons(array $couponsList, array $basket, array $params): array
{
	$result = [];

	if (empty($couponsList))
		return $result;
	if (empty($basket))
		return $result;
	$filteredBasket = array_filter($basket, 'BitrixCatalogDiscountDiscountManager::basketFilter');
	if (empty($filteredBasket))
		return $result;
	$filteredBasket = array_filter($filteredBasket, 'BitrixCatalogDiscountDiscountManager::lastDiscountFilter');
	if (empty($filteredBasket))
		return $result;

	$filteredCoupons = [];
	foreach ($couponsList as $coupon)
	{
		if (!isset($coupon['COUPON']) || $coupon['COUPON'] == '')
			continue;
		if (!isset($coupon['DISCOUNT_ID']) || (int)$coupon['DISCOUNT_ID'] <= 0)
			continue;
		$filteredCoupons[] = $coupon['COUPON'];
	}
	unset($coupon);
	if (empty($filteredCoupons))
		return $result;

	$discountIds = [];
	$discountCoupons = [];
	$oneRowCoupons = [];
	$couponsIterator = CatalogDiscountCouponTable::getList([
		'select' => ['ID', 'COUPON', 'DISCOUNT_ID', 'TYPE'],
		'filter' => ['@COUPON' => $filteredCoupons, 'ACTIVE' => 'Y']
	]);
	while ($coupon = $couponsIterator->fetch())
	{
		$discountIds[$coupon['DISCOUNT_ID']] = true;
		$discountCoupons[$coupon['COUPON']] = $coupon['COUPON'];
		if ($coupon['TYPE'] == CatalogDiscountCouponTable::TYPE_ONE_ROW)
			$oneRowCoupons[$coupon['COUPON']] = true;
	}
	unset($coupon, $couponsIterator);
	if (empty($discountCoupons))
		return $result;

	$userId = (isset($params['USER_ID']) ? (int)$params['USER_ID'] : 0);
	if ($userId <= 0)
		return $result;
	$userGroups = MainUserTable::getUserGroupIds($userId);
	$userGroups[] = -1;

	$iblockList = [];
	$product2Iblock = [];
	$itemIds = [];
	foreach ($filteredBasket as $basketItem)
	{
		$productId = (int)$basketItem['PRODUCT_ID'];
		$itemIds[$productId] = $productId;
	}
	unset($basketItem);

	$itemIterator = IblockElementTable::getList([
		'select' => ['ID', 'IBLOCK_ID'],
		'filter' => ['@ID' => $itemIds, '=ACTIVE' => 'Y']
	]);
	while ($item = $itemIterator->fetch())
	{
		$id = (int)$item['ID'];
		$iblockId = (int)$item['IBLOCK_ID'];
		if (!isset($iblockList[$iblockId]))
			$iblockList[$iblockId] = [];
		$iblockList[$iblockId][$id] = $id;
		$product2Iblock[$id] = $iblockId;
		unset($iblockId, $id);
	}
	unset($item, $itemIterator);
	unset($itemIds);

	if (empty($iblockList))
		return $result;

	foreach($iblockList as $iblockId => $elements)
	{
		/** @noinspection PhpMethodOrClassCallIsNotCaseSensitiveInspection */
		CCatalogDiscount::setProductSectionsCache($elements);
		/** @noinspection PhpMethodOrClassCallIsNotCaseSensitiveInspection */
		CCatalogDiscount::setDiscountProductCache($elements, ['IBLOCK_ID' => $iblockId, 'GET_BY_ID' => 'Y']);
	}
	unset($iblockId, $elements);

	$discountPercentMode = CCatalogDiscount::getUseBasePrice();
	if (isset($params['USE_BASE_PRICE']))
		CCatalogDiscount::setUseBasePrice($params['USE_BASE_PRICE'] == 'Y');

	MainTypeCollection::sortByColumn($filteredBasket, ['PRICE' => SORT_DESC], '', null, true);
	foreach ($filteredBasket as $basketCode => $basketItem)
	{
		$productId = (int)$basketItem['PRODUCT_ID'];
		if (!isset($product2Iblock[$productId]))
			continue;
		if (empty($discountCoupons))
			break;

		/** @noinspection PhpMethodOrClassCallIsNotCaseSensitiveInspection */
		$discountList = CCatalogDiscount::getDiscount(
			$productId,
			$product2Iblock[$productId],
			[-1],
			$userGroups,
			'N',
			$params['SITE_ID'],
			$discountCoupons
		);

		if (empty($discountList))
			continue;

		$itemDiscounts = [];
		foreach ($discountList as $discount)
		{
			if (!isset($discountIds[$discount['ID']]))
				continue;
			$itemDiscounts[] = $discount;
		}
		unset($discount, $discountList);
		if (empty($itemDiscounts))
			continue;

		$itemsDiscountResult = CCatalogDiscount::applyDiscountList($basketItem['PRICE'], $basketItem['CURRENCY'], $itemDiscounts);
		unset($itemDiscounts);
		if (!empty($itemsDiscountResult['DISCOUNT_LIST']))
		{
			$result[$basketCode] = [];
			foreach ($itemsDiscountResult['DISCOUNT_LIST'] as $discount)
			{
				$result[$basketCode][] = CCatalogDiscount::getDiscountDescription($discount);
				if (!empty($discount['COUPON']) && isset($oneRowCoupons[$discount['COUPON']]))
					unset($discountCoupons[$discount['COUPON']]);
			}
			unset($discount);
		}
		unset($itemsDiscountResult);
	}
	unset($basketCode, $basketItem, $basketItem);

	CCatalogDiscount::setUseBasePrice($discountPercentMode);
	unset($discountPercentMode);

	return $result;
}