48 private static $instances = array();
165 if ($this->
isClone() && $cloneEntity->contains($this))
166 return $cloneEntity[$this];
168 $discountClone = clone $this;
169 $discountClone->isClone =
true;
171 if (!$cloneEntity->contains($this))
172 $cloneEntity[$this] = $discountClone;
176 if ($cloneEntity->contains($this->order))
181 if ($cloneEntity->contains($this->basket))
185 return $discountClone;
206 if ($state !==
true && $state !==
false)
208 $this->orderRefresh = $state;
238 if ($this->newOrder !==
null)
240 $this->newOrder =
true;
242 $this->newOrder = ((int)$this->
getOrder()->getId() <= 0);
252 return !empty($this->orderData);
265 $instanceIndex = static::getInstanceIndexByOrder(
$order);
266 if (!static::instanceExists($instanceIndex))
269 $discount = static::getInstance($instanceIndex);
270 $discount->order =
$order;
271 $discount->context =
new Context\User(
$order->getUserId());
272 $discount->initInstanceData();
275 return static::getInstance($instanceIndex);
293 'Could not build discounts from basket which has the order. You have to use buildFromOrder.'
301 $discount = static::getInstance($instanceIndex);
304 $discount->initInstanceData();
307 return static::getInstance($instanceIndex);
323 $instanceIndex = static::getInstanceIndexByBasket(
$basket);
324 if (!static::instanceExists($instanceIndex))
325 return static::buildFromOrder(
$order);
327 $newInstanceIndex = static::getInstanceIndexByOrder(
$order);
328 if (!static::instanceExists($newInstanceIndex))
331 $discount = static::getInstance($instanceIndex);
332 $discount->basket =
null;
333 $discount->order =
$order;
334 $discount->context =
new Context\User(
$order->getUserId());
335 $discount->initInstanceFromOrder();
337 static::migrateInstance($instanceIndex, $newInstanceIndex);
341 static::removeInstance($instanceIndex);
343 return static::getInstance($newInstanceIndex);
381 $this->executeModuleFilter = $moduleList;
392 $extendedMode = ($extendedMode ===
true);
396 self::APPLY_MODE_ADD =>
Loc::getMessage(
'BX_SALE_DISCOUNT_APPLY_MODE_ADD_EXT'),
397 self::APPLY_MODE_LAST =>
Loc::getMessage(
'BX_SALE_DISCOUNT_APPLY_MODE_LAST_EXT'),
398 self::APPLY_MODE_DISABLE =>
Loc::getMessage(
'BX_SALE_DISCOUNT_APPLY_MODE_DISABLE_EXT'),
399 self::APPLY_MODE_FULL_LAST =>
Loc::getMessage(
'BX_SALE_DISCOUNT_APPLY_MODE_FULL_LAST'),
400 self::APPLY_MODE_FULL_DISABLE =>
Loc::getMessage(
'BX_SALE_DISCOUNT_APPLY_MODE_FULL_DISABLE')
404 self::APPLY_MODE_ADD,
405 self::APPLY_MODE_LAST,
406 self::APPLY_MODE_DISABLE,
407 self::APPLY_MODE_FULL_LAST,
408 self::APPLY_MODE_FULL_DISABLE
421 if ((
string)Main\
Config\Option::get(
'sale',
'use_sale_discount_only') !=
'Y')
423 $applyMode = (int)Main\
Config\Option::get(
'sale',
'discount_apply_mode');
424 if (!in_array($applyMode, self::getApplyModeList(
false)))
425 $applyMode = self::APPLY_MODE_ADD;
435 public function calculate()
444 $this->discountsCache = array();
445 $this->couponsCache = array();
459 $couponClassName::useSavedCouponsForApply(
true);
463 $this->orderData =
null;
465 if (!$orderResult->isSuccess())
468 $result->addErrors($orderResult->getErrors());
478 unset($couponClassName);
490 $calculateResult = $this->calculateFull();
493 $calculateResult =
new Result;
494 $calculateResult->addError(
new Main\Entity\EntityError(
500 if (!$calculateResult->isSuccess())
501 $result->addErrors($calculateResult->getErrors());
504 unset($calculateResult);
525 if (!empty($this->applyResult[
'DISCOUNT_LIST']))
527 if (!empty($this->applyResult[
'BASKET']) && is_array($this->applyResult[
'BASKET']))
529 foreach ($this->applyResult[
'BASKET'] as $discountList)
531 if (empty($discountList) || !is_array($discountList))
533 foreach ($discountList as $orderDiscountId => $apply)
536 $this->applyResult[
'DISCOUNT_LIST'][$orderDiscountId] =
'Y';
538 unset($apply, $orderDiscountId);
540 unset($discountList);
553 $extMode = ($extMode ===
true);
570 unset($result[
'APPLY_BLOCKS']);
584 public function verify()
595 if (empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter]))
601 $checkCoupons = $couponClassName::verifyApplied();
602 if (!$checkCoupons->isSuccess())
604 $result->addError(
new Main\Error(
607 $errors = $checkCoupons->getErrors();
608 $row = reset($errors);
609 foreach ($row->getCustomData() as $coupon => $description)
611 $result->addError(
new Main\Error(
612 $coupon.
' : '.$description
615 unset($coupon, $description, $row, $errors);
617 unset($checkCoupons, $couponClassName);
627 public function save()
630 $result =
new Result;
633 $orderId = (int)$this->
getOrder()->getId();
643 $saveResult = $this->saveFull();
646 $saveResult = $this->saveApply();
652 $saveResult =
new Result;
653 $saveResult->addError(
new Main\Entity\EntityError(
658 if (!$saveResult->isSuccess())
660 $result->addErrors($saveResult->getErrors());
669 $orderHistory = $registry->getOrderHistoryClassName();
670 $orderHistory::addLog(
677 $orderHistory::SALE_ORDER_HISTORY_LOG_LEVEL_1
690 $orderHistory = $registry->getOrderHistoryClassName();
691 $orderHistory::collectEntityFields(
'DISCOUNT', $orderId);
699 return $this->valid ===
true;
704 if (!is_bool($value))
706 $this->valid = $value;
714 protected function initInstanceData()
716 $this->orderData =
null;
718 $this->entityResultCache = array();
722 $orderDiscountConfig = array(
724 'CURRENCY' => $this->getCurrency()
728 $storageClassName::setManagerConfig($orderDiscountConfig);
729 unset($storageClassName, $orderDiscountConfig);
764 return (
string)Main\Config\Option::get(
'sale',
'use_sale_discount_only') ==
'Y';
766 return (isset($this->saleOptions[
'SALE_DISCOUNT_ONLY']) && $this->saleOptions[
'SALE_DISCOUNT_ONLY'] ==
'Y');
777 return $this->
getOrder()->getBasket();
810 $result = ($this->basket instanceof
Basket && $this->basket->count() > 0);
829 elseif ($this->
getOrder()->getCalculateType() == $this->
getOrder()::SALE_ORDER_CALC_TYPE_REFRESH)
846 $orderId = $this->
getOrder()->getId();
849 $this->fillEmptyOrderData();
851 $basketResult = $this->loadBasket();
852 if (!$basketResult->isSuccess())
854 $result->addErrors($basketResult->getErrors());
857 unset($basketResult);
861 $basketResult = $this->getBasketTables();
862 if (!$basketResult->isSuccess())
864 $result->addErrors($basketResult->getErrors());
867 unset($basketResult);
870 $this->loadOrderConfig();
877 $dataResult = $this->loadBasketStoredData();
878 if (!$dataResult->isSuccess())
879 $result->addErrors($dataResult->getErrors());
890 protected function fillEmptyOrderData()
897 'USER_ID' => $this->context->getUserId(),
898 'USER_GROUPS' => $this->context->getUserGroups(),
899 'SITE_ID' => $siteId,
901 'ORDER_PRICE' =>
$basket->getBasePrice(),
902 'ORDER_WEIGHT' =>
$basket->getWeight(),
903 'CURRENCY' => $this->getCurrency(),
904 'PERSON_TYPE_ID' => 0,
905 'RECURRING_ID' =>
null,
906 'BASKET_ITEMS' => [],
914 $this->orderData[
'ID'] =
$order->getId();
915 $this->orderData[
'USER_ID'] =
$order->getUserId();
916 $this->orderData[
'ORDER_PRICE'] =
$order->getBasePrice();
917 $this->orderData[
'PERSON_TYPE_ID'] =
$order->getPersonTypeId();
918 $this->orderData[
'RECURRING_ID'] =
$order->getField(
'RECURRING_ID');
921 $propertyCollection =
$order->getPropertyCollection();
923 foreach ($propertyCollection as $orderProperty)
924 $this->orderData[
'ORDER_PROP'][$orderProperty->getPropertyId()] = $orderProperty->getValue();
925 unset($orderProperty);
928 $this->orderData[$propertyCode] =
'';
929 $orderProperty = $propertyCollection->getAttribute($attribute);
931 $this->orderData[$propertyCode] = $orderProperty->getValue();
932 unset($orderProperty);
934 unset($propertyCode, $attribute);
935 unset($propertyCollection);
949 protected function loadBasket()
951 $result =
new Result;
954 throw new Main\ObjectNotFoundException(
'Entity "Basket" not found');
961 foreach (
$basket as $basketItem)
963 if (!$basketItem->canBuy())
965 $this->orderData[
'BASKET_ITEMS'][$basketItem->getBasketCode()] = $this->
getBasketItemFields($basketItem);
980 $item = $basketItem->getFieldValues();
981 $item[
'BASE_PRICE'] = $basketItem->
getField(
'BASE_PRICE');
982 unset($item[
'DATE_INSERT']);
983 unset($item[
'DATE_UPDATE']);
984 unset($item[
'DATE_REFRESH']);
985 $item[
'PROPERTIES'] = $basketItem->getPropertyCollection()->getPropertyValues();
986 if (!isset($item[
'DISCOUNT_PRICE']))
987 $item[
'DISCOUNT_PRICE'] = 0;
988 if ($item[
'BASE_PRICE'] ===
null)
989 $item[
'BASE_PRICE'] = $item[
'PRICE'] + $item[
'DISCOUNT_PRICE'];
990 $item[
'ACTION_APPLIED'] =
'N';
999 protected function loadOrderConfig()
1006 || $this->
getUseMode() == self::USE_MODE_FULL
1012 $entityData = $storageClassName::loadOrderStoredDataFromDb(
1014 $storageClassName::STORAGE_TYPE_ORDER_CONFIG
1022 if (isset($entityData[
'OLD_ORDER']))
1026 $this->loadRoundConfig();
1039 'USE_BASE_PRICE' => Main\
Config\Option::get(
'sale',
'get_discount_percent_from_base_price'),
1040 'SALE_DISCOUNT_ONLY' => Main\
Config\Option::get(
'sale',
'use_sale_discount_only'),
1041 'APPLY_MODE' => Main\
Config\Option::get(
'sale',
'discount_apply_mode')
1063 if (empty($config) || !is_array($config))
1065 if (empty($config[
'OPTIONS']) || !is_array($config[
'OPTIONS']))
1078 if (!empty($data[
'OPTIONS']) && is_array($data[
'OPTIONS']))
1080 foreach (array_keys($this->saleOptions) as $key)
1082 if (isset($data[
'OPTIONS'][$key]))
1083 $this->saleOptions[$key] = $data[
'OPTIONS'][$key];
1094 protected function loadOrderDiscounts()
1097 $this->discountsCache = array();
1098 $this->couponsCache = array();
1114 $this->reverseBasketTable,
1115 $this->orderData[
'BASKET_ITEMS']
1123 if (!empty($applyResultData[
'DISCOUNT_LIST']))
1125 foreach ($applyResultData[
'DISCOUNT_LIST'] as $orderDiscountId => $discountData)
1127 $discountData[
'ACTIONS_DESCR_DATA'] =
false;
1128 if (!empty($discountData[
'ACTIONS_DESCR']) && is_array($discountData[
'ACTIONS_DESCR']))
1130 $discountData[
'ACTIONS_DESCR_DATA'] = $discountData[
'ACTIONS_DESCR'];
1131 $discountData[
'ACTIONS_DESCR'] = $this->
formatDescription($discountData[
'ACTIONS_DESCR']);
1135 $discountData[
'ACTIONS_DESCR'] =
false;
1137 if (empty($discountData[
'ACTIONS_DESCR']))
1139 $discountData[
'ACTIONS_DESCR'] =
false;
1140 $discountData[
'ACTIONS_DESCR_DATA'] =
false;
1142 $this->discountsCache[$orderDiscountId] = $discountData;
1144 unset($orderDiscountId, $discountData);
1146 if (!empty($applyResultData[
'COUPON_LIST']))
1147 $this->couponsCache = $applyResultData[
'COUPON_LIST'];
1149 $this->discountResultCounter = 0;
1150 $this->discountResult[
'APPLY_BLOCKS'] = $applyResultData[
'APPLY_BLOCKS'];
1151 if (!empty($this->discountResult[
'APPLY_BLOCKS']))
1153 foreach ($this->discountResult[
'APPLY_BLOCKS'] as $counter => $applyBlock)
1155 if (!empty($applyBlock[
'BASKET']))
1157 foreach ($applyBlock[
'BASKET'] as $discountList)
1159 foreach ($discountList as $discount)
1161 if ($discount[
'COUPON_ID'] ==
'')
1163 $couponClassName::setApplyByProduct($discount, array($discount[
'COUPON_ID']));
1166 unset($discountList);
1169 if (!empty($applyBlock[
'ORDER']))
1171 foreach ($applyBlock[
'ORDER'] as $discount)
1173 if ($discount[
'COUPON_ID'] !=
'')
1174 $couponClassName::setApply($discount[
'COUPON_ID'], $discount[
'RESULT']);
1179 $this->discountResultCounter = $counter + 1;
1181 unset($counter, $applyBlock);
1184 if (!empty($applyResultData[
'STORED_ACTION_DATA']) && is_array($applyResultData[
'STORED_ACTION_DATA']))
1185 $this->discountStoredActionData = $applyResultData[
'STORED_ACTION_DATA'];
1197 protected function loadBasketStoredData()
1199 $result =
new Result;
1201 $this->basketItemsData = [];
1212 $basketData = $storageClassName::loadStoredDataFromDb(
1214 $storageClassName::STORAGE_TYPE_BASKET_ITEM
1217 if (empty($basketData))
1221 if (!empty($basketCodeList))
1223 foreach ($basketCodeList as $basketCode)
1225 if (!isset($this->forwardBasketTable[$basketCode]))
1227 $basketId = $this->forwardBasketTable[$basketCode];
1228 if (!isset($basketData[$basketId]) || !is_array($basketData[$basketId]))
1230 $this->addBasketItemValues($basketCode, $basketData[$basketId]);
1232 unset($basketId, $basketCode);
1234 unset($basketCodeList);
1235 unset($basketData, $storageClassName);
1251 if (!isset($this->basketItemsData[$code]))
1253 return (isset($this->basketItemsData[$code][$field]) ? $this->basketItemsData[$code][$field] :
null);
1266 if (!isset($this->basketItemsData[$code]) || empty($fields))
1270 foreach ($fields as $fieldName)
1272 $result[$fieldName] = (
1273 isset($this->basketItemsData[$code][$fieldName])
1274 ? $this->basketItemsData[$code][$fieldName]
1287 protected function calculateFull()
1293 $this->discountIds = array();
1294 Discount\Actions::setUseMode(
1297 'USE_BASE_PRICE' => $this->saleOptions[
'USE_BASE_PRICE'],
1298 'SITE_ID' => $this->orderData[
'SITE_ID'],
1299 'CURRENCY' => $this->orderData[
'CURRENCY']
1304 $this->getRoundForBasePrices();
1309 $couponClassName::clearApply();
1310 $basketDiscountResult = $this->calculateFullBasketDiscount();
1311 if (!$basketDiscountResult->isSuccess())
1312 $result->addErrors($basketDiscountResult->getErrors());
1313 unset($basketDiscountResult);
1314 if (!$result->isSuccess())
1317 if ($this->
isRoundMode(self::ROUND_MODE_BASKET_DISCOUNT))
1318 $this->roundFullBasketPrices();
1325 if (!$executeResult->isSuccess())
1326 $result->addErrors($executeResult->getErrors());
1327 unset($executeResult);
1328 if (!$result->isSuccess())
1332 if ($this->
isRoundMode(self::ROUND_MODE_FINAL_PRICE))
1333 $this->roundFullBasketPrices();
1352 if (!empty($this->discountResult[
'APPLY_BLOCKS']))
1354 Discount\Actions::setUseMode(
1357 'USE_BASE_PRICE' => $this->saleOptions[
'USE_BASE_PRICE'],
1358 'SITE_ID' => $this->orderData[
'SITE_ID'],
1359 'CURRENCY' => $this->orderData[
'CURRENCY']
1365 foreach (array_keys($this->discountResult[
'APPLY_BLOCKS']) as $counter)
1367 $this->discountResultCounter = $counter;
1369 if (!$blockResult->isSuccess())
1371 $result->addErrors($blockResult->getErrors());
1372 unset($blockResult);
1376 unset($blockResult);
1379 $this->discountResultCounter = $currentCounter;
1380 unset($currentCounter);
1383 if ($result->isSuccess())
1385 Discount\Actions::setUseMode(
1388 'USE_BASE_PRICE' => $this->saleOptions[
'USE_BASE_PRICE'],
1389 'SITE_ID' => $this->orderData[
'SITE_ID'],
1390 'CURRENCY' => $this->orderData[
'CURRENCY']
1396 $couponsResult = $this->calculateApplyAdditionalCoupons();
1397 if (!$couponsResult->isSuccess())
1399 $result->addErrors($couponsResult->getErrors());
1400 unset($couponsResult);
1403 unset($couponsResult);
1405 if ($this->
isRoundMode(self::ROUND_MODE_FINAL_PRICE))
1406 $this->roundChangedBasketPrices();
1427 if (!empty($this->discountResult[
'APPLY_BLOCKS']))
1429 Discount\Actions::setUseMode(
1432 'USE_BASE_PRICE' => $this->saleOptions[
'USE_BASE_PRICE'],
1433 'SITE_ID' => $this->orderData[
'SITE_ID'],
1434 'CURRENCY' => $this->orderData[
'CURRENCY']
1440 foreach (array_keys($this->discountResult[
'APPLY_BLOCKS']) as $counter)
1442 $this->discountResultCounter = $counter;
1444 if (!$blockResult->isSuccess())
1446 $result->addErrors($blockResult->getErrors());
1447 unset($blockResult);
1451 unset($blockResult);
1454 $this->discountResultCounter = $currentCounter;
1455 unset($currentCounter);
1458 if ($result->isSuccess())
1460 Discount\Actions::setUseMode(
1463 'USE_BASE_PRICE' => $this->saleOptions[
'USE_BASE_PRICE'],
1464 'SITE_ID' => $this->orderData[
'SITE_ID'],
1465 'CURRENCY' => $this->orderData[
'CURRENCY']
1471 $this->getRoundForBasePrices();
1474 $basketDiscountResult = $this->calculateFullBasketDiscount();
1475 if (!$basketDiscountResult->isSuccess())
1477 $result->addErrors($basketDiscountResult->getErrors());
1478 unset($basketDiscountResult);
1481 unset($basketDiscountResult);
1483 if ($this->
isRoundMode(self::ROUND_MODE_BASKET_DISCOUNT))
1484 $this->roundFullBasketPrices();
1486 $couponsResult = $this->calculateApplyAdditionalCoupons();
1487 if (!$couponsResult->isSuccess())
1489 $result->addErrors($couponsResult->getErrors());
1490 unset($couponsResult);
1493 unset($couponsResult);
1495 if ($this->
isRoundMode(self::ROUND_MODE_FINAL_PRICE))
1496 $this->roundChangedBasketPrices();
1507 protected function saveFull()
1512 $orderId = $this->
getOrder()->getId();
1523 $basketResult = $this->getBasketTables();
1524 if (!$basketResult->isSuccess())
1527 $result->addErrors($basketResult->getErrors());
1533 $couponClassName::finalApply();
1534 $couponsResult = $couponClassName::saveApplied();
1535 if (!$couponsResult->isSuccess())
1538 $error =
new Main\Error(
1539 $this->prepareCouponsResult($couponsResult)
1541 $result->addError($error);
1542 $markerResult =
new Result();
1543 $markerResult->addWarning($error);
1544 $markerResult->addWarning(
new Main\Error(
1547 $entityMarkerClassName::addMarker(
1552 unset($markerResult, $error);
1557 $couponsResult = $this->saveCoupons();
1558 if (!$couponsResult->isSuccess())
1561 $result->addErrors($couponsResult->getErrors());
1567 $storageClassName::deleteByOrder($orderId);
1569 $lastApplyBlockResult = $this->saveLastApplyBlock();
1570 if (!$lastApplyBlockResult->isSuccess())
1573 $result->addErrors($lastApplyBlockResult->getErrors());
1575 unset($lastApplyBlockResult);
1581 $dataResult = $storageClassName::saveOrderStoredData(
1583 $storageClassName::STORAGE_TYPE_ORDER_CONFIG,
1586 if (!$dataResult->isSuccess())
1588 $result->addError(
new Main\Entity\EntityError(
1593 unset($dataResult, $config);
1596 'MODE' => $this->roundApplyMode,
1597 'CONFIG' => $this->roundApplyConfig
1599 $dataResult = $storageClassName::saveOrderStoredData(
1601 $storageClassName::STORAGE_TYPE_ROUND_CONFIG,
1603 array(
'ALLOW_UPDATE' =>
'Y')
1605 if (!$dataResult->isSuccess())
1607 $result->addError(
new Main\Entity\EntityError(
1612 unset($dataResult, $config);
1614 if (!empty($this->discountStoredActionData))
1616 $dataResult = $storageClassName::saveOrderStoredData(
1618 $storageClassName::STORAGE_TYPE_DISCOUNT_ACTION_DATA,
1619 $this->discountStoredActionData,
1620 array(
'ALLOW_UPDATE' =>
'Y')
1622 if (!$dataResult->isSuccess())
1624 $result->addError(
new Main\Entity\EntityError(
1632 $dataResult = $this->saveBasketStoredData($this->
getBasketCodes(
true));
1633 if (!$dataResult->isSuccess())
1635 $result->addErrors($dataResult->getErrors());
1642 if ($couponClassName::usedByManager())
1643 $couponClassName::clear(
true);
1649 protected function prepareCouponsResult(Main\Result $couponsResult): string
1652 $errorList = $couponsResult->getErrors();
1653 $error = reset($errorList);
1656 $list = $error->getCustomData();
1657 foreach (array_keys($list) as $coupon)
1659 $commonList[] = $coupon.
' - '.$list[$coupon];
1661 return $error->getMessage().
': '.implode(
', ', $commonList);
1673 'OPTIONS' => $this->saleOptions,
1683 protected function saveBasketStoredData(array $basketCodeList)
1686 if (empty($basketCodeList))
1693 foreach ($basketCodeList as $basketCode)
1695 if (!isset($this->basketItemsData[$basketCode]))
1697 $data = $this->prepareBasketItemStoredData($basketCode);
1700 $basketId = $this->forwardBasketTable[$basketCode];
1701 $itemsData[$basketId] = [
1702 'ENTITY_ID' => $basketId,
1703 'ENTITY_VALUE' => $basketId,
1704 'ENTITY_DATA' => $data
1707 unset($data, $basketCode);
1708 if (!empty($itemsData))
1710 $orderId = $this->
getOrder()->getId();
1713 $dataResult = $storageClassName::saveStoredDataBlock(
1715 $storageClassName::STORAGE_TYPE_BASKET_ITEM,
1717 [
'ALLOW_UPDATE' =>
'Y',
'DELETE_MISSING' =>
'Y']
1719 if (!$dataResult->isSuccess())
1721 $result->addError(
new Main\Entity\EntityError(
1726 unset($dataResult, $storageClassName);
1738 protected function saveApply()
1740 $result =
new Result;
1743 $orderId = $this->
getOrder()->getId();
1748 $basketResult = $this->getBasketTables();
1749 if (!$basketResult->isSuccess())
1752 $result->addErrors($basketResult->getErrors());
1760 $rulesList = array();
1761 $roundList = array();
1762 foreach ($this->discountResult[
'APPLY_BLOCKS'] as $counter => $applyBlock)
1764 if ($counter == $this->discountResultCounter)
1767 if (!empty($applyBlock[
'BASKET']))
1769 foreach ($applyBlock[
'BASKET'] as $basketCode => $discountList)
1771 foreach ($discountList as $discount)
1773 if (!isset($discount[
'RULE_ID']) || (
int)$discount[
'RULE_ID'] < 0)
1776 $result->addError(
new Main\Entity\EntityError(
1782 $rulesList[] = array(
1783 'RULE_ID' => $discount[
'RULE_ID'],
1784 'APPLY' => $discount[
'RESULT'][
'APPLY'],
1785 'DESCR_ID' => (isset($discount[
'RULE_DESCR_ID']) ? (
int)$discount[
'RULE_DESCR_ID'] : 0),
1786 'DESCR' => $discount[
'RESULT'][
'DESCR_DATA'][
'BASKET'],
1791 unset($basketCode, $discountList);
1794 if (!empty($applyBlock[
'ORDER']))
1796 foreach ($applyBlock[
'ORDER'] as $discount)
1798 if (!empty($discount[
'RESULT'][
'BASKET']))
1800 foreach ($discount[
'RESULT'][
'BASKET'] as $basketCode => $applyData)
1802 if (!isset($applyData[
'RULE_ID']) || (
int)$applyData[
'RULE_ID'] < 0)
1805 $result->addError(
new Main\Entity\EntityError(
1812 'RULE_ID' => $applyData[
'RULE_ID'],
1813 'APPLY' => $applyData[
'APPLY'],
1814 'DESCR_ID' => (isset($applyData[
'RULE_DESCR_ID']) ? (
int)$applyData[
'RULE_DESCR_ID'] : 0),
1815 'DESCR' => $applyData[
'DESCR_DATA'],
1817 if (!$discount[
'ACTION_BLOCK_LIST'])
1818 $ruleData[
'ACTION_BLOCK_LIST'] = $applyData[
'ACTION_BLOCK_LIST'];
1819 $rulesList[] = $ruleData;
1822 unset($basketCode, $applyData);
1824 if (!empty($discount[
'RESULT'][
'DELIVERY']))
1826 if (!isset($discount[
'RESULT'][
'DELIVERY'][
'RULE_ID']) || (
int)$discount[
'RESULT'][
'DELIVERY'][
'RULE_ID'] < 0)
1829 $result->addError(
new Main\Entity\EntityError(
1836 'RULE_ID' => $discount[
'RESULT'][
'DELIVERY'][
'RULE_ID'],
1837 'APPLY' => $discount[
'RESULT'][
'DELIVERY'][
'APPLY'],
1838 'DESCR_ID' => (isset($discount[
'RESULT'][
'DELIVERY'][
'RULE_DESCR_ID']) ? (
int)$discount[
'RESULT'][
'DELIVERY'][
'RULE_DESCR_ID'] : 0),
1839 'DESCR' => $discount[
'RESULT'][
'DELIVERY'][
'DESCR_DATA']
1841 $rulesList[] = $ruleData;
1848 if (!empty($applyBlock[
'BASKET_ROUND']))
1850 foreach ($applyBlock[
'BASKET_ROUND'] as $row)
1852 $roundList[] = array(
1853 'RULE_ID' => $row[
'RULE_ID'],
1863 $ruleResult = $storageClassName::updateResultBlock($orderId, $rulesList);
1864 if (!$ruleResult->isSuccess())
1869 $roundResult = $storageClassName::updateRoundBlock($orderId, $roundList);
1870 if (!$roundResult->isSuccess())
1874 unset($roundResult);
1879 if (!empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter]))
1881 $couponClassName::finalApply();
1882 $couponClassName::saveApplied();
1883 $couponsResult = $this->saveCoupons();
1884 if (!$couponsResult->isSuccess())
1887 $result->addErrors($couponsResult->getErrors());
1892 $lastApplyBlockResult = $this->saveLastApplyBlock();
1893 if (!$lastApplyBlockResult->isSuccess())
1896 $result->addErrors($lastApplyBlockResult->getErrors());
1898 unset($lastApplyBlockResult);
1905 if (!empty($this->discountStoredActionData))
1907 $dataResult = $storageClassName::saveOrderStoredData(
1909 $storageClassName::STORAGE_TYPE_DISCOUNT_ACTION_DATA,
1910 $this->discountStoredActionData,
1911 array(
'ALLOW_UPDATE' =>
'Y')
1913 if (!$dataResult->isSuccess())
1915 $result->addError(
new Main\Entity\EntityError(
1926 if ($couponClassName::usedByManager())
1927 $couponClassName::clear(
true);
1940 $result = $this->saveApply();
1942 if ($result->isSuccess())
1944 $basketCodeList = array_merge(
1948 $dataResult = $this->saveBasketStoredData($basketCodeList);
1949 if (!$dataResult->isSuccess())
1951 $result->addErrors($dataResult->getErrors());
1953 unset($dataResult, $basketCodeList);
1964 protected function saveCoupons()
1969 if (!empty($this->couponsCache))
1974 $orderId = $this->
getOrder()->getId();
1975 foreach ($this->couponsCache as $orderCouponId => $couponData)
1977 if ($couponData[
'ID'] > 0)
1979 $fields = $couponData;
1980 $fields[
'ORDER_ID'] = $orderId;
1981 $couponResult = $storageClassName::saveCoupon($fields);
1982 if (!$couponResult->isSuccess())
1984 $result->addErrors($couponResult->getErrors());
1985 unset($couponResult);
1988 $this->couponsCache[$orderCouponId][
'ID'] = $couponResult->getId();
1989 unset($couponResult);
1992 unset($storageClassName);
2003 protected function saveLastApplyBlock()
2005 $result =
new Result;
2007 $orderId = $this->
getOrder()->getId();
2013 $rulesList = array();
2014 if (!empty($applyBlock[
'BASKET']))
2016 foreach ($applyBlock[
'BASKET'] as $basketCode => $discountList)
2019 'ENTITY_TYPE' => self::ENTITY_BASKET_ITEM,
2020 'ENTITY_CODE' => $basketCode
2022 if ($commonFields ===
null)
2024 foreach ($discountList as $discount)
2026 $rulesList[] = $commonFields + [
2027 'ORDER_DISCOUNT_ID' => $discount[
'DISCOUNT_ID'],
2028 'COUPON_ID' => $discount[
'COUPON_ID'],
2029 'APPLY' => $discount[
'RESULT'][
'APPLY'],
2030 'DESCR' => $discount[
'RESULT'][
'DESCR_DATA']
2035 unset($discount, $commonFields, $discountList, $basketCode);
2037 if (!empty($applyBlock[
'ORDER']))
2039 foreach ($applyBlock[
'ORDER'] as $discount)
2041 if (!empty($discount[
'RESULT'][
'BASKET']))
2043 foreach ($discount[
'RESULT'][
'BASKET'] as $basketCode => $applyData)
2046 'ENTITY_TYPE' => self::ENTITY_BASKET_ITEM,
2047 'ENTITY_CODE' => $basketCode
2049 if ($commonFields ===
null)
2051 $rulesList[] = $commonFields + [
2052 'ORDER_DISCOUNT_ID' => $discount[
'DISCOUNT_ID'],
2053 'COUPON_ID' => $discount[
'COUPON_ID'],
2054 'APPLY' => $applyData[
'APPLY'],
2055 'ACTION_BLOCK_LIST' => $applyData[
'ACTION_BLOCK_LIST'],
2056 'DESCR' => $applyData[
'DESCR_DATA']
2059 unset($commonFields, $basketCode, $applyData);
2061 if (!empty($discount[
'RESULT'][
'DELIVERY']))
2064 'ENTITY_TYPE' => self::ENTITY_DELIVERY,
2065 'ENTITY_CODE' => $discount[
'RESULT'][
'DELIVERY'][
'DELIVERY_ID']
2067 if ($commonFields ===
null)
2069 $rulesList[] = $commonFields + [
2070 'ORDER_DISCOUNT_ID' => $discount[
'DISCOUNT_ID'],
2071 'COUPON_ID' => $discount[
'COUPON_ID'],
2072 'APPLY' => $discount[
'RESULT'][
'DELIVERY'][
'APPLY'],
2073 'DESCR' => $discount[
'RESULT'][
'DELIVERY'][
'DESCR_DATA']
2075 unset($commonFields);
2081 if (!empty($rulesList))
2084 $blockResult = $storageClassName::addResultBlock($orderId, $rulesList);
2085 if (!$blockResult->isSuccess())
2087 $result->addError(
new Main\Entity\EntityError(
2092 unset($blockResult);
2096 if (!empty($applyBlock[
'BASKET_ROUND']))
2098 $roundList = array();
2099 foreach ($applyBlock[
'BASKET_ROUND'] as $basketCode => $roundData)
2102 'ENTITY_TYPE' => self::ENTITY_BASKET_ITEM,
2103 'ENTITY_CODE' => $basketCode
2105 if ($commonFields ===
null)
2107 $roundList[] = $commonFields + [
2108 'APPLY' => $roundData[
'APPLY'],
2109 'ROUND_RULE' => $roundData[
'ROUND_RULE']
2112 unset($commonFields, $roundData, $basketCode);
2113 if (!empty($roundList))
2116 $blockResult = $storageClassName::addRoundBlock($orderId, $roundList);
2117 if (!$blockResult->isSuccess())
2119 $result->addError(
new Main\Entity\EntityError(
2124 unset($blockResult);
2145 foreach (array_keys($rows) as $index)
2148 if (isset($rows[$index][
'ORDER_DISCOUNT_ID']))
2149 $rows[$index][
'MODULE_ID'] = $this->discountsCache[$rows[$index][
'ORDER_DISCOUNT_ID']][
'MODULE_ID'];
2150 if (isset($rows[$index][
'COUPON_ID']))
2151 $rows[$index][
'COUPON_ID'] = ($rows[$index][
'COUPON_ID'] !=
'' ? $this->couponsCache[$rows[$index][
'COUPON_ID']][
'ID'] : 0);
2164 !isset($this->currentStep[
'cacheIndex'])
2165 || !isset($this->saleDiscountCache[$this->saleDiscountCacheKey][$this->currentStep[
'cacheIndex']])
2172 if (empty($this->saleDiscountCache[$this->saleDiscountCacheKey][$this->currentStep[
'cacheIndex']][$key]))
2177 if (!array_key_exists($executeKey, $discountLink))
2181 $evalCode =
'$checkOrder='.$discountLink[$key].
';';
2182 if (PHP_MAJOR_VERSION >= 7)
2188 catch (\ParseError $e)
2190 $this->showAdminError();
2199 if (!is_callable($checkOrder))
2201 $result = $checkOrder($this->orderData);
2206 if (!is_callable($discountLink[$executeKey]))
2211 unset($discountLink);
2224 Discount\Actions::clearApplyCounter();
2227 isset($this->currentStep[
'discountIndex'])
2228 ? $this->discountsCache[$this->currentStep[
'discountId']]
2229 : $this->currentStep[
'discount']
2231 if (isset($this->currentStep[
'discountIndex']))
2233 if (!empty($discount[
'APPLICATION']) && !$this->
loadDiscountModules($this->discountsCache[$this->currentStep[
'discountId']][
'MODULES']))
2235 $discount[
'APPLICATION'] =
null;
2243 if (!empty($discount[
'APPLICATION']))
2246 if (!array_key_exists($executeKey, $discount))
2248 $discount[$executeKey] =
null;
2250 $evalCode =
'$discount["'.$executeKey.
'"] = '.$discount[
'APPLICATION'].
';';
2251 if (PHP_MAJOR_VERSION >= 7)
2257 catch (\ParseError $e)
2259 $this->showAdminError();
2268 if (is_callable($discount[$executeKey]))
2273 $currentUseMode == self::USE_MODE_APPLY
2274 || $currentUseMode == self::USE_MODE_MIXED
2283 switch ($currentUseMode)
2287 $actionsResult = $this->calculateFullSaleDiscountResult();
2291 $actionsResult = $this->calculateApplySaleDiscountResult();
2294 $actionsResult =
new Result;
2297 if (!$actionsResult->isSuccess())
2298 $result->addErrors($actionsResult->getErrors());
2299 unset($actionsResult);
2300 unset($currentUseMode);
2304 Discount\Actions::clearAction();
2320 ||
$useMode == self::USE_MODE_MIXED
2324 if (!empty($basketCodeList))
2327 foreach ($basketCodeList as $code)
2329 $basketItem =
$basket->getItemByBasketCode($code);
2332 if (!isset($this->basketDiscountList[$code]))
2334 $this->basketDiscountList[$code] = $basketItem->getField(
'DISCOUNT_LIST');
2335 if ($this->basketDiscountList[$code] ===
null)
2336 unset($this->basketDiscountList[$code]);
2340 unset($basketItem, $code,
$basket);
2342 unset($basketCodeList);
2352 protected function calculateFullBasketDiscount()
2356 if ((
string)Main\
Config\Option::get(
'sale',
'use_sale_discount_only') ==
'Y')
2358 if (empty($this->basketDiscountList))
2370 if ($this->
isOrderNew() && array_key_exists($basketCode, $applyBlock))
2371 unset($applyBlock[$basketCode]);
2372 if (empty($this->basketDiscountList[$basketCode]))
2376 'MODULE_ID' => $this->orderData[
'BASKET_ITEMS'][$basketCode][
'MODULE'],
2377 'PRODUCT_ID' => $this->orderData[
'BASKET_ITEMS'][$basketCode][
'PRODUCT_ID'],
2378 'BASKET_ID' => $basketCode
2380 foreach ($this->basketDiscountList[$basketCode] as $index => $discount)
2391 $orderCouponId =
'';
2392 $this->basketDiscountList[$basketCode][$index][
'ORDER_DISCOUNT_ID'] = $orderDiscountId;
2393 if ($discountData[
'USE_COUPONS'] ==
'Y')
2395 if (empty($discount[
'COUPON']))
2397 $result->addError(
new Main\Entity\EntityError(
2403 $couponResult = $this->convertCoupon($discount[
'COUPON'], $orderDiscountId);
2404 if (!$couponResult->isSuccess())
2406 $result->addErrors($couponResult->getErrors());
2407 unset($couponResult);
2410 $orderCouponId = $couponResult->getId();
2412 $couponClassName::setApplyByProduct($itemData, array($orderCouponId));
2413 unset($couponResult);
2416 if (!isset($applyBlock[$basketCode]))
2417 $applyBlock[$basketCode] = array();
2418 $applyBlock[$basketCode][$index] = array(
2419 'DISCOUNT_ID' => $orderDiscountId,
2420 'COUPON_ID' => $orderCouponId,
2424 'DESCR_DATA' =>
false
2428 $currentProduct = $this->orderData[
'BASKET_ITEMS'][$basketCode];
2429 $orderApplication = (
2430 !empty($this->discountsCache[$orderDiscountId][
'APPLICATION'])
2431 ? $this->discountsCache[$orderDiscountId][
'APPLICATION']
2434 if (!empty($orderApplication))
2436 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT'] = (
2437 !empty($this->discountsCache[$orderDiscountId][
'ACTIONS_DESCR_DATA'])
2438 ? $this->discountsCache[$orderDiscountId][
'ACTIONS_DESCR_DATA']
2442 $applyProduct =
null;
2443 eval(
'$applyProduct='.$orderApplication.
';');
2444 if (is_callable($applyProduct))
2445 $applyProduct($this->orderData[
'BASKET_ITEMS'][$basketCode]);
2446 unset($applyProduct);
2448 if (!empty($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']))
2450 $applyBlock[$basketCode][$index][
'RESULT'][
'DESCR_DATA'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT'][
'BASKET'];
2451 $applyBlock[$basketCode][$index][
'RESULT'][
'DESCR'] = $this->
formatDescription($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']);
2453 unset($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']);
2455 unset($orderApplication);
2459 $this->orderData[
'BASKET_ITEMS'][$basketCode] = $currentProduct;
2460 $applyBlock[$basketCode][$index][
'RESULT'][
'APPLY'] =
'N';
2462 unset($disable, $currentProduct);
2463 if ($applyBlock[$basketCode][$index][
'RESULT'][
'APPLY'] ==
'Y')
2464 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'ACTION_APPLIED'] =
'Y';
2466 unset($discount, $index);
2486 if (empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'BASKET']))
2497 if (isset($applyBlock[$basketCode]))
2498 unset($applyBlock[$basketCode]);
2501 if (empty($applyBlock[$basketCode]))
2504 foreach ($applyBlock[$basketCode] as $index => $discount)
2506 $currentProduct = $this->orderData[
'BASKET_ITEMS'][$basketCode];
2507 $orderDiscountId = $discount[
'DISCOUNT_ID'];
2508 $orderCouponId = $discount[
'COUPON_ID'];
2510 if (!isset($this->discountsCache[$orderDiscountId]))
2519 $orderApplication = (
2520 !empty($this->discountsCache[$orderDiscountId][
'APPLICATION'])
2521 ? $this->discountsCache[$orderDiscountId][
'APPLICATION']
2524 if (!empty($orderApplication) && !$this->
loadDiscountModules($this->discountsCache[$orderDiscountId][
'MODULES']))
2525 $orderApplication =
null;
2527 if (!empty($orderApplication))
2529 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT'] = (
2530 !empty($this->discountsCache[$orderDiscountId][
'ACTIONS_DESCR_DATA'])
2531 ? $this->discountsCache[$orderDiscountId][
'ACTIONS_DESCR_DATA']
2535 $applyProduct =
null;
2536 eval(
'$applyProduct='.$orderApplication.
';');
2537 if (is_callable($applyProduct))
2538 $applyProduct($this->orderData[
'BASKET_ITEMS'][$basketCode]);
2539 unset($applyProduct);
2541 if (!empty($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']))
2543 $applyBlock[$basketCode][$index][
'RESULT'][
'DESCR_DATA'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT'];
2544 $applyBlock[$basketCode][$index][
'RESULT'][
'DESCR'] = $this->
formatDescription($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']);
2546 unset($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']);
2548 unset($orderApplication);
2550 $disable = ($applyBlock[$basketCode][$index][
'RESULT'][
'APPLY'] ==
'N');
2554 if ($applyDisable != $disable)
2555 $disable = $applyDisable;
2556 unset($applyDisable);
2560 $this->orderData[
'BASKET_ITEMS'][$basketCode] = $currentProduct;
2561 $applyBlock[$basketCode][$index][
'RESULT'][
'APPLY'] =
'N';
2565 $applyBlock[$basketCode][$index][
'RESULT'][
'APPLY'] =
'Y';
2566 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'ACTION_APPLIED'] =
'Y';
2568 unset($disable, $currentProduct);
2571 unset($index, $discount);
2590 if (!$basketDiscountResult->isSuccess())
2592 $result->addErrors($basketDiscountResult->getErrors());
2593 unset($basketDiscountResult);
2597 unset($basketDiscountResult);
2599 $roundApply =
false;
2600 if ($this->
isRoundMode(self::ROUND_MODE_BASKET_DISCOUNT))
2603 $this->roundApplyBasketPrices();
2606 if ($this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT) && !$roundApply)
2609 'DISCOUNT_INDEX' => -1,
2613 if (!empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER']))
2616 foreach ($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'] as $indexDiscount => $discount)
2619 $orderDiscountId = $discount[
'DISCOUNT_ID'];
2620 if (!isset($this->discountsCache[$orderDiscountId]))
2628 Discount\Actions::clearAction();
2629 if (!empty($discount[
'RESULT'][
'BASKET']))
2631 if ($discount[
'ACTION_BLOCK_LIST'])
2633 $applyResultMode = Discount\Actions::APPLY_RESULT_MODE_COUNTER;
2634 $blockList = array();
2635 foreach ($discount[
'RESULT'][
'BASKET'] as $basketCode => $basketItem)
2636 $blockList[$basketCode] = $basketItem[
'ACTION_BLOCK_LIST'];
2637 unset($basketCode, $basketItem);
2641 if ($this->discountsCache[$orderDiscountId][
'SIMPLE_ACTION'])
2643 $applyResultMode = Discount\Actions::APPLY_RESULT_MODE_SIMPLE;
2644 $blockList = array_fill_keys(array_keys($discount[
'RESULT'][
'BASKET']),
true);
2648 $applyResultMode = Discount\Actions::APPLY_RESULT_MODE_DESCR;
2649 $blockList = array();
2650 foreach ($discount[
'RESULT'][
'BASKET'] as $basketCode => $basketItem)
2651 $blockList[$basketCode] = $basketItem[
'DESCR_DATA'];
2652 unset($basketCode, $basketItem);
2655 Discount\Actions::setApplyResultMode($applyResultMode);
2656 Discount\Actions::setApplyResult(array(
'BASKET' => $blockList));
2657 unset($blockList, $applyResultMode);
2659 if ($this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT) && !$roundApply)
2662 'DISCOUNT_INDEX' => $index,
2663 'DISCOUNT_ID' => $orderDiscountId
2667 'discountIndex' => $indexDiscount,
2668 'discountId' => $orderDiscountId,
2671 if (!$actionsResult->isSuccess())
2673 $result->addErrors($actionsResult->getErrors());
2674 unset($actionsResult);
2677 unset($orderDiscountId);
2679 if ($this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT) && !$roundApply)
2683 'DISCOUNT_INDEX' => $index,
2687 if (is_array($roundConfig))
2689 if ($roundConfig[
'DISCOUNT_INDEX'] > $index && $roundConfig[
'DISCOUNT_ID'] == 0)
2692 'DISCOUNT_INDEX' => $roundConfig[
'DISCOUNT_INDEX'],
2697 unset($roundConfig);
2699 unset($discount, $indexDiscount, $currentList);
2702 if ($this->
isRoundMode(self::ROUND_MODE_FINAL_PRICE))
2703 $this->roundApplyBasketPrices();
2715 protected function calculateApplyAdditionalCoupons()
2725 $couponList = $this->getAdditionalCoupons(array(
'!MODULE_ID' =>
'sale'));
2726 if (!empty($couponList))
2729 'USE_BASE_PRICE' => $this->saleOptions[
'USE_BASE_PRICE'],
2730 'USER_ID' => $this->orderData[
'USER_ID'],
2731 'SITE_ID' => $this->orderData[
'SITE_ID']
2733 $couponsByModule = array();
2734 foreach ($couponList as &$coupon)
2736 if (!isset($couponsByModule[$coupon[
'MODULE_ID']]))
2737 $couponsByModule[$coupon[
'MODULE_ID']] = array();
2738 $couponsByModule[$coupon[
'MODULE_ID']][] = array(
2739 'DISCOUNT_ID' => $coupon[
'DISCOUNT_ID'],
2740 'COUPON' => $coupon[
'COUPON']
2744 if (!empty($couponsByModule))
2748 foreach ($couponsByModule as $moduleId => $moduleCoupons)
2750 if (
$useMode == self::USE_MODE_APPLY)
2752 $currentBasket = $this->orderData[
'BASKET_ITEMS'];
2756 $currentBasket = array();
2758 foreach ($basketCodeList as $basketCode)
2759 $currentBasket[$basketCode] = $this->orderData[
'BASKET_ITEMS'][$basketCode];
2760 unset($basketCode, $basketCodeList);
2762 if (empty($currentBasket))
2764 $couponsApply = $storageClassName::calculateApplyCoupons(
2770 unset($currentBasket);
2771 if (!empty($couponsApply))
2773 $couponsApplyResult = $this->calculateApplyBasketAdditionalCoupons($couponsApply);
2774 if (!$couponsApplyResult->isSuccess())
2775 $result->addErrors($couponsApplyResult->getErrors());
2776 unset($couponsApplyResult);
2778 unset($couponsApply);
2780 unset($moduleId, $moduleCoupons);
2782 unset($couponsByModule, $params);
2787 $couponList = $this->getAdditionalCoupons(array(
'MODULE_ID' =>
'sale'));
2788 if (!empty($couponList))
2791 if (!$couponsApplyResult->isSuccess())
2792 $result->addErrors($couponsApplyResult->getErrors());
2793 unset($couponsApplyResult);
2805 protected function calculateFullSaleDiscountResult()
2807 $result =
new Result;
2812 $this->orderData[
'DISCOUNT_RESULT'] = Discount\Actions::getActionResult();
2813 $this->orderData[
'DISCOUNT_DESCR'] = Discount\Actions::getActionDescription();
2814 if (!empty($this->orderData[
'DISCOUNT_RESULT']) && is_array($this->orderData[
'DISCOUNT_RESULT']))
2820 $stepResult = Discount\Result\CompatibleFormat::getStepResult(
2822 $this->currentStep[
'oldData']
2824 if (!empty($stepResult))
2826 if (empty($this->orderData[
'DISCOUNT_DESCR']) || !is_array($this->orderData[
'DISCOUNT_DESCR']))
2827 $this->orderData[
'DISCOUNT_DESCR'] = Discount\Result\CompatibleFormat::getDiscountDescription($stepResult);
2831 Discount\Actions::fillCompatibleFields($this->orderData);
2832 $applied = !empty($stepResult);
2834 $orderDiscountId = 0;
2835 $orderCouponId =
'';
2841 $this->currentStep[
'discount'][
'ACTIONS_DESCR'] = $this->orderData[
'DISCOUNT_DESCR'];
2842 $discountResult = $this->convertDiscount($this->currentStep[
'discount']);
2851 $this->currentStep[
'discount'][
'ORDER_DISCOUNT_ID'] = $orderDiscountId;
2853 if ($discountData[
'USE_COUPONS'] ==
'Y')
2855 if (empty($this->currentStep[
'discount'][
'COUPON']))
2857 $result->addError(
new Main\Entity\EntityError(
2864 $couponResult = $this->convertCoupon($this->currentStep[
'discount'][
'COUPON'][
'COUPON'], $orderDiscountId);
2865 if (!$couponResult->isSuccess())
2867 $result->addErrors($couponResult->getErrors());
2868 unset($couponResult);
2872 $orderCouponId = $couponResult->getId();
2873 $couponClassName::setApply($orderCouponId, $stepResult);
2874 unset($couponResult);
2878 unset($this->orderData[
'DISCOUNT_DESCR'], $this->orderData[
'DISCOUNT_RESULT']);
2884 !empty($this->applyResult[
'DISCOUNT_LIST'][$orderDiscountId])
2885 && $this->applyResult[
'DISCOUNT_LIST'][$orderDiscountId] ==
'N'
2889 $orderCouponId !=
''
2890 && !empty($this->applyResult[
'COUPON_LIST'][$orderCouponId])
2891 && $this->applyResult[
'COUPON_LIST'][$orderCouponId] ==
'N'
2895 $this->orderData = $this->currentStep[
'oldData'];
2896 if (!empty($stepResult[
'BASKET']))
2898 foreach ($stepResult[
'BASKET'] as &$basketItem)
2899 $basketItem[
'APPLY'] =
'N';
2902 if (!empty($stepResult[
'DELIVERY']))
2903 $stepResult[
'DELIVERY'][
'APPLY'] =
'N';
2907 if (!empty($this->applyResult[
'BASKET']) && is_array($this->applyResult[
'BASKET']))
2909 foreach ($this->applyResult[
'BASKET'] as $basketCode => $discountList)
2912 is_array($discountList) && !empty($discountList[$orderDiscountId]) && $discountList[$orderDiscountId] ==
'N'
2915 if (empty($stepResult[
'BASKET'][$basketCode]))
2917 $stepResult[
'BASKET'][$basketCode][
'APPLY'] =
'N';
2918 $this->orderData[
'BASKET_ITEMS'][$basketCode] = $this->currentStep[
'oldData'][
'BASKET_ITEMS'][$basketCode];
2921 unset($basketCode, $discountList);
2923 if (!empty($this->applyResult[
'DELIVERY']))
2926 is_array($this->applyResult[
'DELIVERY']) && !empty($this->applyResult[
'DELIVERY'][$orderDiscountId]) && $this->applyResult[
'DELIVERY'][$orderDiscountId] ==
'N'
2929 $this->orderData[
'PRICE_DELIVERY'] = $this->currentStep[
'oldData'][
'PRICE_DELIVERY'];
2930 $this->orderData[
'PRICE_DELIVERY_DIFF'] = $this->currentStep[
'oldData'][
'PRICE_DELIVERY_DIFF'];
2931 $stepResult[
'DELIVERY'][
'APPLY'] =
'N';
2937 if ($applied && $orderCouponId !=
'')
2939 $couponApply = $couponClassName::setApply($this->couponsCache[$orderCouponId][
'COUPON'], $stepResult);
2940 unset($couponApply);
2947 if (!empty($stepResult[
'BASKET']))
2949 foreach ($stepResult[
'BASKET'] as $basketCode => $itemResult)
2951 if ($itemResult[
'APPLY'] ==
'Y')
2952 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'ACTION_APPLIED'] =
'Y';
2954 unset($basketCode, $itemResult);
2958 'DISCOUNT_ID' => $orderDiscountId,
2959 'COUPON_ID' => $orderCouponId,
2960 'RESULT' => $stepResult
2962 if ($this->currentStep[
'discount'][
'LAST_DISCOUNT'] ==
'Y')
2963 $this->currentStep[
'stop'] =
true;
2965 if ($this->currentStep[
'discount'][
'LAST_LEVEL_DISCOUNT'] ==
'Y')
2966 $this->currentStep[
'stopLevel'] =
true;
2981 if (empty($stepResult[
'BASKET']))
2986 foreach ($stepResult[
'BASKET'] as $basketItemId => $item)
2988 if ($item[
'APPLY'] !==
'Y')
2993 if (empty($item[
'DESCR_DATA']))
2998 foreach ($item[
'DESCR_DATA'] as $rowDescription)
3002 !empty($rowDescription[
'REVERT_APPLY']) &&
3020 if (empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter]))
3026 foreach ($applyBlock[
'ORDER'] as &$orderBlock)
3028 foreach ($orderBlock[
'RESULT'][
'BASKET'] as $bid => &$basketItem)
3030 if ($bid != $basketItemId)
3035 $basketItem[
'APPLY'] =
'N';
3045 protected function calculateApplySaleDiscountResult()
3052 $this->orderData[
'DISCOUNT_RESULT'] = Discount\Actions::getActionResult();
3053 if (!empty($this->orderData[
'DISCOUNT_RESULT']) && is_array($this->orderData[
'DISCOUNT_RESULT']))
3056 $stepResult = Discount\Result\CompatibleFormat::getStepResult(
3057 $this->orderData, $this->currentStep[
'oldData']
3059 $applied = !empty($stepResult);
3061 $orderDiscountId = 0;
3062 $orderCouponId =
'';
3066 $this->
correctStepResult($stepResult, $this->discountsCache[$this->currentStep[
'discountId']]);
3068 $orderDiscountId = $this->discountResult[
'APPLY_BLOCKS'][
$this->discountResultCounter][
'ORDER'][$this->currentStep[
'discountIndex']][
'DISCOUNT_ID'];
3069 $orderCouponId = $this->discountResult[
'APPLY_BLOCKS'][
$this->discountResultCounter][
'ORDER'][$this->currentStep[
'discountIndex']][
'COUPON_ID'];
3072 unset($this->orderData[
'DISCOUNT_RESULT']);
3078 !empty($this->applyResult[
'DISCOUNT_LIST'][$orderDiscountId])
3079 && $this->applyResult[
'DISCOUNT_LIST'][$orderDiscountId] ==
'N'
3083 $orderCouponId !=
''
3084 && !empty($this->applyResult[
'COUPON_LIST'][$orderCouponId])
3085 && $this->applyResult[
'COUPON_LIST'][$orderCouponId] ==
'N'
3089 $this->orderData = $this->currentStep[
'oldData'];
3090 if (!empty($stepResult[
'BASKET']))
3092 foreach ($stepResult[
'BASKET'] as &$basketItem)
3093 $basketItem[
'APPLY'] =
'N';
3096 if (!empty($stepResult[
'DELIVERY']))
3097 $stepResult[
'DELIVERY'][
'APPLY'] =
'N';
3101 if (!empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$this->currentStep[
'discountIndex']][
'RESULT']))
3103 $existDiscountResult = $this->discountResult[
'APPLY_BLOCKS'][
$this->discountResultCounter][
'ORDER'][$this->currentStep[
'discountIndex']][
'RESULT'];
3104 if (!empty($existDiscountResult[
'BASKET']))
3107 if (!empty($basketCodeList))
3109 foreach ($basketCodeList as &$basketCode)
3113 if (isset($existDiscountResult[
'BASKET'][$basketCode]))
3115 $disable = ($existDiscountResult[
'BASKET'][$basketCode][
'APPLY'] ==
'N');
3116 if (isset($this->applyResult[
'BASKET'][$basketCode][$orderDiscountId]))
3118 $applyDisable = ($this->applyResult[
'BASKET'][$basketCode][$orderDiscountId] ==
'N');
3119 if ($disable != $applyDisable)
3120 $disable = $applyDisable;
3121 unset($applyDisable);
3125 $stepResult[
'BASKET'][$basketCode][
'APPLY'] =
'N';
3126 $this->orderData[
'BASKET_ITEMS'][$basketCode] = $this->currentStep[
'oldData'][
'BASKET_ITEMS'][$basketCode];
3130 $stepResult[
'BASKET'][$basketCode][
'APPLY'] =
'Y';
3131 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'ACTION_APPLIED'] =
'Y';
3135 unset($disable, $basketCode);
3138 if (!empty($existDiscountResult[
'DELIVERY']))
3140 $disable = ($existDiscountResult[
'DELIVERY'][
'APPLY'] ==
'N');
3141 if (!empty($this->applyResult[
'DELIVERY'][$orderDiscountId]))
3143 $applyDisable = ($this->applyResult[
'DELIVERY'][$orderDiscountId] ==
'N');
3144 if ($disable != $applyDisable)
3145 $disable = $applyDisable;
3146 unset($applyDisable);
3150 $this->orderData[
'PRICE_DELIVERY'] = $this->currentStep[
'oldData'][
'PRICE_DELIVERY'];
3151 $this->orderData[
'PRICE_DELIVERY_DIFF'] = $this->currentStep[
'oldData'][
'PRICE_DELIVERY_DIFF'];
3152 $stepResult[
'DELIVERY'][
'APPLY'] =
'N';
3156 $stepResult[
'DELIVERY'][
'APPLY'] =
'Y';
3164 if ($applied && $orderCouponId !=
'')
3166 $couponApply = $couponClassName::setApply($this->couponsCache[$orderCouponId][
'COUPON'], $stepResult);
3167 unset($couponApply);
3176 if (!empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$this->currentStep[
'discountIndex']]))
3205 return $this->roundApplyMode == $mode;
3214 protected function loadRoundConfig()
3217 $this->roundApplyMode = $defaultApplyMode;
3218 $this->roundApplyConfig = array();
3222 $orderId = $this->
getOrder()->getId();
3225 $entityData = $storageClassName::loadOrderStoredDataFromDb(
3227 $storageClassName::STORAGE_TYPE_ROUND_CONFIG
3232 is_array($entityData)
3233 && isset($entityData[
'MODE'])
3236 $this->roundApplyMode = (int)$entityData[
'MODE'];
3237 if ($this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT))
3238 $this->roundApplyConfig = (isset($entityData[
'CONFIG']) ? $entityData[
'CONFIG'] : array());
3243 $this->roundApplyMode != self::ROUND_MODE_BASKET_DISCOUNT
3244 && $this->roundApplyMode != self::ROUND_MODE_SALE_DISCOUNT
3245 && $this->roundApplyMode != self::ROUND_MODE_FINAL_PRICE
3247 $this->roundApplyMode =
null;
3248 if (!is_array($this->roundApplyConfig))
3249 $this->roundApplyConfig = array();
3250 unset($defaultApplyMode);
3263 if (!$this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT))
3265 if (!isset($index[
'DISCOUNT_INDEX']) || !isset($index[
'DISCOUNT_ID']))
3267 if (!isset($this->roundApplyConfig[$this->discountResultCounter]))
3282 if (!$this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT))
3284 if ($applyCounter ===
null)
3286 return (isset($this->roundApplyConfig[$applyCounter][$entity]) ? $this->roundApplyConfig[$applyCounter][$entity] :
null);
3294 protected function roundFullBasketPrices()
3297 if (!empty($basketCodeList))
3302 $basket = array_intersect_key(
3303 $this->orderData[
'BASKET_ITEMS'],
3304 array_fill_keys($basketCodeList,
true)
3310 $result = $storageClassName::roundBasket(
3315 foreach ($result as $basketCode => $roundResult)
3317 if (empty($roundResult) || !is_array($roundResult))
3321 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'PRICE'] = $roundResult[
'PRICE'];
3322 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_PRICE'] = $roundResult[
'DISCOUNT_PRICE'];
3324 $roundBlock[$basketCode] = array(
3326 'ROUND_RULE' => $roundResult[
'ROUND_RULE']
3329 unset($basketCode, $roundResult, $result);
3330 unset($storageClassName);
3334 unset($basketCodeList);
3342 protected function roundApplyBasketPrices()
3344 if (empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'BASKET_ROUND']))
3348 if (!empty($basketCodeList))
3352 $roundData = array();
3353 foreach ($basketCodeList as $basketCode)
3355 if (empty($roundBlock[$basketCode]))
3357 if ($roundBlock[$basketCode][
'APPLY'] !=
'Y')
3359 $basket[$basketCode] = $this->orderData[
'BASKET_ITEMS'][$basketCode];
3360 $roundData[$basketCode] = $roundBlock[$basketCode][
'ROUND_RULE'];
3372 $result = $storageClassName::roundBasket(
3377 foreach ($result as $basketCode => $roundResult)
3379 if (empty($roundResult) || !is_array($roundResult))
3383 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'PRICE'] = $roundResult[
'PRICE'];
3384 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_PRICE'] = $roundResult[
'DISCOUNT_PRICE'];
3386 unset($basketCode, $roundResult, $result);
3393 unset($basketCodeList);
3401 protected function roundChangedBasketPrices()
3403 $basketCodeList = array();
3408 if (!empty($applyBlock[
'BASKET']))
3410 foreach (array_keys($applyBlock[
'BASKET']) as $basketCode)
3412 $basketCodeList[$basketCode] = $basketCode;
3416 if (!empty($applyBlock[
'ORDER']))
3418 foreach ($applyBlock[
'ORDER'] as $discount)
3420 if (empty($discount[
'RESULT'][
'BASKET']))
3422 foreach (array_keys($discount[
'RESULT'][
'BASKET']) as $basketCode)
3424 $basketCodeList[$basketCode] = $basketCode;
3427 unset($basketCode, $discount);
3431 if (!empty($applyBlock[
'BASKET']))
3433 foreach (array_keys($applyBlock[
'BASKET']) as $basketCode)
3435 $basketCodeList[$basketCode] = $basketCode;
3439 if (!empty($applyBlock[
'ORDER']))
3441 foreach ($applyBlock[
'ORDER'] as $discount)
3443 if (empty($discount[
'RESULT'][
'BASKET']))
3445 foreach (array_keys($discount[
'RESULT'][
'BASKET']) as $basketCode)
3447 $basketCodeList[$basketCode] = $basketCode;
3450 unset($basketCode, $discount);
3453 $basketCodeList[$basketCode] = $basketCode;
3457 if (!empty($basketCodeList))
3462 $basket = array_intersect_key(
3463 $this->orderData[
'BASKET_ITEMS'],
3464 array_fill_keys($basketCodeList,
true)
3470 $result = $storageClassName::roundBasket(
3476 foreach ($result as $basketCode => $roundResult)
3478 if (empty($roundResult) || !is_array($roundResult))
3482 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'PRICE'] = $roundResult[
'PRICE'];
3483 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_PRICE'] = $roundResult[
'DISCOUNT_PRICE'];
3485 $roundBlock[$basketCode] = array(
3487 'ROUND_RULE' => $roundResult[
'ROUND_RULE']
3490 unset($basketCode, $roundResult, $result);
3491 unset($storageClassName);
3495 unset($basketCodeList);
3507 if (!$this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT))
3509 if ($this->
getUseMode() != self::USE_MODE_FULL)
3512 $this->roundFullBasketPrices();
3513 if (!empty($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'BASKET_ROUND']))
3526 if (!isset($index[
'DISCOUNT_INDEX']))
3528 if (!$this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT))
3530 if ($this->
getUseMode() != self::USE_MODE_APPLY && $this->
getUseMode() != self::USE_MODE_MIXED)
3534 if ($roundConfig ===
null)
3536 if ($roundConfig[
'DISCOUNT_INDEX'] != $index[
'DISCOUNT_INDEX'])
3538 $this->roundApplyBasketPrices();
3549 protected function convertDiscount($discount)
3565 $resultData = array(
3566 'ORDER_DISCOUNT_ID' => $orderDiscountId,
3567 'USE_COUPONS' => $discountData[
'USE_COUPONS'],
3568 'MODULE_ID' => $discountData[
'MODULE_ID'],
3569 'DISCOUNT_ID' => $discountData[
'DISCOUNT_ID']
3571 if (!isset($this->discountsCache[$orderDiscountId]))
3573 $discountData[
'ACTIONS_DESCR_DATA'] =
false;
3574 if (!empty($discountData[
'ACTIONS_DESCR']) && is_array($discountData[
'ACTIONS_DESCR']))
3576 $discountData[
'ACTIONS_DESCR_DATA'] = $discountData[
'ACTIONS_DESCR'];
3577 $discountData[
'ACTIONS_DESCR'] = $this->
formatDescription($discountData[
'ACTIONS_DESCR']);
3581 $discountData[
'ACTIONS_DESCR'] =
false;
3583 if (empty($discountData[
'ACTIONS_DESCR']))
3585 $discountData[
'ACTIONS_DESCR'] =
false;
3586 $discountData[
'ACTIONS_DESCR_DATA'] =
false;
3588 $this->discountsCache[$orderDiscountId] = $discountData;
3591 $result->setId($orderDiscountId);
3592 $result->setData($resultData);
3593 unset($discountData, $resultData, $orderDiscountId);
3605 protected function convertCoupon($coupon, $discount)
3607 $result =
new Result;
3612 if (!is_array($coupon))
3614 $couponData = $couponClassName::getEnteredCoupon($coupon,
true);
3615 if (empty($couponData))
3617 $result->addError(
new Main\Entity\EntityError(
3624 'COUPON' => $couponData[
'COUPON'],
3625 'TYPE' => $couponData[
'TYPE'],
3626 'COUPON_ID' => $couponData[
'ID'],
3627 'DATA' => $couponData
3631 $coupon[
'ORDER_DISCOUNT_ID'] = $discount;
3634 $orderCouponId = $coupon[
'COUPON'];
3635 if (!isset($this->couponsCache[$orderCouponId]))
3636 $this->couponsCache[$orderCouponId] = $coupon;
3637 $result->setId($orderCouponId);
3638 $result->setData($coupon);
3639 unset($coupon, $orderCouponId);
3652 $stepResult = &
$order[
'DISCOUNT_RESULT'];
3653 if (!empty($stepResult[
'BASKET']) && is_array($stepResult[
'BASKET']))
3655 if (!isset($result[
'BASKET']))
3656 $result[
'BASKET'] = array();
3657 foreach ($stepResult[
'BASKET'] as $basketCode => $basketResult)
3659 $result[
'BASKET'][$basketCode] = array(
3662 'DESCR_DATA' => $basketResult,
3663 'MODULE' =>
$order[
'BASKET_ITEMS'][$basketCode][
'MODULE'],
3664 'PRODUCT_ID' =>
$order[
'BASKET_ITEMS'][$basketCode][
'PRODUCT_ID'],
3665 'BASKET_ID' => (isset(
$order[
'BASKET_ITEMS'][$basketCode][
'ID']) ?
$order[
'BASKET_ITEMS'][$basketCode][
'ID'] : $basketCode),
3666 'ACTION_BLOCK_LIST' => array_keys($basketResult)
3668 if (is_array($result[
'BASKET'][$basketCode][
'DESCR']))
3669 $result[
'BASKET'][$basketCode][
'DESCR'] = implode(
', ', $result[
'BASKET'][$basketCode][
'DESCR']);
3671 unset($basketCode, $basketResult);
3687 if ($discount[
'USE_COUPONS'] ==
'Y' && !empty($discount[
'COUPON']))
3691 (!empty($stepResult[
'BASKET']) && count($stepResult[
'BASKET']) > 1)
3696 $basketKeys = array();
3697 foreach ($stepResult[
'BASKET'] as $key => $row)
3699 $basketKeys[$key] = $key;
3700 if ($maxPrice < $this->currentStep[
'oldData'][
'BASKET_ITEMS'][$key][
'PRICE'])
3702 $maxPrice = $this->currentStep[
'oldData'][
'BASKET_ITEMS'][$key][
'PRICE'];
3706 unset($basketKeys[$maxKey]);
3707 foreach ($basketKeys as $key => $row)
3709 unset($stepResult[
'BASKET'][$key]);
3710 $this->orderData[
'BASKET_ITEMS'][$row] = $this->currentStep[
'oldData'][
'BASKET_ITEMS'][$row];
3729 $orderDiscountId = (int)$orderDiscountId;
3730 if (!isset($this->discountsCache[$orderDiscountId]))
3734 if (!isset($this->discountStoredActionData[$this->discountResultCounter]))
3735 $this->discountStoredActionData[$this->discountResultCounter] = array();
3747 $orderDiscountId = (int)$orderDiscountId;
3748 if (isset($this->discountStoredActionData[$this->discountResultCounter][$orderDiscountId]))
3749 return $this->discountStoredActionData[$this->discountResultCounter][$orderDiscountId];
3763 !empty($this->applyResult[
'DISCOUNT_LIST'])
3764 || !empty($this->applyResult[
'COUPON_LIST'])
3765 || !empty($this->applyResult[
'BASKET'])
3776 $discountApply = array();
3777 $couponApply = array();
3779 if (!empty($this->discountsCache))
3781 foreach ($this->discountsCache as $id => $discount)
3783 $this->discountResult[
'DISCOUNT_LIST'][$id] = array(
3785 'NAME' => $discount[
'NAME'],
3786 'MODULE_ID' => $discount[
'MODULE_ID'],
3787 'DISCOUNT_ID' => $discount[
'ID'],
3788 'REAL_DISCOUNT_ID' => $discount[
'DISCOUNT_ID'],
3789 'USE_COUPONS' => $discount[
'USE_COUPONS'],
3790 'ACTIONS_DESCR' => $discount[
'ACTIONS_DESCR'],
3791 'ACTIONS_DESCR_DATA' => $discount[
'ACTIONS_DESCR_DATA'],
3793 'EDIT_PAGE_URL' => $discount[
'EDIT_PAGE_URL']
3795 $discountApply[$id] = &$this->discountResult[
'DISCOUNT_LIST'][$id];
3797 unset($id, $discount);
3800 if (!empty($this->couponsCache))
3802 foreach ($this->couponsCache as $id => $coupon)
3804 $this->discountResult[
'COUPON_LIST'][$id] = $coupon;
3805 $this->discountResult[
'COUPON_LIST'][$id][
'APPLY'] =
'N';
3806 $couponApply[$id] = &$this->discountResult[
'COUPON_LIST'][$id];
3808 unset($id, $coupon);
3811 if (empty($this->discountResult[
'APPLY_BLOCKS']))
3813 unset($discountApply, $couponApply);
3817 foreach ($this->discountResult[
'APPLY_BLOCKS'] as $counter => $applyBlock)
3819 if (!empty($applyBlock[
'BASKET']))
3821 foreach ($applyBlock[
'BASKET'] as $basketCode => $discountList)
3823 foreach ($discountList as $discount)
3825 if ($discount[
'RESULT'][
'APPLY'] ==
'Y')
3827 if (isset($discountApply[$discount[
'DISCOUNT_ID']]))
3828 $discountApply[$discount[
'DISCOUNT_ID']][
'APPLY'] =
'Y';
3829 if (isset($couponApply[$discount[
'COUPON_ID']]))
3830 $couponApply[$discount[
'COUPON_ID']][
'APPLY'] =
'Y';
3835 unset($basketCode, $discountList);
3838 if (!empty($applyBlock[
'ORDER']))
3840 foreach ($applyBlock[
'ORDER'] as $discount)
3842 if (!empty($discount[
'RESULT'][
'BASKET']))
3844 foreach ($discount[
'RESULT'][
'BASKET'] as $basketCode => $applyList)
3846 if ($applyList[
'APPLY'] ==
'Y')
3848 if (isset($discountApply[$discount[
'DISCOUNT_ID']]))
3849 $discountApply[$discount[
'DISCOUNT_ID']][
'APPLY'] =
'Y';
3850 if (isset($couponApply[$discount[
'COUPON_ID']]))
3851 $couponApply[$discount[
'COUPON_ID']][
'APPLY'] =
'Y';
3854 unset($basketCode, $applyList);
3856 if (!empty($discount[
'RESULT'][
'DELIVERY']) && $discount[
'RESULT'][
'DELIVERY'][
'APPLY'] ==
'Y')
3858 if (isset($discountApply[$discount[
'DISCOUNT_ID']]))
3859 $discountApply[$discount[
'DISCOUNT_ID']][
'APPLY'] =
'Y';
3860 if (isset($couponApply[$discount[
'COUPON_ID']]))
3861 $couponApply[$discount[
'COUPON_ID']][
'APPLY'] =
'Y';
3867 unset($counter, $applyBlock);
3869 unset($discountApply, $couponApply);
3882 if (!empty($this->orderData[
'BASKET_ITEMS']))
3884 foreach ($this->orderData[
'BASKET_ITEMS'] as $basketCode => $basketItem)
3887 'BASE_PRICE' => $basketItem[
'BASE_PRICE'],
3888 'PRICE' => $basketItem[
'PRICE'],
3889 'DISCOUNT' => $basketItem[
'DISCOUNT_PRICE']
3892 unset($basketCode, $basketItem);
3895 $this->discountResult[
'PRICES'] = [
3909 if (!empty($this->discountResult[
'APPLY_BLOCKS']))
3911 foreach ($this->discountResult[
'APPLY_BLOCKS'] as $counter => $applyBlock)
3913 if (!empty($applyBlock[
'BASKET']))
3915 foreach ($applyBlock[
'BASKET'] as $basketCode => $discountList)
3917 if (!isset(
$basket[$basketCode]))
3919 foreach ($discountList as $discount)
3922 'DISCOUNT_ID' => $discount[
'DISCOUNT_ID'],
3923 'COUPON_ID' => $discount[
'COUPON_ID'],
3924 'APPLY' => $discount[
'RESULT'][
'APPLY'],
3925 'DESCR' => $discount[
'RESULT'][
'DESCR']
3930 unset($basketCode, $discountList);
3933 if (!empty($applyBlock[
'ORDER']))
3935 foreach ($applyBlock[
'ORDER'] as $discount)
3937 if (!empty($discount[
'RESULT'][
'BASKET']))
3939 foreach ($discount[
'RESULT'][
'BASKET'] as $basketCode => $applyList)
3941 if (!isset(
$basket[$basketCode]))
3944 'DISCOUNT_ID' => $discount[
'DISCOUNT_ID'],
3945 'COUPON_ID' => $discount[
'COUPON_ID'],
3946 'APPLY' => $applyList[
'APPLY'],
3947 'DESCR' => $applyList[
'DESCR']
3950 unset($basketCode, $applyList);
3956 unset($counter, $applyBlock);
3959 $this->discountResult[
'RESULT'] = [
3972 protected function getBasketTables()
3976 $this->forwardBasketTable = array();
3977 $this->reverseBasketTable = array();
3984 foreach ($basket as $basketItem)
3986 $code = $basketItem->getBasketCode();
3987 $id = $basketItem->getField(
'ID');
3988 $this->forwardBasketTable[$code] = $id;
3989 $this->reverseBasketTable[$id] = $code;
3992 if ($basketItem->isBundleParent())
3994 $bundle = $basketItem->getBundleCollection();
4004 foreach ($bundle as $bundleItem)
4006 $code = $bundleItem->getBasketCode();
4007 $id = $bundleItem->getField(
'ID');
4008 $this->forwardBasketTable[$code] = $id;
4009 $this->reverseBasketTable[$id] = $code;
4012 unset($bundle, $bundleItem);
4030 switch ($entity[
'ENTITY_TYPE'])
4033 $basketCode = $entity[
'ENTITY_CODE'];
4034 if (isset($this->forwardBasketTable[$basketCode]))
4038 'ENTITY_ID' => (int)$this->forwardBasketTable[$basketCode],
4039 'ENTITY_VALUE' => (
string)$this->forwardBasketTable[$basketCode]
4047 'ENTITY_ID' => (int)$entity[
'ENTITY_CODE'],
4048 'ENTITY_VALUE' => (
string)$entity[
'ENTITY_CODE']
4068 return $this->
isCustomPrice($this->orderData[
'BASKET_ITEMS'][$code]);
4079 if (!empty($item[
'CUSTOM_PRICE']) && $item[
'CUSTOM_PRICE'] ==
'Y')
4094 return $this->
isInSet($this->orderData[
'BASKET_ITEMS'][$code]);
4105 if (!empty($item[
'IN_SET']) && $item[
'IN_SET'] ==
'Y')
4120 || !isset($this->orderData[
'BASKET_ITEMS'][$code][
'ID'])
4121 || $this->orderData[
'BASKET_ITEMS'][$code][
'ID'] <= 0
4160 return (static::isCustomPrice($item) || static::isInSet($item));
4174 $basketItem = $this->
getBasket()->getItemByBasketCode($code);
4178 if (in_array(
'PRODUCT_ID', $basketItem->getFields()->getChangedKeys()))
4195 return isset($this->orderData[
'BASKET_ITEMS'][$code]);
4216 if (empty($this->orderData[
'BASKET_ITEMS']))
4219 foreach ($this->orderData[
'BASKET_ITEMS'] as $basketItem)
4221 if (!isset($basketItem[
'ID']) || (
int)$basketItem[
'ID'] <= 0)
4231 if ($this->isOrderedBasketChanged())
4243 protected function isOrderedBasketChanged()
4250 foreach ($basket as $basketItem)
4252 if (!$basketItem->isChanged())
4255 if (in_array(
'PRODUCT_ID', $basketItem->getFields()->getChangedKeys()))
4275 if (empty($this->orderData[
'BASKET_ITEMS']))
4281 foreach ($this->orderData[
'BASKET_ITEMS'] as $code => $item)
4287 unset($code, $item);
4290 foreach ($this->orderData[
'BASKET_ITEMS'] as $code => $item)
4300 unset($code, $item);
4303 $full = ($full ===
true);
4306 foreach ($this->orderData[
'BASKET_ITEMS'] as $code => $item)
4314 unset($code, $item);
4318 foreach ($this->orderData[
'BASKET_ITEMS'] as $code => $item)
4328 unset($code, $item);
4339 if (empty($this->orderData[
'BASKET_ITEMS']))
4342 foreach ($this->orderData[
'BASKET_ITEMS'] as $code => $item)
4348 unset($code, $item);
4362 if (!isset($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index]))
4364 if (empty($stepResult) || !is_array($stepResult))
4366 $basketKeys = array_keys($this->orderData[
'BASKET_ITEMS']);
4367 foreach ($basketKeys as &$basketCode)
4371 if (isset($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index][
'RESULT'][
'BASKET'][$basketCode]))
4372 unset($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index][
'RESULT'][
'BASKET'][$basketCode]);
4375 if (isset($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index][
'RESULT'][
'DESCR_DATA']))
4376 unset($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index][
'RESULT'][
'DESCR_DATA']);
4377 if (isset($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index][
'RESULT'][
'DESCR']))
4378 unset($this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index][
'RESULT'][
'DESCR']);
4379 self::recursiveMerge($stepResult, $this->discountResult[
'APPLY_BLOCKS'][$this->discountResultCounter][
'ORDER'][$index][
'RESULT']);
4390 $this->discountResultCounter = 0;
4391 $this->discountResult = [
4392 'APPLY_BLOCKS' => [],
4393 'DISCOUNT_LIST' => [],
4397 $this->discountStoredActionData = [];
4398 $this->basketItemsData = [];
4399 $this->entityResultCache = [];
4410 $basketKeys = [
'PRICE',
'DISCOUNT_PRICE',
'VAT_RATE',
'VAT_VALUE',
'CURRENCY'];
4412 'BASKET_ITEMS' => [],
4413 'CURRENCY' => $this->orderData[
'CURRENCY']
4415 foreach ($this->orderData[
'BASKET_ITEMS'] as $index => $basketItem)
4417 $result[
'BASKET_ITEMS'][$index] = [];
4418 foreach ($basketKeys as $key)
4420 if (isset($basketItem[$key]))
4421 $result[
'BASKET_ITEMS'][$index][$key] = $basketItem[$key];
4425 unset($index, $basketItem);
4446 $this->currentStep = array(
4447 'oldData' => array(),
4448 'discount' => array(),
4449 'discountIndex' =>
null,
4451 'result' => array(),
4465 if (!empty($data) && is_array($data))
4467 foreach ($data as $key => $value)
4468 $this->currentStep[$key] = $value;
4469 unset($value, $key);
4478 protected function extendOrderData()
4480 if (empty($this->discountIds))
4483 $entityCacheKey = md5(serialize($this->discountIds));
4484 if (!isset($this->entityResultCache[$entityCacheKey]))
4486 $this->entityResultCache[$entityCacheKey] = array();
4487 $this->entityList = RuntimeCache\DiscountCache::getInstance()->getDiscountEntities($this->discountIds);
4488 if (empty($this->entityList))
4493 self::EVENT_EXTEND_ORDER_DATA,
4495 'ORDER' => $this->orderData,
4496 'ENTITY' => $this->entityList
4500 $this->entityResultCache[$entityCacheKey] = $event->getResults();
4502 $resultList = $this->entityResultCache[$entityCacheKey];
4503 if (empty($resultList) || !is_array($resultList))
4506 foreach ($resultList as &$eventResult)
4508 if ($eventResult->getType() != Main\EventResult::SUCCESS)
4511 $newData = $eventResult->getParameters();
4512 if (empty($newData) || !is_array($newData))
4517 unset($newData, $eventResult, $resultList);
4528 if (!empty($newData) && is_array($newData))
4541 if (empty($descr) || !is_array($descr))
4543 if (isset($descr[
'DELIVERY']))
4545 $result[
'DELIVERY'] = array();
4546 foreach ($descr[
'DELIVERY'] as $index => $value)
4548 if (!is_array($value))
4550 $result[
'DELIVERY'][$index] = Discount\Formatter::formatRow($value);
4551 if ($result[
'DELIVERY'][$index] ===
null)
4552 unset($result[
'DELIVERY'][$index]);
4554 unset($value, $index);
4555 if (!empty($result[
'DELIVERY']))
4556 $result[
'DELIVERY'] = implode(
', ', $result[
'DELIVERY']);
4558 if (isset($descr[
'BASKET']))
4560 $result[
'BASKET'] = array();
4561 foreach ($descr[
'BASKET'] as $index => $value)
4563 if (!is_array($value))
4565 $result[
'BASKET'][$index] = Discount\Formatter::formatRow($value);
4566 if ($result[
'BASKET'][$index] ===
null)
4567 unset($result[
'BASKET'][$index]);
4569 unset($value, $index);
4570 if (!empty($result[
'BASKET']))
4571 $result[
'BASKET'] = implode(
', ', $result[
'BASKET']);
4608 $this->orderData[
'ORDER_PRICE'] =
$order->getBasePrice();
4614 $this->orderData[
'ORDER_PRICE'] =
$basket->getBasePrice();
4626 foreach ($this->orderData[
'BASKET_ITEMS'] as &$basketItem)
4630 $basketItem = self::resetBasketItemPrice($basketItem);
4642 foreach ($this->orderData[
'BASKET_ITEMS'] as &$basketItem)
4646 $basketItem[
'ACTION_APPLIED'] =
'N';
4662 if ($saleDiscountOnly)
4664 if (
$useMode == self::USE_MODE_FULL && $this->
isRoundMode(self::ROUND_MODE_SALE_DISCOUNT))
4665 $roundApply =
false;
4668 $this->discountIds = array();
4669 if (empty($this->saleDiscountCacheKey) || empty($this->saleDiscountCache[$this->saleDiscountCacheKey]))
4674 'DISCOUNT_INDEX' => -1,
4682 $this->discountIds = array_keys($currentList);
4683 $this->extendOrderData();
4685 Discount\Actions::clearAction();
4688 self::getExecuteFieldName(
'UNPACK') =>
true,
4689 self::getExecuteFieldName(
'APPLICATION') =>
true,
4690 self::getExecuteFieldName(
'PREDICTIONS_APP') =>
true
4694 $skipPriorityLevel =
null;
4695 foreach ($currentList as $discountIndex => $discount)
4697 if($skipPriorityLevel == $discount[
'PRIORITY'])
4701 $skipPriorityLevel =
null;
4704 'discount' => $discount,
4705 'cacheIndex' => $discountIndex
4711 if (!$roundApply && $discount[
'EXECUTE_MODULE'] ==
'sale')
4714 'DISCOUNT_INDEX' => $index,
4715 'DISCOUNT_ID' => $discount[
'ID']
4720 if (
$useMode == self::USE_MODE_FULL && !isset($this->fullDiscountList[$discount[
'ID']]))
4721 $this->fullDiscountList[$discount[
'ID']] = array_diff_key($discount, $blackList);
4724 if (!$actionsResult->isSuccess())
4726 $result->addErrors($actionsResult->getErrors());
4727 unset($actionsResult);
4731 if ($this->currentStep[
'stop'])
4734 if (isset($this->currentStep[
'stopLevel']) && $this->currentStep[
'stopLevel'])
4736 $skipPriorityLevel = $discount[
'PRIORITY'];
4739 unset($discount, $currentList);
4746 'DISCOUNT_INDEX' => $index,
4761 if ($this->
getUseMode() != self::USE_MODE_FULL)
4764 if ($applyMode == self::APPLY_MODE_ADD)
4767 $codeList = array_keys($this->orderData[
'BASKET_ITEMS']);
4772 foreach ($codeList as &$code)
4774 if (isset($this->basketDiscountList[$code]) && !empty($this->basketDiscountList[$code]))
4775 $this->orderData[
'BASKET_ITEMS'][$code][
'LAST_DISCOUNT'] =
'Y';
4781 foreach ($codeList as &$code)
4783 if (!isset($this->basketDiscountList[$code]) || empty($this->basketDiscountList[$code]))
4785 $lastDiscount = end($this->basketDiscountList[$code]);
4786 if (!empty($lastDiscount[
'LAST_DISCOUNT']) && $lastDiscount[
'LAST_DISCOUNT'] ==
'Y')
4787 $this->orderData[
'BASKET_ITEMS'][$code][
'LAST_DISCOUNT'] =
'Y';
4792 unset($codeList, $applyMode);
4804 if ($this->
getUseMode() != self::USE_MODE_FULL)
4809 if ($applyMode == self::APPLY_MODE_FULL_LAST || $applyMode == self::APPLY_MODE_FULL_DISABLE)
4811 foreach ($this->orderData[
'BASKET_ITEMS'] as $basketItem)
4813 if (isset($basketItem[
'LAST_DISCOUNT']) && $basketItem[
'LAST_DISCOUNT'] ==
'Y')
4837 if (empty($coupons))
4840 if (empty($this->discountsCache))
4845 foreach ($coupons as $couponCode => $couponData)
4848 foreach ($this->discountsCache as &$discount)
4851 $discount[
'MODULE_ID'] == $couponData[
'MODULE_ID']
4852 && $discount[
'DISCOUNT_ID'] == $couponData[
'DISCOUNT_ID']
4853 && $discount[
'USE_COUPONS'] ==
'N'
4861 if (!$found && !empty($this->couponsCache))
4863 foreach ($this->couponsCache as $existCouponCode => $existCouponData)
4865 $discount = $this->discountsCache[$existCouponData[
'ORDER_DISCOUNT_ID']];
4867 $discount[
'MODULE_ID'] != $couponData[
'MODULE_ID']
4868 || $discount[
'DISCOUNT_ID'] != $couponData[
'DISCOUNT_ID']
4871 if ($couponCode == $existCouponCode)
4889 if ($discount[
'MODULE_ID'] ==
'sale')
4897 unset($existCouponCode, $existCouponData);
4901 $result[$couponCode] = $couponData;
4904 unset($couponCode, $couponData);
4916 protected function getAdditionalCoupons(array $filter = array())
4920 if (isset($filter[
'MODULE_ID']) && $filter[
'MODULE_ID'] !=
'sale')
4922 if (isset($filter[
'!MODULE_ID']) && $filter[
'!MODULE_ID'] ==
'sale')
4924 $filter[
'MODULE_ID'] =
'sale';
4930 $useOrderCoupons = $couponClassName::isUsedOrderCouponsForApply();
4931 $couponClassName::useSavedCouponsForApply(
false);
4932 $coupons = $couponClassName::getForApply($filter, array(),
true);
4933 $couponClassName::useSavedCouponsForApply($useOrderCoupons);
4934 unset($useOrderCoupons);
4936 if (empty($coupons))
4948 protected function calculateApplyBasketAdditionalCoupons(array $applyCoupons)
4950 $result =
new Result;
4954 if (empty($applyCoupons))
4965 foreach ($basketCodeList as &$basketCode)
4967 if (array_key_exists($basketCode, $applyBlock))
4968 unset($applyBlock[$basketCode]);
4969 if (empty($applyCoupons[$basketCode]))
4973 'MODULE_ID' => $this->orderData[
'BASKET_ITEMS'][$basketCode][
'MODULE'],
4974 'PRODUCT_ID' => $this->orderData[
'BASKET_ITEMS'][$basketCode][
'PRODUCT_ID'],
4975 'BASKET_ID' => $basketCode
4977 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE_TMP'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE'];
4978 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'PRICE'];
4979 foreach ($applyCoupons[$basketCode] as $index => $discount)
4990 $applyCoupons[$basketCode][$index][
'ORDER_DISCOUNT_ID'] = $orderDiscountId;
4992 if (empty($discount[
'COUPON']))
4994 $result->addError(
new Main\Entity\EntityError(
5000 $couponResult = $this->convertCoupon($discount[
'COUPON'], $orderDiscountId);
5001 if (!$couponResult->isSuccess())
5003 $result->addErrors($couponResult->getErrors());
5004 unset($couponResult);
5007 $orderCouponId = $couponResult->getId();
5009 $couponClassName::setApplyByProduct($itemData, array($orderCouponId));
5010 unset($couponResult);
5013 if (!isset($applyBlock[$basketCode]))
5014 $applyBlock[$basketCode] = array();
5015 $applyBlock[$basketCode][$index] = array(
5016 'DISCOUNT_ID' => $orderDiscountId,
5017 'COUPON_ID' => $orderCouponId,
5021 'DESCR_DATA' =>
false
5025 $currentProduct = $this->orderData[
'BASKET_ITEMS'][$basketCode];
5026 $orderApplication = (
5027 !empty($this->discountsCache[$orderDiscountId][
'APPLICATION'])
5028 ? $this->discountsCache[$orderDiscountId][
'APPLICATION']
5031 if (!empty($orderApplication))
5033 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT'] = (
5034 !empty($this->discountsCache[$orderDiscountId][
'ACTIONS_DESCR_DATA'])
5035 ? $this->discountsCache[$orderDiscountId][
'ACTIONS_DESCR_DATA']
5039 $applyProduct =
null;
5040 eval(
'$applyProduct='.$orderApplication.
';');
5041 if (is_callable($applyProduct))
5042 $applyProduct($this->orderData[
'BASKET_ITEMS'][$basketCode]);
5043 unset($applyProduct);
5045 if (!empty($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']))
5047 $applyBlock[$basketCode][$index][
'RESULT'][
'DESCR_DATA'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT'][
'BASKET'];
5048 $applyBlock[$basketCode][$index][
'RESULT'][
'DESCR'] = $this->
formatDescription($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']);
5050 unset($this->orderData[
'BASKET_ITEMS'][$basketCode][
'DISCOUNT_RESULT']);
5052 unset($orderApplication);
5056 $this->orderData[
'BASKET_ITEMS'][$basketCode] = $currentProduct;
5057 $applyBlock[$basketCode][$index][
'RESULT'][
'APPLY'] =
'N';
5059 unset($currentProduct);
5060 if ($applyBlock[$basketCode][$index][
'RESULT'][
'APPLY'] ==
'Y')
5061 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'ACTION_APPLIED'] =
'Y';
5063 unset($discount, $index);
5064 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE_TMP'];
5065 unset($this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE_TMP']);
5067 unset($basketCode, $basketCodeList);
5084 if (empty($applyCoupons))
5089 $discountId = array();
5090 foreach ($applyCoupons as $coupon)
5091 $discountId[] = $coupon[
'DISCOUNT_ID'];
5101 foreach ($basketCodeList as $basketCode)
5103 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE_TMP'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE'];
5104 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'PRICE'];
5110 if (!$executeResult->isSuccess())
5111 $result->addErrors($executeResult->getErrors());
5112 unset($executeResult);
5114 unset($currentUseMode);
5116 foreach ($basketCodeList as $basketCode)
5118 $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE'] = $this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE_TMP'];
5119 unset($this->orderData[
'BASKET_ITEMS'][$basketCode][
'BASE_PRICE_TMP']);
5122 unset($basketCodeList);
5144 $orderCouponId !=
''
5145 && !empty($this->applyResult[
'COUPON_LIST'][$orderCouponId])
5146 && $this->applyResult[
'COUPON_LIST'][$orderCouponId] ==
'N'
5154 !empty($this->applyResult[
'DISCOUNT_LIST'][$orderDiscountId])
5155 && $this->applyResult[
'DISCOUNT_LIST'][$orderDiscountId] ==
'N'
5160 if (!empty($this->applyResult[
'BASKET'][$basketCode]))
5162 if (is_string($this->applyResult[
'BASKET'][$basketCode]))
5163 $disable = ($this->applyResult[
'BASKET'][$basketCode] ==
'N');
5164 elseif (!empty($this->applyResult[
'BASKET'][$basketCode][$orderDiscountId]))
5165 $disable = ($this->applyResult[
'BASKET'][$basketCode][$orderDiscountId] ==
'N');
5179 if (!empty($this->orderData[
'BASKET_ITEMS']))
5181 foreach (array_keys($this->orderData[
'BASKET_ITEMS']) as $basketCode)
5184 $basketItem = $this->orderData[
'BASKET_ITEMS'][$basketCode];
5185 $basketItem[
'DISCOUNT_PRICE'] = (!$customPrice
5191 if ($basketItem[
'DISCOUNT_PRICE'] > 0)
5192 $basketItem[
'PRICE'] = $basketItem[
'BASE_PRICE'] - $basketItem[
'DISCOUNT_PRICE'];
5196 $this->orderData[
'BASKET_ITEMS'][$basketCode] = $basketItem;
5198 unset($basketItem, $customPrice, $basketCode);
5212 $className = get_called_class();
5213 if (!isset(self::$instances[$className]))
5215 return isset(self::$instances[$className][$index]);
5226 $className = get_called_class();
5227 if (!isset(self::$instances[$className]))
5228 self::$instances[$className] = array();
5229 if (!isset(self::$instances[$className][$index]))
5230 self::$instances[$className][$index] = self::createObject();
5232 return self::$instances[$className][$index];
5237 $className = get_called_class();
5238 if (!isset(self::$instances[$className]))
5240 if (isset(self::$instances[$className][$oldIndex]) && !isset(self::$instances[$className][$newIndex]))
5242 self::$instances[$className][$newIndex] = self::$instances[$className][$oldIndex];
5243 unset(self::$instances[$className][$oldIndex]);
5249 $className = get_called_class();
5250 if (!isset(self::$instances[$className]))
5252 if (isset(self::$instances[$className][$index]))
5253 unset(self::$instances[$className][$index]);
5277 return $order->getInternalId().
'|0'.
'|'.$order->getSiteId();
5293 return '0|'.$basket->getFUserId(
false).
'|'.
$basket->getSiteId();
5294 return '0|-1|'.$basket->getSiteId().
'|'.
$context->getUserGroupsHash();
5316 return ($this->order instanceof
OrderBase);
5328 return $this->order->getSiteId();
5330 return $this->basket->getSiteId();
5340 protected function getCurrency()
5343 return $this->order->getCurrency();
5350 $basketItem = $this->basket->rewind();
5351 $result = $basketItem->getCurrency();
5370 $result = Internals\SiteCurrencyTable::getCurrency($this->
getSiteId());;
5371 if (is_array($result))
5372 return $result[
'CURRENCY'];
5373 $result = (string)Main\
Config\Option::get(
'sale',
'default_currency');
5376 $result = Currency\CurrencyManager::getBaseCurrency();
5393 return self::EXECUTE_FIELD_PREFIX.$fieldName;
5405 return [
'UNPACK',
'APPLICATION'];
5431 $this->discountIds = array();
5432 $userGroups = $this->context->getUserGroups();
5433 if (empty($userGroups))
5437 $customFilter = array_diff_key(
5440 '@GROUP_ID' =>
true,
5445 $filter[
'@GROUP_ID'] = $userGroups;
5446 $filter[
'=ACTIVE'] =
'Y';
5449 if (empty($customFilter))
5451 $this->discountIds = Discount\RuntimeCache\DiscountCache::getInstance()->getDiscountIds($userGroups);
5455 $discountCache = array();
5456 $groupDiscountIterator = Internals\DiscountGroupTable::getList(array(
5457 'select' => array(
'DISCOUNT_ID'),
5458 'filter' => $filter,
5459 'order' => array(
'DISCOUNT_ID' =>
'ASC')
5461 while ($groupDiscount = $groupDiscountIterator->fetch())
5463 $groupDiscount[
'DISCOUNT_ID'] = (int)$groupDiscount[
'DISCOUNT_ID'];
5464 if ($groupDiscount[
'DISCOUNT_ID'] > 0)
5465 $discountCache[$groupDiscount[
'DISCOUNT_ID']] = $groupDiscount[
'DISCOUNT_ID'];
5467 unset($groupDiscount, $groupDiscountIterator);
5468 $this->discountIds = $discountCache;
5469 unset($discountCache);
5486 if (empty($modules))
5489 foreach ($modules as $moduleId)
5491 if (!isset($this->loadedModules[$moduleId]))
5492 $this->loadedModules[$moduleId] = Main\Loader::includeModule($moduleId);
5493 if (!$this->loadedModules[$moduleId])
5513 if (empty($this->discountIds))
5517 array(
'MODULE_ID' =>
'sale',
'DISCOUNT_ID' => $this->discountIds),
5522 $this->saleDiscountCacheKey = md5(
'D'.implode(
'_', $this->discountIds));
5523 if (!empty($couponList))
5524 $this->saleDiscountCacheKey .=
'-C'.implode(
'_', array_keys($couponList));
5526 $this->saleDiscountCacheKey .=
'-MF'.implode(
'_', $this->executeModuleFilter);
5528 if (!isset($this->saleDiscountCache[$this->saleDiscountCacheKey]))
5530 $currentList = Discount\RuntimeCache\DiscountCache::getInstance()->getDiscounts(
5532 $this->executeModuleFilter,
5534 $couponList?: array()
5537 if (!empty($currentList))
5541 foreach (array_keys($currentList) as $index)
5543 $discount = $currentList[$index];
5546 unset($currentList[$index]);
5550 foreach ($executeFields as $field)
5552 if (!empty($discount[$field]))
5556 unset($field, $code, $discount, $index, $executeFields);
5558 if ($evalCode !== '')
5560 if (PHP_MAJOR_VERSION >= 7)
5566 catch (\ParseError $e)
5568 $this->showAdminError();
5579 $this->saleDiscountCache[$this->saleDiscountCacheKey] = $currentList;
5583 /* Sale disocunt hit cache methods end */
5588 private static function createObject()
5590 $registry = Registry::getInstance(static::getRegistryType());
5591 $discountClassName = $registry->getDiscountClassName();
5593 return new $discountClassName();
5604 protected function getOrderDiscountClassName()
5606 $registry = Registry::getInstance(static::getRegistryType());
5607 return $registry->getOrderDiscountClassName();
5618 protected function getDiscountCouponClassName()
5620 $registry = Registry::getInstance(static::getRegistryType());
5621 return $registry->getDiscountCouponClassName();
5632 protected function getShipmentClassName()
5634 $registry = Registry::getInstance(static::getRegistryType());
5635 return $registry->getShipmentClassName();
5644 protected function getEntityMarkerClassName(): string
5646 $registry = Registry::getInstance(static::getRegistryType());
5647 return $registry->getEntityMarkerClassName();
5650 private function showAdminError()
5652 $iterator = \CAdminNotify::GetList(
5654 array('MODULE_ID
' => 'sale
', 'TAG
' => self::ERROR_ID)
5656 $notify = $iterator->Fetch();
5661 $messages = array();
5662 $languages = Main\Localization\LanguageTable::getList(array(
5663 'select
' => array('ID
', 'DEF
'),
5664 'filter
' => array('=ACTIVE
' => 'Y
')
5666 while ($row = $languages->fetch())
5668 if ($row['DEF
'] == 'Y
')
5669 $defaultLang = $row['ID
'];
5670 $languageId = $row['ID
'];
5671 Main\Localization\Loc::loadLanguageFile(
5675 $messages[$languageId] = Main\Localization\Loc::getMessage(
5676 'BX_SALE_DISCOUNT_ERR_PARSE_ERROR
',
5677 array('#LINK#
' => '/
bitrix/admin/settings.php?lang=
'.$languageId.'&mid=sale
'),
5681 unset($row, $languages);
5683 \CAdminNotify::Add(array(
5684 'MODULE_ID
' => 'sale
',
5685 'TAG
' => self::ERROR_ID,
5686 'ENABLE_CLOSE
' => 'N
',
5687 'NOTIFY_TYPE
' => \CAdminNotify::TYPE_ERROR,
5688 'MESSAGE
' => $messages[$defaultLang],
5691 unset($messages, $defaultLang);
5701 protected static function getOrderPropertyCodes()
5704 'DELIVERY_LOCATION
' => 'IS_LOCATION
',
5705 'USER_EMAIL
' => 'IS_EMAIL
',
5706 'PAYER_NAME
' => 'IS_PAYER
',
5707 'PROFILE_NAME
' => 'IS_PROFILE_NAME
',
5708 'DELIVERY_LOCATION_ZIP
' => 'IS_ZIP
'
5719 protected static function recursiveMerge(&$dest, $src)
5721 if (!is_array($dest) || !is_array($src))
5728 foreach ($src as $key => $value)
5730 if (!isset($dest[$key]))
5732 $dest[$key] = $value;
5735 if (is_array($dest[$key]))
5736 self::recursiveMerge($dest[$key], $value);
5738 unset($value, $key);
5746 public static function getEmptyApplyBlock()
5749 'BASKET
' => array(),
5750 'BASKET_ROUND
' => array(),
5762 public static function calculateDiscountPercent($basePrice, $discount)
5764 $basePrice = (float)$basePrice;
5765 if ($basePrice <= 0)
5767 $discount = (float)$discount;
5768 if ($discount > $basePrice)
5771 $result = round(100*$discount/$basePrice, 0);
5782 public function getShowPrices()
5784 if (!$this->isOrderNew() && !$this->isLoaded())
5786 $this->initUseMode();
5787 $this->loadOrderData();
5795 $useMode = $this->getUseMode();
5798 case self::USE_MODE_APPLY:
5799 case self::USE_MODE_MIXED:
5800 if (!$this->isValidState())
5801 $checkRound = false;
5805 if (!empty($this->orderData['BASKET_ITEMS
']))
5808 $storageClassName = $this->getOrderDiscountClassName();
5810 $basket = $this->orderData['BASKET_ITEMS
'];
5811 $order = $this->orderData;
5812 unset($order['BASKET_ITEMS
']);
5816 case self::USE_MODE_FULL:
5817 case self::USE_MODE_APPLY:
5820 $basketCodeList = $this->getBasketCodes(true);
5821 $existRound = array();
5822 $existRoundRules = array();
5823 foreach ($basketCodeList as $basketCode)
5825 if (!empty($this->basketItemsData[$basketCode]['BASE_PRICE_ROUND_RULE
']))
5827 $existRound[$basketCode] = self::resetBasketItemPrice($basket[$basketCode]);
5828 $existRoundRules[$basketCode] = $this->basketItemsData[$basketCode]['BASE_PRICE_ROUND_RULE
'];
5831 if (!empty($existRound))
5833 $roundResult = $storageClassName::roundBasket(
5838 foreach ($roundResult as $basketCode => $row)
5840 if (empty($row) || !is_array($row))
5842 if (!isset($existRound[$basketCode]))
5844 $basket[$basketCode]['BASE_PRICE
'] = $row['PRICE
'];
5845 $basket[$basketCode]['DISCOUNT_PRICE
'] = $basket[$basketCode]['BASE_PRICE
'] - $basket[$basketCode]['PRICE
'];
5848 unset($existRoundRules, $existRound);
5851 case self::USE_MODE_MIXED:
5854 $existRound = array();
5855 $existRoundRules = array();
5856 foreach ($basket as $basketCode => $item)
5858 if ($this->isFreezedBasketItem($item))
5860 if (!empty($this->basketItemsData[$basketCode]['BASE_PRICE_ROUND_RULE
']))
5862 $existRound[$basketCode] = self::resetBasketItemPrice($basket[$basketCode]);
5863 $existRoundRules[$basketCode] = $this->basketItemsData[$basketCode]['BASE_PRICE_ROUND_RULE
'];
5866 unset($code, $item);
5867 if (!empty($existRound))
5869 $roundResult = $storageClassName::roundBasket(
5874 foreach ($roundResult as $basketCode => $row)
5876 if (empty($row) || !is_array($row))
5878 if (!isset($existRound[$basketCode]))
5880 $basket[$basketCode]['BASE_PRICE
'] = $row['PRICE
'];
5881 $basket[$basketCode]['DISCOUNT_PRICE
'] = $basket[$basketCode]['BASE_PRICE
'] - $basket[$basketCode]['PRICE
'];
5884 unset($existRoundRules, $existRound);
5889 foreach ($basket as $basketCode => $basketItem)
5891 $result['BASKET
'][$basketCode] = $this->getShowBasketItemPrice($basketCode, $basketItem);
5892 $result['BASKET
'][$basketCode]['REAL_BASE_PRICE
'] = $this->orderData['BASKET_ITEMS
'][$basketCode]['BASE_PRICE
'];
5893 $result['BASKET
'][$basketCode]['REAL_PRICE
'] = $this->orderData['BASKET_ITEMS
'][$basketCode]['PRICE
'];
5894 $result['BASKET
'][$basketCode]['REAL_DISCOUNT
'] = $this->orderData['BASKET_ITEMS
'][$basketCode]['DISCOUNT_PRICE
'];
5896 unset($basketCode, $basketItem);
5908 private function getRoundForBasePrices()
5910 $mode = $this->getUseMode();
5911 if ($mode != self::USE_MODE_FULL && $mode != self::USE_MODE_MIXED)
5914 $basketCodeList = $this->getBasketCodes(true);
5915 if (empty($basketCodeList))
5918 $basket = array_intersect_key(
5919 $this->orderData['BASKET_ITEMS
'],
5920 array_fill_keys($basketCodeList, true)
5926 foreach ($basketCodeList as $basketCode)
5928 $this->addBasketItemValues(
5930 ['BASE_PRICE_ROUND
' => $basket[$basketCode]['BASE_PRICE
'], 'BASE_PRICE_ROUND_RULE
' => []]
5935 foreach ($basket as &$basketItem)
5936 $basketItem = self::resetBasketItemPrice($basketItem);
5939 $orderData = $this->orderData;
5940 unset($orderData['BASKET_ITEMS
']);
5943 $storageClassName = $this->getOrderDiscountClassName();
5945 $result = $storageClassName::roundBasket(
5950 foreach ($basketCodeList as $basketCode)
5952 if (empty($result[$basketCode]) || !is_array($result[$basketCode]))
5954 $this->addBasketItemValues(
5957 'BASE_PRICE_ROUND
' => $result[$basketCode]['PRICE
'],
5958 'BASE_PRICE_ROUND_RULE
' => $result[$basketCode]['ROUND_RULE
']
5962 unset($basketCode, $result);
5963 unset($storageClassName);
5964 unset($basket, $orderData);
5974 private function getShowBasketItemPrice($basketCode, array $item)
5976 if ($this->isFreezedBasketItem($item))
5978 if ($item['BASE_PRICE
'] <= $item['PRICE
'])
5979 $result = $this->getShowPriceWithZeroDiscountPercent($item);
5981 $result = $this->getShowPriceWithDiscountPercent($item);
5985 if ($item['BASE_PRICE
'] <= $item['PRICE
'])
5986 return $this->getShowPriceWithZeroDiscountPercent($item);
5988 if ($this->isExistBasketItemDiscount($basketCode))
5989 return $this->getShowPriceWithDiscountPercent($item);
5991 return $this->getShowPriceWithZeroDiscountPercent($item);
6000 private function getShowPriceWithDiscountPercent(array $item)
6003 'SHOW_BASE_PRICE
' => $item['BASE_PRICE
'],
6004 'SHOW_PRICE
' => $item['PRICE
'],
6005 'SHOW_DISCOUNT
' => $item['DISCOUNT_PRICE
'],
6006 'SHOW_DISCOUNT_PERCENT
' => $this->calculateDiscountPercent(
6007 $item['BASE_PRICE
'],
6008 $item['DISCOUNT_PRICE
']
6019 private function getShowPriceWithZeroDiscountPercent(array $item)
6022 'SHOW_BASE_PRICE
' => $item['PRICE
'],
6023 'SHOW_PRICE
' => $item['PRICE
'],
6024 'SHOW_DISCOUNT
' => 0,
6025 'SHOW_DISCOUNT_PERCENT
' => 0
6035 private function isExistBasketItemDiscount($basketCode)
6039 if (!empty($this->discountResult['APPLY_BLOCKS
']))
6041 foreach ($this->discountResult['APPLY_BLOCKS
'] as $counter => $applyBlock)
6043 if (isset($applyBlock['BASKET
'][$basketCode]))
6045 foreach ($applyBlock['BASKET
'][$basketCode] as $discount)
6047 if ($discount['RESULT
']['APPLY
'] == 'Y
')
6053 if (!empty($applyBlock['ORDER
']))
6055 foreach ($applyBlock['ORDER
'] as $discount)
6057 if (!empty($discount['RESULT
']['BASKET
']))
6059 if (!isset($discount['RESULT
']['BASKET
'][$basketCode]))
6061 if ($discount['RESULT
']['BASKET
'][$basketCode]['APPLY
'] == 'Y
')
6068 unset($counter, $applyBlock);
6080 private function prepareBasketItemStoredData($basketCode)
6083 if (isset($this->basketItemsData[$basketCode]))
6085 if (isset($this->basketItemsData[$basketCode]['BASE_PRICE_ROUND_RULE
']))
6086 $result['BASE_PRICE_ROUND_RULE
'] = $this->basketItemsData[$basketCode]['BASE_PRICE_ROUND_RULE
'];
6089 return (!empty($result) ? $result : null);
6098 private static function resetBasketItemPrice(array $item)
6100 $item['PRICE
'] = $item['BASE_PRICE
'];
6101 $item['DISCOUNT_PRICE
'] = 0;
6113 private function addBasketItemValues($basketCode, array $values)
6118 if (!isset($this->basketItemsData[$basketCode]))
6120 $this->basketItemsData[$basketCode] = $values;
6124 foreach ($values as $index => $value)
6125 $this->basketItemsData[$basketCode][$index] = $value;
6126 unset($index, $value);