• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/discount/actions.php
  • Класс: BitrixSaleDiscountActions
  • Вызов: Actions::applyToBasket
static function applyToBasket(array &$order, array $action, $filter)
{
	static::increaseApplyCounter();

	if (!isset($action['VALUE']) || !isset($action['UNIT']))
		return;

	$orderCurrency = static::getCurrency();
	$value = (float)$action['VALUE'];
	$limitValue = (int)$action['LIMIT_VALUE'];
	$unit = (string)$action['UNIT'];
	$currency = (isset($action['CURRENCY']) ? $action['CURRENCY'] : $orderCurrency);
	$maxBound = false;
	if ($unit == self::VALUE_TYPE_FIX && $value < 0)
		$maxBound = (isset($action['MAX_BOUND']) && $action['MAX_BOUND'] == 'Y');
	$valueAction = (
		$value < 0
		? Formatter::VALUE_ACTION_DISCOUNT
		: Formatter::VALUE_ACTION_EXTRA
	);

	$actionDescription = array(
		'ACTION_TYPE' => Formatter::TYPE_VALUE,
		'VALUE' => abs($value),
		'VALUE_ACTION' => $valueAction
	);
	switch ($unit)
	{
		case self::VALUE_TYPE_SUMM:
			$actionDescription = [
				'ACTION_TYPE' => Formatter::TYPE_VALUE,
				'VALUE' => abs($value),
				'VALUE_ACTION' => ($value < 0 ? Formatter::VALUE_ACTION_DISCOUNT : Formatter::VALUE_ACTION_EXTRA),
				'VALUE_TYPE' => Formatter::VALUE_TYPE_SUMM,
				'VALUE_UNIT' => $currency
			];
			break;
		case self::VALUE_TYPE_PERCENT:
			$actionDescription = [
				'ACTION_TYPE' => Formatter::TYPE_VALUE,
				'VALUE' => abs($value),
				'VALUE_ACTION' => ($value < 0 ? Formatter::VALUE_ACTION_DISCOUNT : Formatter::VALUE_ACTION_EXTRA),
				'VALUE_TYPE' => Formatter::VALUE_TYPE_PERCENT
			];
			break;
		case self::VALUE_TYPE_FIX:
			$actionDescription = [
				'ACTION_TYPE' => ($maxBound ? Formatter::TYPE_MAX_BOUND : Formatter::TYPE_VALUE),
				'VALUE' => abs($value),
				'VALUE_ACTION' => ($value < 0 ? Formatter::VALUE_ACTION_DISCOUNT : Formatter::VALUE_ACTION_EXTRA),
				'VALUE_TYPE' => Formatter::VALUE_TYPE_CURRENCY,
				'VALUE_UNIT' => $currency
			];
			break;
		case self::VALUE_TYPE_CLOSEOUT:
			$actionDescription = [
				'ACTION_TYPE' => Formatter::TYPE_FIXED,
				'VALUE' => abs($value),
				'VALUE_ACTION' => Formatter::VALUE_ACTION_DISCOUNT,
				'VALUE_TYPE' => Formatter::VALUE_TYPE_CURRENCY,
				'VALUE_UNIT' => $currency
			];
			break;
		default:
			return;
			break;
	}
	$valueAction = $actionDescription['VALUE_ACTION'];

	if(!empty($limitValue))
	{
		$actionDescription['ACTION_TYPE'] = Formatter::TYPE_LIMIT_VALUE;
		$actionDescription['LIMIT_TYPE'] = Formatter::LIMIT_MAX;
		$actionDescription['LIMIT_UNIT'] = $orderCurrency;
		$actionDescription['LIMIT_VALUE'] = $limitValue;
	}

	static::setActionDescription(self::RESULT_ENTITY_BASKET, $actionDescription);

	if (empty($order['BASKET_ITEMS']) || !is_array($order['BASKET_ITEMS']))
		return;

	static::enableBasketFilter();
	$filteredBasket = static::getBasketForApply($order['BASKET_ITEMS'], $filter, $action);
	if (empty($filteredBasket))
		return;

	$applyBasket = array_filter($filteredBasket, 'BitrixSaleDiscountActions::filterBasketForAction');
	unset($filteredBasket);
	if (empty($applyBasket))
		return;

	if ($unit == self::VALUE_TYPE_SUMM || $unit == self::VALUE_TYPE_FIX)
	{
		if ($currency != $orderCurrency)
			$value = CCurrencyRates::ConvertCurrency($value, $currency, $orderCurrency);
		if ($unit == self::VALUE_TYPE_SUMM)
		{
			$value = static::getPercentByValue($applyBasket, $value);
			if (
				($valueAction == Formatter::VALUE_ACTION_DISCOUNT && ($value >= 0 || $value < -100))
				||
				($valueAction == Formatter::VALUE_ACTION_EXTRA && $value <= 0)
			)
				return;
			$unit = self::VALUE_TYPE_PERCENT;
		}
	}
	$value = static::roundZeroValue($value);
	if ($value == 0)
		return;

	foreach ($applyBasket as $basketCode => $basketRow)
	{
		list($calculateValue, $result) = self::calculateDiscountPrice(
			$value,
			$unit,
			$basketRow,
			$limitValue,
			$maxBound
		);
		if ($result >= 0)
		{
			self::fillDiscountPrice($basketRow, $result, -$calculateValue);

			$order['BASKET_ITEMS'][$basketCode] = $basketRow;

			$rowActionDescription = $actionDescription;
			$rowActionDescription['BASKET_CODE'] = $basketCode;
			$rowActionDescription['RESULT_VALUE'] = abs($calculateValue);
			$rowActionDescription['RESULT_UNIT'] = $orderCurrency;

			if(!empty($limitValue))
			{
				$rowActionDescription['ACTION_TYPE'] = Formatter::TYPE_LIMIT_VALUE;
				$rowActionDescription['LIMIT_TYPE'] = Formatter::LIMIT_MAX;
				$rowActionDescription['LIMIT_UNIT'] = $orderCurrency;
				$rowActionDescription['LIMIT_VALUE'] = $limitValue;
			}

			static::setActionResult(self::RESULT_ENTITY_BASKET, $rowActionDescription);
			unset($rowActionDescription);
		}
		unset($result);
	}
	unset($basketCode, $basketRow);
}