- Модуль: sale
- Путь к файлу: ~/bitrix/modules/sale/lib/discount/actions.php
- Класс: BitrixSaleDiscountActions
- Вызов: Actions::applyCumulativeToBasket
static function applyCumulativeToBasket(array &$order, array $ranges, array $configuration = array(), $filter = null)
{
static::increaseApplyCounter();
MainTypeCollection::sortByColumn($ranges, 'sum');
$sumConfiguration = $configuration['sum']?: array();
$applyIfMoreProfitable = $configuration['apply_if_more_profitable'] === 'Y';
if (static::checkUseMode(array(self::MODE_MANUAL, self::MODE_MIXED)))
{
$actionStoredData = self::getActionStoredData();
$cumulativeOrderUserValue = $actionStoredData['cumulative_value'];
}
else
{
$cumulativeCalculator = new CumulativeCalculator((int)$order['USER_ID'], $order['SITE_ID']);
$cumulativeCalculator->setSumConfiguration(
array(
'type_sum_period' => $sumConfiguration['type_sum_period'],
'sum_period_data' => array(
'order_start' => $sumConfiguration['sum_period_data']['discount_sum_order_start'],
'order_end' => $sumConfiguration['sum_period_data']['discount_sum_order_end'],
'period_value' => $sumConfiguration['sum_period_data']['discount_sum_period_value'],
'period_type' => $sumConfiguration['sum_period_data']['discount_sum_period_type'],
),
)
);
$cumulativeOrderUserValue = $cumulativeCalculator->calculate();
}
$rangeToApply = null;
foreach ($ranges as $range)
{
if ($cumulativeOrderUserValue >= $range['sum'])
{
$rangeToApply = $range;
}
}
if (!$rangeToApply)
{
return;
}
$action = array(
'VALUE' => -$rangeToApply['value'],
'UNIT' => $rangeToApply['type'],
);
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 = Formatter::VALUE_ACTION_CUMULATIVE;
$actionDescription = array(
'ACTION_TYPE' => Formatter::TYPE_VALUE,
'VALUE' => abs($value),
'VALUE_ACTION' => $valueAction
);
switch ($unit)
{
case self::VALUE_TYPE_PERCENT:
$actionDescription['VALUE_TYPE'] = Formatter::VALUE_TYPE_PERCENT;
break;
case self::VALUE_TYPE_FIX:
$actionDescription['VALUE_TYPE'] = Formatter::VALUE_TYPE_CURRENCY;
$actionDescription['VALUE_UNIT'] = $currency;
if ($maxBound)
$actionDescription['ACTION_TYPE'] = Formatter::TYPE_MAX_BOUND;
break;
default:
return;
}
if ($unit == self::VALUE_TYPE_FIX && $currency != $orderCurrency)
{
$value = CCurrencyRates::ConvertCurrency($value, $currency, $orderCurrency);
}
$value = static::roundZeroValue($value);
if ($value == 0)
{
return;
}
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();
if ($applyIfMoreProfitable)
{
if ($filter === null)
{
$filter = function(){
return true;
};
}
$filter = self::wrapFilterToFindMoreProfitableForCumulative($filter, $unit, $value, $limitValue, $maxBound);
}
$filteredBasket = static::getBasketForApply($order['BASKET_ITEMS'], $filter, $action);
if (empty($filteredBasket))
return;
$applyBasket = array_filter($filteredBasket, 'BitrixSaleDiscountActions::filterBasketForAction');
unset($filteredBasket);
if (empty($applyBasket))
return;
foreach ($applyBasket as $basketCode => $basketRow)
{
if ($applyIfMoreProfitable)
{
$basketRow['PRICE'] = $basketRow['BASE_PRICE'];
$basketRow['DISCOUNT_PRICE'] = 0;
}
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;
}
if ($applyIfMoreProfitable)
{
//TODO: remove this hack
//revert apply on affected basket items
$rowActionDescription['REVERT_APPLY'] = true;
}
static::setActionResult(self::RESULT_ENTITY_BASKET, $rowActionDescription);
unset($rowActionDescription);
}
unset($result);
}
unset($basketCode, $basketRow);
if (self::getUseMode() == self::MODE_CALCULATE)
{
self::setActionStoredData(
array(
'cumulative_value' => $cumulativeOrderUserValue,
)
);
}
}