58 private static $compatibleBasketFields = array(
'DISCOUNT_PRICE',
'PRICE',
'VAT_VALUE',
'PRICE_DEFAULT');
68 return (abs($value) <= self::VALUE_EPS ? 0 : $value);
81 return Sale\PriceMaths::roundPrecision($value);
91 public static function setUseMode($mode, array $config = array())
94 if ($mode !== self::MODE_CALCULATE && $mode !== self::MODE_MANUAL && $mode !== self::MODE_MIXED)
96 self::$useMode = $mode;
97 switch (self::$useMode)
100 $percentOption = (string)Main\
Config\Option::get(
'sale',
'get_discount_percent_from_base_price');
102 unset($percentOption);
103 if (isset($config[
'CURRENCY']))
104 self::$currencyId = $config[
'CURRENCY'];
105 if (isset($config[
'SITE_ID']))
107 self::$siteId = $config[
'SITE_ID'];
108 if (self::$currencyId ==
'')
109 self::$currencyId = Sale\Internals\SiteCurrencyTable::getSiteCurrency(self::$siteId);
115 if (isset($config[
'USE_BASE_PRICE']))
116 $percentOption = $config[
'USE_BASE_PRICE'];
117 if ($percentOption ==
'')
118 $percentOption = (string)Main\
Config\Option::get(
'sale',
'get_discount_percent_from_base_price');
120 unset($percentOption);
121 if (isset($config[
'CURRENCY']))
122 self::$currencyId = $config[
'CURRENCY'];
123 if (isset($config[
'SITE_ID']))
125 self::$siteId = $config[
'SITE_ID'];
126 if (self::$currencyId ==
'')
127 self::$currencyId = Sale\Internals\SiteCurrencyTable::getSiteCurrency(self::$siteId);
131 static::clearApplyCounter();
132 static::enableBasketFilter();
183 return (in_array(self::$useMode, $list,
true));
233 self::$applyCounter++;
243 if (!static::isMixedMode())
245 self::$useBasketFilter =
false;
255 if (!static::isMixedMode())
257 self::$useBasketFilter =
true;
278 $adminSection = Main\Context::getCurrent()->getRequest()->isAdminSection();
279 if (empty($order) || !is_array($order))
281 if (!empty($order[
'BASKET_ITEMS']) && is_array($order[
'BASKET_ITEMS']))
283 foreach ($order[
'BASKET_ITEMS'] as &$item)
285 if (isset($item[
'PRICE_DEFAULT']))
286 $item[
'PRICE_DEFAULT'] = $item[
'PRICE'];
290 foreach (self::$compatibleBasketFields as &$fieldName)
292 if (array_key_exists($fieldName, $item) && !is_array($item[$fieldName]))
293 $item[
'~'.$fieldName] = $item[$fieldName];
310 (!isset($item[
'CUSTOM_PRICE']) || $item[
'CUSTOM_PRICE'] !=
'Y') &&
313 (!isset($item[
'SET_PARENT_ID']) || (
int)$item[
'SET_PARENT_ID'] <= 0)
315 (!isset($item[
'ITEM_FIX']) || $item[
'ITEM_FIX'] !=
'Y') &&
316 (!isset($item[
'LAST_DISCOUNT']) || $item[
'LAST_DISCOUNT'] !=
'Y') &&
317 (!isset($item[
'IN_SET']) || $item[
'IN_SET'] !=
'Y')
350 if ($mode != self::APPLY_RESULT_MODE_COUNTER && $mode != self::APPLY_RESULT_MODE_DESCR && $mode != self::APPLY_RESULT_MODE_SIMPLE)
352 self::$applyResultMode = $mode;
353 self::$applyResult = array();
385 self::$storedData = $data;
406 if (!static::isCalculateMode())
410 self::$storedData[static::getApplyCounter()] = $data;
420 $counter = static::getApplyCounter();
421 if (isset(self::$storedData[$counter]))
422 return self::$storedData[$counter];
434 self::$applyResult = array();
435 self::$actionResult = array();
436 self::$actionDescription = array();
437 self::$storedData = array();
457 static::increaseApplyCounter();
459 if (!isset($action[
'VALUE']) || !isset($action[
'UNIT']))
462 $orderCurrency = static::getCurrency();
463 $value = (float)$action[
'VALUE'];
464 $limitValue = (int)$action[
'LIMIT_VALUE'];
465 $unit = (string)$action[
'UNIT'];
466 $currency = (isset($action[
'CURRENCY']) ? $action[
'CURRENCY'] : $orderCurrency);
468 if ($unit == self::VALUE_TYPE_FIX && $value < 0)
469 $maxBound = (isset($action[
'MAX_BOUND']) && $action[
'MAX_BOUND'] ==
'Y');
478 'VALUE' => abs($value),
479 'VALUE_ACTION' => $valueAction
486 'VALUE' => abs($value),
489 'VALUE_UNIT' => $currency
495 'VALUE' => abs($value),
503 'VALUE' => abs($value),
506 'VALUE_UNIT' => $currency
512 'VALUE' => abs($value),
515 'VALUE_UNIT' => $currency
524 if(!empty($limitValue))
534 if (empty($order[
'BASKET_ITEMS']) || !is_array($order[
'BASKET_ITEMS']))
537 static::enableBasketFilter();
538 $filteredBasket = static::getBasketForApply($order[
'BASKET_ITEMS'], $filter, $action);
539 if (empty($filteredBasket))
542 $applyBasket = array_filter($filteredBasket,
'\Bitrix\Sale\Discount\Actions::filterBasketForAction');
543 unset($filteredBasket);
544 if (empty($applyBasket))
547 if ($unit == self::VALUE_TYPE_SUMM || $unit == self::VALUE_TYPE_FIX)
549 if ($currency != $orderCurrency)
550 $value = \CCurrencyRates::ConvertCurrency($value, $currency, $orderCurrency);
551 if ($unit == self::VALUE_TYPE_SUMM)
553 $value = static::getPercentByValue($applyBasket, $value);
563 $value = static::roundZeroValue($value);
567 foreach ($applyBasket as $basketCode => $basketRow)
580 $order[
'BASKET_ITEMS'][$basketCode] = $basketRow;
583 $rowActionDescription[
'BASKET_CODE'] = $basketCode;
584 $rowActionDescription[
'RESULT_VALUE'] = abs($calculateValue);
585 $rowActionDescription[
'RESULT_UNIT'] = $orderCurrency;
587 if(!empty($limitValue))
591 $rowActionDescription[
'LIMIT_UNIT'] = $orderCurrency;
592 $rowActionDescription[
'LIMIT_VALUE'] = $limitValue;
595 static::setActionResult(self::RESULT_ENTITY_BASKET, $rowActionDescription);
596 unset($rowActionDescription);
600 unset($basketCode, $basketRow);
615 static::increaseApplyCounter();
617 Main\Type\Collection::sortByColumn($ranges,
'sum');
619 $sumConfiguration = $configuration[
'sum']?: array();
620 $applyIfMoreProfitable = $configuration[
'apply_if_more_profitable'] ===
'Y';
622 if (static::checkUseMode(array(self::MODE_MANUAL, self::MODE_MIXED)))
625 $cumulativeOrderUserValue = $actionStoredData[
'cumulative_value'];
630 $cumulativeCalculator->setSumConfiguration(
632 'type_sum_period' => $sumConfiguration[
'type_sum_period'],
633 'sum_period_data' => array(
634 'order_start' => $sumConfiguration[
'sum_period_data'][
'discount_sum_order_start'],
635 'order_end' => $sumConfiguration[
'sum_period_data'][
'discount_sum_order_end'],
636 'period_value' => $sumConfiguration[
'sum_period_data'][
'discount_sum_period_value'],
637 'period_type' => $sumConfiguration[
'sum_period_data'][
'discount_sum_period_type'],
641 $cumulativeOrderUserValue = $cumulativeCalculator->calculate();
644 $rangeToApply =
null;
645 foreach ($ranges as $range)
647 if ($cumulativeOrderUserValue >= $range[
'sum'])
649 $rangeToApply = $range;
659 'VALUE' => -$rangeToApply[
'value'],
660 'UNIT' => $rangeToApply[
'type'],
663 if (!isset($action[
'VALUE']) || !isset($action[
'UNIT']))
666 $orderCurrency = static::getCurrency();
667 $value = (float)$action[
'VALUE'];
668 $limitValue = (int)$action[
'LIMIT_VALUE'];
669 $unit = (string)$action[
'UNIT'];
670 $currency = (isset($action[
'CURRENCY']) ? $action[
'CURRENCY'] : $orderCurrency);
672 if ($unit == self::VALUE_TYPE_FIX && $value < 0)
673 $maxBound = (isset($action[
'MAX_BOUND']) && $action[
'MAX_BOUND'] ==
'Y');
678 'VALUE' => abs($value),
679 'VALUE_ACTION' => $valueAction
696 if ($unit == self::VALUE_TYPE_FIX && $currency != $orderCurrency)
698 $value = \CCurrencyRates::ConvertCurrency($value, $currency, $orderCurrency);
701 $value = static::roundZeroValue($value);
707 if(!empty($limitValue))
717 if (empty($order[
'BASKET_ITEMS']) || !is_array($order[
'BASKET_ITEMS']))
720 static::enableBasketFilter();
722 if ($applyIfMoreProfitable)
724 if ($filter ===
null)
726 $filter =
function(){
730 $filter = self::wrapFilterToFindMoreProfitableForCumulative($filter, $unit, $value, $limitValue, $maxBound);
733 $filteredBasket = static::getBasketForApply($order[
'BASKET_ITEMS'], $filter, $action);
734 if (empty($filteredBasket))
738 $applyBasket = array_filter($filteredBasket,
'\Bitrix\Sale\Discount\Actions::filterBasketForAction');
739 unset($filteredBasket);
740 if (empty($applyBasket))
743 foreach ($applyBasket as $basketCode => $basketRow)
745 if ($applyIfMoreProfitable)
747 $basketRow[
'PRICE'] = $basketRow[
'BASE_PRICE'];
748 $basketRow[
'DISCOUNT_PRICE'] = 0;
762 $order[
'BASKET_ITEMS'][$basketCode] = $basketRow;
765 $rowActionDescription[
'BASKET_CODE'] = $basketCode;
766 $rowActionDescription[
'RESULT_VALUE'] = abs($calculateValue);
767 $rowActionDescription[
'RESULT_UNIT'] = $orderCurrency;
769 if(!empty($limitValue))
773 $rowActionDescription[
'LIMIT_UNIT'] = $orderCurrency;
774 $rowActionDescription[
'LIMIT_VALUE'] = $limitValue;
777 if ($applyIfMoreProfitable)
781 $rowActionDescription[
'REVERT_APPLY'] =
true;
784 static::setActionResult(self::RESULT_ENTITY_BASKET, $rowActionDescription);
785 unset($rowActionDescription);
789 unset($basketCode, $basketRow);
791 if (self::getUseMode() == self::MODE_CALCULATE)
795 'cumulative_value' => $cumulativeOrderUserValue,
801 private static function wrapFilterToFindMoreProfitableForCumulative($filter, $unit, $value, $limitValue, $maxBound)
803 if (!is_callable($filter))
808 return function($basketItem) use ($filter, $unit, $value, $limitValue, $maxBound) {
809 if (empty($basketItem[
'BASE_PRICE']))
814 if (empty($basketItem[
'DISCOUNT_PRICE']))
819 if (!$filter($basketItem))
824 $prevPrice = $basketItem[
'PRICE'];
825 $basketItem[
'PRICE'] = $basketItem[
'BASE_PRICE'];
834 return $newPrice < $prevPrice;
854 static::increaseApplyCounter();
856 if (!isset($action[
'VALUE']) || !isset($action[
'UNIT']))
858 if ($action[
'UNIT'] != self::VALUE_TYPE_PERCENT && $action[
'UNIT'] != self::VALUE_TYPE_FIX)
861 $orderCurrency = static::getCurrency();
862 $unit = (string)$action[
'UNIT'];
863 $value = (float)$action[
'VALUE'];
864 $currency = (isset($action[
'CURRENCY']) ? $action[
'CURRENCY'] : $orderCurrency);
866 if ($unit == self::VALUE_TYPE_FIX && $value < 0)
867 $maxBound = (isset($action[
'MAX_BOUND']) && $action[
'MAX_BOUND'] ==
'Y');
871 'VALUE' => abs($value),
885 $value = ($order[
'PRICE_DELIVERY'] * $value) / 100;
890 if ($currency != $orderCurrency)
891 $value = \CCurrencyRates::ConvertCurrency($value, $currency, $orderCurrency);
896 if (isset($order[
'CUSTOM_PRICE_DELIVERY']) && $order[
'CUSTOM_PRICE_DELIVERY'] ==
'Y')
899 !isset($order[
'PRICE_DELIVERY'])
901 static::roundZeroValue($order[
'PRICE_DELIVERY']) == 0
907 $value = static::roundValue($value, $order[
'CURRENCY']);
908 $value = static::roundZeroValue($value);
912 $resultValue = static::roundZeroValue($order[
'PRICE_DELIVERY'] + $value);
913 if ($maxBound && $resultValue < 0)
916 $value = -$order[
'PRICE_DELIVERY'];
919 if ($resultValue < 0)
922 if (!isset($order[
'PRICE_DELIVERY_DIFF']))
923 $order[
'PRICE_DELIVERY_DIFF'] = 0;
924 $order[
'PRICE_DELIVERY_DIFF'] -= $value;
925 $order[
'PRICE_DELIVERY'] = $resultValue;
944 static::increaseApplyCounter();
951 if (!is_callable($filter))
954 if (empty($order[
'BASKET_ITEMS']) || !is_array($order[
'BASKET_ITEMS']))
957 static::disableBasketFilter();
959 $itemsCopy = $order[
'BASKET_ITEMS'];
960 Main\Type\Collection::sortByColumn($itemsCopy,
'PRICE',
null,
null,
true);
961 $filteredBasket = static::getBasketForApply(
965 'GIFT_TITLE' =>
Loc::getMessage(
'BX_SALE_DISCOUNT_ACTIONS_SIMPLE_GIFT_DESCR')
970 static::enableBasketFilter();
972 if (empty($filteredBasket))
975 $applyBasket = array_filter($filteredBasket,
'\Bitrix\Sale\Discount\Actions::filterBasketForAction');
976 unset($filteredBasket);
977 if (empty($applyBasket))
980 foreach ($applyBasket as $basketCode => $basketRow)
984 $order[
'BASKET_ITEMS'][$basketCode] = $basketRow;
987 $rowActionDescription[
'BASKET_CODE'] = $basketCode;
988 static::setActionResult(self::RESULT_ENTITY_BASKET, $rowActionDescription);
989 unset($rowActionDescription);
991 unset($basketCode, $basketRow);
1005 switch (static::getUseMode())
1008 $result = (is_callable($filter) ? array_filter($basket, $filter) : $basket);
1012 switch (static::getApplyResultMode())
1015 $currentCounter = static::getApplyCounter();
1016 $basketCodeList = array_keys($basket);
1017 foreach ($basketCodeList as &$code)
1019 if (empty(self::$applyResult[
'BASKET'][$code]) || !is_array(self::$applyResult[
'BASKET'][$code]))
1021 if (!in_array($currentCounter, self::$applyResult[
'BASKET'][$code]))
1023 $result[$code] = $basket[$code];
1025 unset($code, $basketCodeList, $currentCounter);
1028 $basketCodeList = array_keys($basket);
1029 foreach ($basketCodeList as &$code)
1031 if (empty(self::$applyResult[
'BASKET'][$code]) || !is_array(self::$applyResult[
'BASKET'][$code]))
1033 foreach (self::$applyResult[
'BASKET'][$code] as $descr)
1035 if (static::compareBasketResultDescr($action, $descr))
1037 $result[$code] = $basket[$code];
1043 if (!isset($result[$code]))
1045 if (isset($action[
'GIFT_TITLE']))
1047 end(self::$applyResult[
'BASKET'][$code]);
1048 $descr = current(self::$applyResult[
'BASKET'][$code]);
1051 && $descr[
'DESCR'] == $action[
'GIFT_TITLE']
1053 $result[$code] = $basket[$code];
1058 unset($code, $basketCodeList);
1061 $basketCodeList = array_keys($basket);
1062 foreach ($basketCodeList as &$code)
1064 if (isset(self::$applyResult[
'BASKET'][$code]))
1065 $result[$code] = $basket[$code];
1067 unset($code, $basketCodeList);
1085 if (!static::isCalculateMode())
1087 if (empty($description) || !is_array($description) || !isset($description[
'ACTION_TYPE']))
1089 $actionType = $description[
'ACTION_TYPE'];
1091 $description = (isset($description[
'ACTION_DESCRIPTION']) ? $description[
'ACTION_DESCRIPTION'] :
'');
1093 $prepareResult = Sale\Discount\Formatter::prepareRow($actionType, $description);
1096 if ($prepareResult !==
null)
1101 if (!isset(self::$actionDescription[
'BASKET']))
1102 self::$actionDescription[
'BASKET'] = array();
1103 self::$actionDescription[
'BASKET'][static::getApplyCounter()] = $prepareResult;
1106 if (!isset(self::$actionDescription[
'DELIVERY']))
1107 self::$actionDescription[
'DELIVERY'] = array();
1108 self::$actionDescription[
'DELIVERY'][static::getApplyCounter()] = $prepareResult;
1112 unset($prepareResult);
1132 $prepareResult = Sale\Discount\Formatter::prepareRow($actionType,
$actionDescription);
1135 if ($prepareResult !==
null)
1140 if (!isset(self::$actionResult[
'BASKET']))
1141 self::$actionResult[
'BASKET'] = array();
1143 if (!isset(self::$actionResult[
'BASKET'][$basketCode]))
1144 self::$actionResult[
'BASKET'][$basketCode] = array();
1147 $prepareResult[
'REVERT_APPLY'] =
$actionResult[
'REVERT_APPLY'];
1148 self::$actionResult[
'BASKET'][$basketCode][static::getApplyCounter()] = $prepareResult;
1152 if (!isset(self::$actionResult[
'DELIVERY']))
1153 self::$actionResult[
'DELIVERY'] = array();
1154 self::$actionResult[
'DELIVERY'][static::getApplyCounter()] = $prepareResult;
1158 unset($prepareResult);
1171 if (empty($entityParams))
1173 if (array_key_exists(
'BASKET', self::$actionResult))
1174 unset(self::$actionResult[
'BASKET']);
1178 if (isset($entityParams[
'BASKET_CODE']) && array_key_exists($entityParams[
'BASKET_CODE'], self::$actionResult[
'BASKET']))
1179 unset(self::$actionResult[
'BASKET'][$entityParams[
'BASKET_CODE']]);
1183 if (array_key_exists(
'DELIVERY', self::$actionResult))
1184 unset(self::$actionResult[
'DELIVERY']);
1199 switch (static::getPercentMode())
1202 foreach ($basket as $basketRow)
1203 $summ += (float)$basketRow[
'BASE_PRICE'] * (
float)$basketRow[
'QUANTITY'];
1207 foreach ($basket as $basketRow)
1208 $summ += (float)$basketRow[
'PRICE'] * (
float)$basketRow[
'QUANTITY'];
1213 return static::roundZeroValue($summ > 0 ? ($value * 100) / $summ : 0);
1226 switch (static::getPercentMode())
1229 $value = ((float)$basketRow[
'BASE_PRICE'] * $percent) / 100;
1232 $value = ((float)$basketRow[
'PRICE'] * $percent) / 100;
1243 if(!$actionStructure || !is_array($actionStructure))
1248 if($actionStructure[
'CLASS_ID'] !=
'CondGroup')
1253 if(count($actionStructure[
'CHILDREN']) > 1)
1258 $action = reset($actionStructure[
'CHILDREN']);
1259 if($action[
'CLASS_ID'] !=
'ActSaleBsktGrp')
1264 $actionData = $action[
'DATA'];
1266 $configuration = array(
1267 'TYPE' => $actionData[
'Type'],
1268 'VALUE' => $actionData[
'Value'],
1269 'LIMIT_VALUE' => $actionData[
'Max']?: 0,
1271 switch ($actionData[
'Unit'])
1274 $configuration[
'VALUE_TYPE'] = Sale\Discount\Actions::VALUE_TYPE_FIX;
1277 $configuration[
'VALUE_TYPE'] = Sale\Discount\Actions::VALUE_TYPE_SUMM;
1280 $configuration[
'VALUE_TYPE'] = Sale\Discount\Actions::VALUE_TYPE_PERCENT;
1284 return $configuration;
1289 $actionStructure =
null;
1290 if (isset($discount[
'ACTIONS']) && !empty($discount[
'ACTIONS']))
1292 $actionStructure =
false;
1293 if (!is_array($discount[
'ACTIONS']))
1295 if (CheckSerializedData($discount[
'ACTIONS']))
1297 $actionStructure = unserialize($discount[
'ACTIONS'], [
'allowed_classes' =>
false]);
1302 $actionStructure = $discount[
'ACTIONS'];
1305 elseif(isset($discount[
'ACTIONS_LIST']) && is_array($discount[
'ACTIONS_LIST']))
1307 $actionStructure = $discount[
'ACTIONS_LIST'];
1310 return $actionStructure;
1326 if (!is_array($resultDescr) || !isset($resultDescr[
'TYPE']))
1329 $currency = (isset($action[
'CURRENCY']) ? $action[
'CURRENCY'] : static::getCurrency());
1330 $value = abs($action[
'VALUE']);
1332 $action[
'VALUE'] < 0
1337 switch ($resultDescr[
'TYPE'])
1341 $resultDescr[
'VALUE'] == $value
1342 && $resultDescr[
'VALUE_ACTION'] = $valueAction
1345 switch($action[
'UNIT'])
1353 && $resultDescr[
'VALUE_UNIT'] == $currency
1362 && $resultDescr[
'VALUE_UNIT'] == $currency
1370 $resultDescr[
'VALUE'] == $value
1371 && $resultDescr[
'VALUE_ACTION'] == $valueAction
1373 && $resultDescr[
'VALUE_UNIT'] == $currency
1378 unset($valueAction, $value, $currency);
1396 $calculateValue = $value;
1397 if ($unit == self::VALUE_TYPE_PERCENT)
1398 $calculateValue = static::percentToValue($basketRow, $calculateValue);
1399 $calculateValue = static::roundValue($calculateValue, $basketRow[
'CURRENCY']);
1401 if ($unit == self::VALUE_TYPE_CLOSEOUT)
1403 if ($calculateValue < $basketRow[
'PRICE'])
1405 $result = $calculateValue;
1406 $calculateValue = $result - $basketRow[
'PRICE'];
1415 if (!empty($limitValue) && $limitValue + $calculateValue <= 0)
1416 $calculateValue = -$limitValue;
1418 $result = static::roundZeroValue($basketRow[
'PRICE'] + $calculateValue);
1419 if ($maxBound && $result < 0)
1422 $calculateValue = -$basketRow[
'PRICE'];
1426 return [$calculateValue, $result];
1439 if (!isset($basketRow[
'DISCOUNT_PRICE']))
1440 $basketRow[
'DISCOUNT_PRICE'] = 0;
1441 $basketRow[
'PRICE'] = $price;
1442 $basketRow[
'DISCOUNT_PRICE'] += $discount;
static loadMessages($file)
static getMessage($code, $replace=null, $language=null)
static filterBasketForAction(array $item)
static fillCompatibleFields(array &$order)
static setActionDescription($type, $description)
static setActionStoredData(array $data)
static $actionDescription
static usedBasketFilter()
static clearEntityActionResult($entity, array $entityParams=array())
static applyToDelivery(array &$order, array $action)
static percentToValue($basketRow, $percent)
static getActionStoredData()
const APPLY_RESULT_MODE_DESCR
const PERCENT_FROM_CURRENT_PRICE
static getActionDescription()
const GIFT_SELECT_TYPE_ALL
const BASKET_APPLIED_FIELD
static increaseApplyCounter()
const PERCENT_FROM_BASE_PRICE
static clearApplyCounter()
static getActionConfiguration(array $discount)
static calculateDiscountPrice($value, $unit, array $basketRow, $limitValue, $maxBound)
static getActionStructure(array $discount)
const APPLY_RESULT_MODE_SIMPLE
static disableBasketFilter()
static applySimpleGift(array &$order, $filter)
static compareBasketResultDescr(array $action, $resultDescr)
static enableBasketFilter()
static getApplyResultMode()
static roundZeroValue($value)
static setUseMode($mode, array $config=array())
static applyToBasket(array &$order, array $action, $filter)
const APPLY_RESULT_MODE_COUNTER
static setActionResult($entity, array $actionResult)
const RESULT_ENTITY_ORDER
const RESULT_ENTITY_BASKET
const ACTION_TYPE_DISCOUNT
const GIFT_SELECT_TYPE_ONE
static setApplyResult(array $applyResult)
static applyCumulativeToBasket(array &$order, array $ranges, array $configuration=array(), $filter=null)
static getPercentByValue($basket, $value)
static fillDiscountPrice(array &$basketRow, $price, $discount)
const VALUE_TYPE_CLOSEOUT
static roundValue($value, $currency)
const APPLY_COUNTER_START
static getBasketForApply(array $basket, $filter, $action=array())
static setApplyResultMode($mode)
static checkUseMode(array $list)
static setStoredData(array $data)
const RESULT_ENTITY_DELIVERY