Ejemplo n.º 1
0
 public static function DoProcessOrder(&$arOrder, $arOptions, &$arErrors)
 {
     if (empty($arOrder['BASKET_ITEMS']) || !is_array($arOrder['BASKET_ITEMS'])) {
         return;
     }
     $arIDS = array();
     $groupDiscountIterator = Internals\DiscountGroupTable::getList(array('select' => array('DISCOUNT_ID'), 'filter' => array('@GROUP_ID' => CUser::GetUserGroup($arOrder['USER_ID']), '=ACTIVE' => 'Y')));
     while ($groupDiscount = $groupDiscountIterator->fetch()) {
         $groupDiscount['DISCOUNT_ID'] = (int) $groupDiscount['DISCOUNT_ID'];
         if ($groupDiscount['DISCOUNT_ID'] > 0) {
             $arIDS[$groupDiscount['DISCOUNT_ID']] = true;
         }
     }
     if (!empty($arIDS)) {
         $arIDS = array_keys($arIDS);
         $couponList = DiscountCouponsManager::getForApply(array('MODULE' => 'sale', 'DISCOUNT_ID' => $arIDS), array(), true);
         $arExtend = array('catalog' => array('fields' => true, 'props' => true));
         foreach (GetModuleEvents('sale', 'OnExtendBasketItems', true) as $arEvent) {
             ExecuteModuleEventEx($arEvent, array(&$arOrder['BASKET_ITEMS'], $arExtend));
         }
         foreach ($arOrder['BASKET_ITEMS'] as &$arOneItem) {
             if (array_key_exists('PRODUCT_PROVIDER_CLASS', $arOneItem) && empty($arOneItem['PRODUCT_PROVIDER_CLASS']) && array_key_exists('CALLBACK_FUNC', $arOneItem) && empty($arOneItem['CALLBACK_FUNC']) && (!isset($arOneItem['CUSTOM_PRICE']) || $arOneItem['CUSTOM_PRICE'] != 'Y')) {
                 if (isset($arOneItem['DISCOUNT_PRICE'])) {
                     $arOneItem['PRICE'] += $arOneItem['DISCOUNT_PRICE'];
                     $arOneItem['DISCOUNT_PRICE'] = 0;
                 }
             }
         }
         if (isset($arOneItem)) {
             unset($arOneItem);
         }
         if (empty(self::$cacheDiscountHandlers)) {
             self::$cacheDiscountHandlers = CSaleDiscount::getDiscountHandlers($arIDS);
         } else {
             $needDiscountHandlers = array();
             foreach ($arIDS as &$discountID) {
                 if (!isset(self::$cacheDiscountHandlers[$discountID])) {
                     $needDiscountHandlers[] = $discountID;
                 }
             }
             unset($discountID);
             if (!empty($needDiscountHandlers)) {
                 $discountHandlersList = CSaleDiscount::getDiscountHandlers($needDiscountHandlers);
                 if (!empty($discountHandlersList)) {
                     foreach ($discountHandlersList as $discountID => $discountHandlers) {
                         self::$cacheDiscountHandlers[$discountID] = $discountHandlers;
                     }
                     unset($discountHandlers, $discountID);
                 }
                 unset($discountHandlersList);
             }
             unset($needDiscountHandlers);
         }
         CTimeZone::Disable();
         $currentDatetime = new Type\DateTime();
         $discountSelect = array('ID', 'PRIORITY', 'SORT', 'LAST_DISCOUNT', 'UNPACK', 'APPLICATION', 'USE_COUPONS');
         $discountOrder = array('PRIORITY' => 'DESC', 'SORT' => 'ASC', 'ID' => 'ASC');
         $discountFilter = array('@ID' => $arIDS, '=LID' => $arOrder['SITE_ID'], array('LOGIC' => 'OR', 'ACTIVE_FROM' => '', '<=ACTIVE_FROM' => $currentDatetime), array('LOGIC' => 'OR', 'ACTIVE_TO' => '', '>=ACTIVE_TO' => $currentDatetime));
         if (empty($couponList)) {
             $discountFilter['=USE_COUPONS'] = 'N';
         } else {
             $discountFilter[] = array('LOGIC' => 'OR', '=USE_COUPONS' => 'N', array('=USE_COUPONS' => 'Y', '=COUPON.COUPON' => array_keys($couponList)));
             $discountSelect['DISCOUNT_COUPON'] = 'COUPON.COUPON';
         }
         $discountIterator = Internals\DiscountTable::getList(array('select' => $discountSelect, 'filter' => $discountFilter, 'order' => $discountOrder));
         $discountApply = array();
         $resultDiscountList = array();
         $resultDiscountKeys = array();
         $resultDiscountIndex = 0;
         while ($discount = $discountIterator->fetch()) {
             $discount['ID'] = (int) $discount['ID'];
             if (isset($discountApply[$discount['ID']])) {
                 continue;
             }
             $discount['MODULE'] = 'sale';
             $discountApply[$discount['ID']] = true;
             $applyFlag = true;
             if (isset(self::$cacheDiscountHandlers[$discount['ID']])) {
                 $moduleList = self::$cacheDiscountHandlers[$discount['ID']]['MODULES'];
                 if (!empty($moduleList)) {
                     foreach ($moduleList as &$moduleID) {
                         if (!isset(self::$usedModules[$moduleID])) {
                             self::$usedModules[$moduleID] = Loader::includeModule($moduleID);
                         }
                         if (!self::$usedModules[$moduleID]) {
                             $applyFlag = false;
                             break;
                         }
                     }
                     unset($moduleID);
                 }
                 unset($moduleList);
             }
             if ($applyFlag && self::__Unpack($arOrder, $discount['UNPACK'])) {
                 $oldOrder = $arOrder;
                 self::__ApplyActions($arOrder, $discount['APPLICATION']);
                 $discountResult = self::getDiscountResult($oldOrder, $arOrder, false);
                 if (!empty($discountResult['DELIVERY']) || !empty($discountResult['BASKET'])) {
                     if ($discount['USE_COUPONS'] == 'Y' && !empty($discount['DISCOUNT_COUPON'])) {
                         if ($couponList[$discount['DISCOUNT_COUPON']]['TYPE'] == Internals\DiscountCouponTable::TYPE_BASKET_ROW) {
                             self::changeDiscountResult($oldOrder, $arOrder, $discountResult);
                         }
                         $couponApply = DiscountCouponsManager::setApply($discount['DISCOUNT_COUPON'], $discountResult);
                     }
                     $resultDiscountList[$resultDiscountIndex] = array('MODULE_ID' => $discount['MODULE_ID'], 'ID' => $discount['ID'], 'PRIORITY' => $discount['PRIORITY'], 'SORT' => $discount['SORT'], 'LAST_DISCOUNT' => $discount['LAST_DISCOUNT'], 'UNPACK' => $discount['UNPACK'], 'APPLICATION' => $discount['APPLICATION'], 'RESULT' => $discountResult, 'HANDLERS' => self::$cacheDiscountHandlers[$discount['ID']], 'USE_COUPONS' => $discount['USE_COUPONS'], 'COUPON' => $discount['USE_COUPONS'] == 'Y' ? $couponList[$discount['DISCOUNT_COUPON']] : false);
                     $resultDiscountKeys[$discount['ID']] = $resultDiscountIndex;
                     $resultDiscountIndex++;
                     if ($discount['LAST_DISCOUNT'] == 'Y') {
                         break;
                     }
                 }
                 unset($discountResult);
             }
         }
         unset($discount, $discountIterator);
         CTimeZone::Enable();
         if ($resultDiscountIndex > 0) {
             $discountIterator = Internals\DiscountTable::getList(array('select' => array('ID', 'NAME', 'CONDITIONS', 'ACTIONS'), 'filter' => array('@ID' => array_keys($resultDiscountKeys))));
             while ($discount = $discountIterator->fetch()) {
                 $discount['ID'] = (int) $discount['ID'];
                 if (isset($resultDiscountKeys[$discount['ID']])) {
                     $key = $resultDiscountKeys[$discount['ID']];
                     $resultDiscountList[$key]['NAME'] = $discount['NAME'];
                     $resultDiscountList[$key]['CONDITIONS'] = $discount['CONDITIONS'];
                     $resultDiscountList[$key]['ACTIONS'] = $discount['ACTIONS'];
                 }
             }
             unset($discount, $discountIterator);
         }
         $arOrder["ORDER_PRICE"] = 0;
         $arOrder["ORDER_WEIGHT"] = 0;
         $arOrder["USE_VAT"] = false;
         $arOrder["VAT_RATE"] = 0;
         $arOrder["VAT_SUM"] = 0;
         $arOrder["DISCOUNT_PRICE"] = 0.0;
         $arOrder["DISCOUNT_VALUE"] = $arOrder["DISCOUNT_PRICE"];
         $arOrder["DELIVERY_PRICE"] = $arOrder["PRICE_DELIVERY"];
         foreach ($arOrder['BASKET_ITEMS'] as &$arShoppingCartItem) {
             if (!CSaleBasketHelper::isSetItem($arShoppingCartItem)) {
                 $arOrder["ORDER_PRICE"] += doubleval($arShoppingCartItem["PRICE"]) * doubleval($arShoppingCartItem["QUANTITY"]);
                 $arOrder["ORDER_WEIGHT"] += $arShoppingCartItem["WEIGHT"] * $arShoppingCartItem["QUANTITY"];
                 $arShoppingCartItem["PRICE_FORMATED"] = CCurrencyLang::CurrencyFormat($arShoppingCartItem["PRICE"], $arShoppingCartItem["CURRENCY"], true);
                 $arShoppingCartItem["DISCOUNT_PRICE_PERCENT"] = 0;
                 if ($arShoppingCartItem["DISCOUNT_PRICE"] + $arShoppingCartItem["PRICE"] > 0) {
                     $arShoppingCartItem["DISCOUNT_PRICE_PERCENT"] = $arShoppingCartItem["DISCOUNT_PRICE"] * 100 / ($arShoppingCartItem["DISCOUNT_PRICE"] + $arShoppingCartItem["PRICE"]);
                 }
                 $arShoppingCartItem["DISCOUNT_PRICE_PERCENT_FORMATED"] = roundEx($arShoppingCartItem["DISCOUNT_PRICE_PERCENT"], SALE_VALUE_PRECISION) . "%";
                 if ($arShoppingCartItem["VAT_RATE"] > 0) {
                     $arOrder["USE_VAT"] = true;
                     if ($arShoppingCartItem["VAT_RATE"] > $arOrder["VAT_RATE"]) {
                         $arOrder["VAT_RATE"] = $arShoppingCartItem["VAT_RATE"];
                     }
                     $arOrder["VAT_SUM"] += $arShoppingCartItem["VAT_VALUE"] * $arShoppingCartItem["QUANTITY"];
                 }
             }
         }
         if (isset($arShoppingCartItem)) {
             unset($arShoppingCartItem);
         }
         $arOrder['DISCOUNT_LIST'] = $resultDiscountList;
     }
 }
Ejemplo n.º 2
0
 /**
  * @param array $arParams
  * @return array|false
  */
 public static function OrderProduct($arParams)
 {
     $adminSection = defined('ADMIN_SECTION') && ADMIN_SECTION === true;
     $arParams['RENEWAL'] = isset($arParams['RENEWAL']) && $arParams['RENEWAL'] == 'Y' ? 'Y' : 'N';
     $arParams['CHECK_QUANTITY'] = isset($arParams['CHECK_QUANTITY']) && $arParams['CHECK_QUANTITY'] == 'N' ? 'N' : 'Y';
     $arParams['CHECK_DISCOUNT'] = isset($arParams['CHECK_DISCOUNT']) && $arParams['CHECK_DISCOUNT'] == 'N' ? 'N' : 'Y';
     $arParams['USER_ID'] = isset($arParams['USER_ID']) ? (int) $arParams['USER_ID'] : 0;
     if ($arParams['USER_ID'] < 0) {
         $arParams['USER_ID'] = 0;
     }
     $arParams['SITE_ID'] = isset($arParams['SITE_ID']) ? $arParams['SITE_ID'] : false;
     $strSiteID = $arParams['SITE_ID'];
     $arParams['BASKET_ID'] = (string) (isset($arParams['BASKET_ID']) ? $arParams['BASKET_ID'] : '0');
     $arParams['CURRENCY'] = isset($arParams['CURRENCY']) ? Currency\CurrencyManager::checkCurrencyID($arParams['CURRENCY']) : false;
     if ($arParams['CURRENCY'] === false) {
         $arParams['CURRENCY'] = CSaleLang::GetLangCurrency($strSiteID ? $strSiteID : SITE_ID);
     }
     global $USER;
     $productID = (int) $arParams['PRODUCT_ID'];
     $quantity = (double) $arParams['QUANTITY'];
     $intUserID = (int) $arParams['USER_ID'];
     $arResult = array();
     if ($adminSection) {
         if ($intUserID == 0) {
             return $arResult;
         }
         if (!($userGroups = static::getHitCache('USER_GROUPS', $intUserID))) {
             $userGroups = self::getUserGroups($intUserID);
             static::setHitCache('USER_GROUPS', $intUserID, $userGroups);
         }
         if (empty($userGroups)) {
             return $arResult;
         }
         if (!($arProduct = static::getHitCache('IBLOCK_ELEMENT_PERM_N', $productID))) {
             $dbIBlockElement = CIBlockElement::GetList(array(), array('ID' => $productID, 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y', 'CHECK_PERMISSION' => 'N'), false, false, array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL'));
             if ($arProduct = $dbIBlockElement->GetNext()) {
                 static::setHitCache('IBLOCK_ELEMENT_PERM_N', $productID, $arProduct);
             }
             unset($dbIBlockElement);
         }
         if (empty($arProduct) || !is_array($arProduct)) {
             return $arResult;
         }
         $iblockRightByID = null;
         if (!($iblockRightByID = static::getHitCache('IBLOCK_RIGHT', $arProduct['IBLOCK_ID']))) {
             if ($iblockRightByID = CIBlock::GetArrayByID($arProduct['IBLOCK_ID'], 'RIGHTS_MODE')) {
                 static::setHitCache('IBLOCK_RIGHT', $arProduct['IBLOCK_ID'], $iblockRightByID);
             }
         }
         if ($iblockRightByID == 'E') {
             $proxyUserPermissionKey = $productID . "|" . $intUserID;
             if (!($arUserRights = static::getHitCache('USER_RIGHT', $proxyUserPermissionKey))) {
                 if ($arUserRights = CIBlockElementRights::GetUserOperations($productID, $intUserID)) {
                     static::setHitCache('USER_RIGHT', $proxyUserPermissionKey, $arUserRights);
                 }
             }
             if (empty($arUserRights) || !isset($arUserRights['element_read'])) {
                 return $arResult;
             }
             unset($arUserRights);
         } else {
             $proxyIblockPermissionKey = $arProduct['IBLOCK_ID'] . "|" . $intUserID;
             if (!($iblockPermissions = static::getHitCache('IBLOCK_PERM', $proxyIblockPermissionKey))) {
                 if ($iblockPermissions = CIBlock::GetPermission($arProduct['IBLOCK_ID'], $intUserID)) {
                     static::setHitCache('IBLOCK_PERM', $proxyIblockPermissionKey, $iblockPermissions);
                 }
             }
             if ($iblockPermissions < 'R') {
                 return $arResult;
             }
         }
     } else {
         $userGroups = $USER->GetUserGroupArray();
         if (!($arProduct = static::getHitCache('IBLOCK_ELEMENT_PERM_Y', $productID))) {
             $dbIBlockElement = CIBlockElement::GetList(array(), array('ID' => $productID, 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y', 'CHECK_PERMISSIONS' => 'Y', 'MIN_PERMISSION' => 'R'), false, false, array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL'));
             if ($arProduct = $dbIBlockElement->GetNext()) {
                 static::setHitCache('IBLOCK_ELEMENT_PERM_Y', $productID, $arProduct);
             }
             unset($dbIBlockElement);
         }
         if (empty($arProduct) || !is_array($arProduct)) {
             return $arResult;
         }
     }
     if (!($arCatalogProduct = static::getHitCache('CATALOG_PRODUCT', $productID))) {
         $rsProducts = CCatalogProduct::GetList(array(), array('ID' => $productID), false, false, array('ID', 'CAN_BUY_ZERO', 'QUANTITY_TRACE', 'QUANTITY', 'WEIGHT', 'WIDTH', 'HEIGHT', 'LENGTH', 'BARCODE_MULTI', 'TYPE'));
         if ($arCatalogProduct = $rsProducts->Fetch()) {
             static::setHitCache('CATALOG_PRODUCT', $productID, $arCatalogProduct);
         }
         unset($rsProducts);
     }
     if (!empty($arCatalogProduct) && is_array($arCatalogProduct)) {
         $arCatalogProduct["QUANTITY"] = (double) $arCatalogProduct["QUANTITY"];
         if ($arParams["CHECK_QUANTITY"] == "Y") {
             if ('Y' != $arCatalogProduct["CAN_BUY_ZERO"] && 'Y' == $arCatalogProduct["QUANTITY_TRACE"] && ($arCatalogProduct["QUANTITY"] <= 0 || $quantity > $arCatalogProduct["QUANTITY"])) {
                 return $arResult;
             }
         }
     } else {
         return $arResult;
     }
     if ($adminSection) {
         CCatalogDiscountSave::SetDiscountUserID($intUserID);
     }
     $productHash = array('MODULE' => 'catalog', 'PRODUCT_ID' => $productID, 'BASKET_ID' => $arParams['BASKET_ID']);
     $arCoupons = DiscountCouponsManager::getForApply(array(), $productHash, true);
     if (!empty($arCoupons)) {
         $arCoupons = array_keys($arCoupons);
     }
     $currentVatMode = CCatalogProduct::getPriceVatIncludeMode();
     $currentUseDiscount = CCatalogProduct::getUseDiscount();
     CCatalogProduct::setUseDiscount($arParams['CHECK_DISCOUNT'] == 'Y');
     CCatalogProduct::setPriceVatIncludeMode(true);
     CCatalogProduct::setUsedCurrency($arParams['CURRENCY']);
     $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $userGroups, $arParams['RENEWAL'], array(), $adminSection ? $strSiteID : false, $arCoupons);
     if (empty($arPrice)) {
         if ($nearestQuantity = CCatalogProduct::GetNearestQuantityPrice($productID, $quantity, $userGroups)) {
             $quantity = $nearestQuantity;
             $arPrice = CCatalogProduct::GetOptimalPrice($productID, $quantity, $userGroups, $arParams['RENEWAL'], array(), $adminSection ? $strSiteID : false, $arCoupons);
         }
     }
     CCatalogProduct::clearUsedCurrency();
     CCatalogProduct::setPriceVatIncludeMode($currentVatMode);
     CCatalogProduct::setUseDiscount($currentUseDiscount);
     unset($userGroups, $currentUseDiscount, $currentVatMode);
     if ($adminSection) {
         CCatalogDiscountSave::ClearDiscountUserID();
     }
     if (empty($arPrice)) {
         return $arResult;
     }
     $arDiscountList = array();
     if (empty($arPrice['DISCOUNT_LIST']) && !empty($arPrice['DISCOUNT']) && is_array($arPrice['DISCOUNT'])) {
         $arPrice['DISCOUNT_LIST'] = array($arPrice['DISCOUNT']);
     }
     if (!empty($arPrice['DISCOUNT_LIST'])) {
         $appliedCoupons = array();
         foreach ($arPrice['DISCOUNT_LIST'] as &$arOneDiscount) {
             $arOneList = array('ID' => $arOneDiscount['ID'], 'NAME' => $arOneDiscount['NAME'], 'COUPON' => '', 'COUPON_TYPE' => '', 'USE_COUPONS' => isset($arOneDiscount['USE_COUPONS']) ? $arOneDiscount['USE_COUPONS'] : 'N', 'MODULE_ID' => isset($oneDiscount['MODULE_ID']) ? $oneDiscount['MODULE_ID'] : 'catalog', 'TYPE' => $arOneDiscount['TYPE'], 'VALUE' => $arOneDiscount['VALUE'], 'VALUE_TYPE' => $arOneDiscount['VALUE_TYPE'], 'MAX_VALUE' => $arOneDiscount['VALUE_TYPE'] == Catalog\DiscountTable::VALUE_TYPE_PERCENT ? $arOneDiscount['MAX_DISCOUNT'] : 0, 'CURRENCY' => $arOneDiscount['CURRENCY'], 'HANDLERS' => isset($arOneDiscount['HANDLERS']) ? $arOneDiscount['HANDLERS'] : array());
             if (!empty($arOneDiscount['COUPON'])) {
                 $arOneList['USE_COUPONS'] = 'Y';
                 $arOneList['COUPON'] = $arOneDiscount['COUPON'];
                 $arOneList['COUPON_TYPE'] = $arOneDiscount['COUPON_ONE_TIME'];
                 $appliedCoupons[] = $arOneDiscount['COUPON'];
             }
             $arDiscountList[] = $arOneList;
         }
         unset($arOneList, $arOneDiscount);
         if (!empty($appliedCoupons)) {
             $resultApply = DiscountCouponsManager::setApplyByProduct($productHash, $appliedCoupons);
         }
         unset($resultApply, $appliedCoupons);
     }
     if (empty($arPrice['PRICE']['CATALOG_GROUP_NAME'])) {
         if (!empty($arPrice['PRICE']['CATALOG_GROUP_ID'])) {
             $priceName = self::getPriceTitle($arPrice['PRICE']['CATALOG_GROUP_ID']);
             if ($priceName != '') {
                 $arPrice['PRICE']['CATALOG_GROUP_NAME'] = $priceName;
             }
             unset($priceName);
         }
     }
     if (empty($arPrice['RESULT_PRICE']) || !is_array($arPrice['RESULT_PRICE'])) {
         $arPrice['RESULT_PRICE'] = CCatalogDiscount::calculateDiscountList($arPrice['PRICE'], $arParams['CURRENCY'], $arDiscountList, true);
     }
     $arResult = array('PRODUCT_PRICE_ID' => $arPrice['PRICE']['ID'], 'BASE_PRICE' => $arPrice['RESULT_PRICE']['BASE_PRICE'], 'PRICE' => $arPrice['RESULT_PRICE']['DISCOUNT_PRICE'], 'VAT_RATE' => $arPrice['PRICE']['VAT_RATE'], "CURRENCY" => $arPrice['RESULT_PRICE']['CURRENCY'], "WEIGHT" => (double) $arCatalogProduct["WEIGHT"], "DIMENSIONS" => serialize(array("WIDTH" => $arCatalogProduct["WIDTH"], "HEIGHT" => $arCatalogProduct["HEIGHT"], "LENGTH" => $arCatalogProduct["LENGTH"])), "NAME" => $arProduct["~NAME"], "CAN_BUY" => "Y", "DETAIL_PAGE_URL" => $arProduct['~DETAIL_PAGE_URL'], "NOTES" => $arPrice["PRICE"]["CATALOG_GROUP_NAME"], "DISCOUNT_PRICE" => $arPrice['RESULT_PRICE']['DISCOUNT'], "TYPE" => $arCatalogProduct["TYPE"] == CCatalogProduct::TYPE_SET ? CCatalogProductSet::TYPE_SET : null, "DISCOUNT_VALUE" => $arPrice['RESULT_PRICE']['PERCENT'] > 0 ? $arPrice['RESULT_PRICE']['PERCENT'] . '%' : 0, "DISCOUNT_NAME" => '', "DISCOUNT_COUPON" => '', "DISCOUNT_LIST" => array());
     if ($arParams["CHECK_QUANTITY"] == "Y") {
         $arResult["QUANTITY"] = $quantity;
     } else {
         $arResult["QUANTITY"] = $arParams["QUANTITY"];
     }
     if (!empty($arDiscountList)) {
         $arResult['DISCOUNT_LIST'] = $arDiscountList;
     }
     if (!empty($arPrice['DISCOUNT'])) {
         $arResult['DISCOUNT_NAME'] = '[' . $arPrice['DISCOUNT']['ID'] . '] ' . $arPrice['DISCOUNT']['NAME'];
         if (!empty($arPrice['DISCOUNT']['COUPON'])) {
             $arResult['DISCOUNT_COUPON'] = $arPrice['DISCOUNT']['COUPON'];
         }
         if (empty($arResult['DISCOUNT_LIST'])) {
             $arResult['DISCOUNT_LIST'] = array($arPrice['DISCOUNT']);
         }
     }
     $arResult["VAT_INCLUDED"] = "Y";
     return $arResult;
 }
Ejemplo n.º 3
0
 /**
  * @param int $intProductID
  * @param int $intIBlockID
  * @param array $arCatalogGroups
  * @param array $arUserGroups
  * @param string $strRenewal
  * @param bool|string $siteID
  * @param bool|array $arDiscountCoupons
  * @param bool $boolSKU
  * @param bool $boolGetIDS
  * @return array|false
  */
 public function GetDiscount($intProductID, $intIBlockID, $arCatalogGroups = array(), $arUserGroups = array(), $strRenewal = "N", $siteID = false, $arDiscountCoupons = false, $boolSKU = true, $boolGetIDS = false)
 {
     static $eventOnGetExists = null;
     static $eventOnResultExists = null;
     global $DB, $APPLICATION;
     self::initDiscountSettings();
     if ($eventOnGetExists === true || $eventOnGetExists === null) {
         foreach (GetModuleEvents("catalog", "OnGetDiscount", true) as $arEvent) {
             $eventOnGetExists = true;
             $mxResult = ExecuteModuleEventEx($arEvent, array($intProductID, $intIBlockID, $arCatalogGroups, $arUserGroups, $strRenewal, $siteID, $arDiscountCoupons, $boolSKU, $boolGetIDS));
             if ($mxResult !== true) {
                 return $mxResult;
             }
         }
         if ($eventOnGetExists === null) {
             $eventOnGetExists = false;
         }
     }
     $boolSKU = $boolSKU === true;
     $boolGetIDS = $boolGetIDS === true;
     $intProductID = (int) $intProductID;
     if ($intProductID <= 0) {
         $APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_DISC_ERR_PRODUCT_ID_ABSENT"), "NO_PRODUCT_ID");
         return false;
     }
     $intIBlockID = (int) $intIBlockID;
     if ($intIBlockID <= 0) {
         $APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_DISC_ERR_IBLOCK_ID_ABSENT"), "NO_IBLOCK_ID");
         return false;
     }
     if (!is_array($arUserGroups)) {
         $arUserGroups = array($arUserGroups);
     }
     $arUserGroups[] = 2;
     if (!empty($arUserGroups)) {
         Main\Type\Collection::normalizeArrayValuesByInt($arUserGroups, true);
     }
     if (!is_array($arCatalogGroups)) {
         $arCatalogGroups = array($arCatalogGroups);
     }
     if (empty($arCatalogGroups)) {
         $catalogGroupIterator = CCatalogGroup::GetGroupsList(array('GROUP_ID' => $arUserGroups, 'BUY' => array('Y', 'N')));
         while ($catalogGroup = $catalogGroupIterator->Fetch()) {
             $arCatalogGroups[$catalogGroup['CATALOG_GROUP_ID']] = $catalogGroup['CATALOG_GROUP_ID'];
         }
         unset($catalogGroup, $catalogGroupIterator);
     }
     if (!empty($arCatalogGroups)) {
         Main\Type\Collection::normalizeArrayValuesByInt($arCatalogGroups, true);
     }
     if (empty($arCatalogGroups)) {
         return false;
     }
     $strRenewal = (string) $strRenewal == 'Y' ? 'Y' : 'N';
     if ($siteID === false) {
         $siteID = SITE_ID;
     }
     $arSKUExt = false;
     if ($boolSKU) {
         $arSKUExt = CCatalogSKU::GetInfoByOfferIBlock($intIBlockID);
         $boolSKU = !empty($arSKUExt);
     }
     $arResult = array();
     $arResultID = array();
     if (self::$useSaleDiscount) {
     } else {
         $strCacheKey = md5('C' . implode('_', $arCatalogGroups) . '-' . 'U' . implode('_', $arUserGroups));
         if (!isset(self::$arCacheDiscountFilter[$strCacheKey])) {
             $arFilter = array('PRICE_TYPE_ID' => $arCatalogGroups, 'USER_GROUP_ID' => $arUserGroups);
             $arDiscountIDs = CCatalogDiscount::__GetDiscountID($arFilter);
             if (!empty($arDiscountIDs)) {
                 sort($arDiscountIDs);
             }
             self::$arCacheDiscountFilter[$strCacheKey] = $arDiscountIDs;
         } else {
             $arDiscountIDs = self::$arCacheDiscountFilter[$strCacheKey];
         }
         $arProduct = array();
         if (!empty($arDiscountIDs)) {
             if ($arDiscountCoupons === false) {
                 if (self::$existCouponsManager && Loader::includeModule('sale')) {
                     $arDiscountCoupons = DiscountCouponsManager::getForApply(array('MODULE' => 'catalog', 'DISCOUNT_ID' => $arDiscountIDs), array('MODULE' => 'catalog', 'PRODUCT_ID' => $intProductID, 'BASKET_ID' => '0'), true);
                     if (!empty($arDiscountCoupons)) {
                         $arDiscountCoupons = array_keys($arDiscountCoupons);
                     }
                 } else {
                     if (!isset($_SESSION['CATALOG_USER_COUPONS']) || !is_array($_SESSION['CATALOG_USER_COUPONS'])) {
                         $_SESSION['CATALOG_USER_COUPONS'] = array();
                     }
                     $arDiscountCoupons = $_SESSION["CATALOG_USER_COUPONS"];
                 }
             }
             if ($arDiscountCoupons === false) {
                 $arDiscountCoupons = array();
             }
             $boolGenerate = false;
             if (empty(self::$cacheDiscountHandlers)) {
                 self::$cacheDiscountHandlers = CCatalogDiscount::getDiscountHandlers($arDiscountIDs);
             } else {
                 $needDiscountHandlers = array();
                 foreach ($arDiscountIDs as &$discountID) {
                     if (!isset(self::$cacheDiscountHandlers[$discountID])) {
                         $needDiscountHandlers[] = $discountID;
                     }
                 }
                 unset($discountID);
                 if (!empty($needDiscountHandlers)) {
                     $discountHandlersList = CCatalogDiscount::getDiscountHandlers($needDiscountHandlers);
                     if (!empty($discountHandlersList)) {
                         foreach ($discountHandlersList as $discountID => $discountHandlers) {
                             self::$cacheDiscountHandlers[$discountID] = $discountHandlers;
                         }
                         unset($discountHandlers, $discountID);
                     }
                     unset($discountHandlersList);
                 }
                 unset($needDiscountHandlers);
             }
             $strCacheKey = 'D' . implode('_', $arDiscountIDs) . '-' . 'S' . $siteID . '-R' . $strRenewal;
             if (!empty($arDiscountCoupons)) {
                 $strCacheKey .= '-C' . implode('|', $arDiscountCoupons);
             }
             $strCacheKey = md5($strCacheKey);
             if (!isset(self::$arCacheDiscountResult[$strCacheKey])) {
                 $arDiscountList = array();
                 $arSelect = array('ID', 'TYPE', 'SITE_ID', 'ACTIVE', 'ACTIVE_FROM', 'ACTIVE_TO', 'RENEWAL', 'NAME', 'SORT', 'MAX_DISCOUNT', 'VALUE_TYPE', 'VALUE', 'CURRENCY', 'PRIORITY', 'LAST_DISCOUNT', 'COUPON', 'COUPON_ONE_TIME', 'COUPON_ACTIVE', 'UNPACK', 'CONDITIONS');
                 $strDate = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")));
                 $discountRows = array_chunk($arDiscountIDs, 500);
                 foreach ($discountRows as &$row) {
                     $arFilter = array('@ID' => $row, 'SITE_ID' => $siteID, 'TYPE' => self::ENTITY_ID, 'RENEWAL' => $strRenewal, '+<=ACTIVE_FROM' => $strDate, '+>=ACTIVE_TO' => $strDate);
                     if (is_array($arDiscountCoupons)) {
                         $arFilter['+COUPON'] = $arDiscountCoupons;
                     }
                     CTimeZone::Disable();
                     $rsPriceDiscounts = CCatalogDiscount::GetList(array(), $arFilter, false, false, $arSelect);
                     CTimeZone::Enable();
                     while ($arPriceDiscount = $rsPriceDiscounts->Fetch()) {
                         $arPriceDiscount['HANDLERS'] = array();
                         $arPriceDiscount['MODULE_ID'] = 'catalog';
                         $arDiscountList[] = $arPriceDiscount;
                     }
                 }
                 unset($row, $discountRows);
                 self::$arCacheDiscountResult[$strCacheKey] = $arDiscountList;
             } else {
                 $arDiscountList = self::$arCacheDiscountResult[$strCacheKey];
             }
             if (!empty($arDiscountList)) {
                 $discountApply = array();
                 foreach ($arDiscountList as &$arPriceDiscount) {
                     if (!isset($discountApply[$arPriceDiscount['ID']]) && $arPriceDiscount['COUPON_ACTIVE'] != 'N') {
                         if (!$boolGenerate) {
                             if (!isset(self::$arCacheProduct[$intProductID])) {
                                 $arProduct = array('ID' => $intProductID, 'IBLOCK_ID' => $intIBlockID);
                                 if (!self::__GenerateFields($arProduct)) {
                                     return false;
                                 }
                                 if ($boolSKU) {
                                     if (!self::__GenerateParent($arProduct, $arSKUExt)) {
                                         $boolSKU = false;
                                     }
                                 }
                                 $boolGenerate = true;
                                 self::$arCacheProduct[$intProductID] = $arProduct;
                             } else {
                                 $boolGenerate = true;
                                 $arProduct = self::$arCacheProduct[$intProductID];
                             }
                         }
                         $discountApply[$arPriceDiscount['ID']] = true;
                         $applyFlag = true;
                         if (isset(self::$cacheDiscountHandlers[$arPriceDiscount['ID']])) {
                             $arPriceDiscount['HANDLERS'] = self::$cacheDiscountHandlers[$arPriceDiscount['ID']];
                             $moduleList = self::$cacheDiscountHandlers[$arPriceDiscount['ID']]['MODULES'];
                             if (!empty($moduleList)) {
                                 foreach ($moduleList as &$moduleID) {
                                     if (!isset(self::$usedModules[$moduleID])) {
                                         self::$usedModules[$moduleID] = Loader::includeModule($moduleID);
                                     }
                                     if (!self::$usedModules[$moduleID]) {
                                         $applyFlag = false;
                                         break;
                                     }
                                 }
                                 unset($moduleID);
                             }
                             unset($moduleList);
                         }
                         if ($applyFlag && CCatalogDiscount::__Unpack($arProduct, $arPriceDiscount['UNPACK'])) {
                             $arResult[] = $arPriceDiscount;
                             $arResultID[] = $arPriceDiscount['ID'];
                         }
                     }
                 }
                 if (isset($arPriceDiscount)) {
                     unset($arPriceDiscount);
                 }
                 unset($discountApply);
             }
         }
         if (!$boolGetIDS) {
             $arDiscSave = CCatalogDiscountSave::GetDiscount(array('USER_ID' => 0, 'USER_GROUPS' => $arUserGroups, 'SITE_ID' => $siteID));
             if (!empty($arDiscSave)) {
                 $arResult = !empty($arResult) ? array_merge($arResult, $arDiscSave) : $arDiscSave;
             }
         } else {
             $arResult = $arResultID;
         }
     }
     if ($eventOnResultExists === true || $eventOnResultExists === null) {
         foreach (GetModuleEvents("catalog", "OnGetDiscountResult", true) as $arEvent) {
             $eventOnResultExists = true;
             ExecuteModuleEventEx($arEvent, array(&$arResult));
         }
         if ($eventOnResultExists === null) {
             $eventOnResultExists = false;
         }
     }
     return $arResult;
 }
Ejemplo n.º 4
0
 public static function DoProcessOrder(&$arOrder, $arOptions, &$arErrors)
 {
     if (empty($arOrder['BASKET_ITEMS']) || !is_array($arOrder['BASKET_ITEMS'])) {
         return;
     }
     $isOrderConverted = \Bitrix\Main\Config\Option::get("main", "~sale_converted_15", 'N');
     $oldDelivery = '';
     $checkIds = true;
     $arIDS = array();
     if ($isOrderConverted == 'Y') {
         if (isset($arOrder['DELIVERY_ID']) && $arOrder['DELIVERY_ID'] != '') {
             $oldDelivery = $arOrder['DELIVERY_ID'];
             $arOrder['DELIVERY_ID'] = \CSaleDelivery::getIdByCode($arOrder['DELIVERY_ID']);
         }
         $adminSection = defined('ADMIN_SECTION') && ADMIN_SECTION === true;
         if (!$adminSection) {
             $mode = Sale\Compatible\DiscountCompatibility::MODE_MANAGER;
             $modeParams = array();
             if (isset($arOrder['CURRENCY'])) {
                 $modeParams['CURRENCY'] = $arOrder['CURRENCY'];
             }
             if (isset($arOrder['SITE_ID'])) {
                 $modeParams['SITE_ID'] = $arOrder['SITE_ID'];
                 if (!isset($modeParams['CURRENCY'])) {
                     $modeParams['CURRENCY'] = Sale\Internals\SiteCurrencyTable::getSiteCurrency($modeParams['SITE_ID']);
                 }
             }
         } else {
             $mode = Sale\Compatible\DiscountCompatibility::MODE_CLIENT;
             $modeParams = array('SITE_ID' => SITE_ID, 'CURRENCY' => Sale\Internals\SiteCurrencyTable::getSiteCurrency(SITE_ID));
         }
         unset($adminSection);
         if (!empty($modeParams)) {
             Sale\Discount\Actions::setUseMode(Sale\Discount\Actions::MODE_CALCULATE, array('USE_BASE_PRICE' => \Bitrix\Main\Config\Option::get('sale', 'get_discount_percent_from_base_price'), 'SITE_ID' => $modeParams['SITE_ID'], 'CURRENCY' => $modeParams['CURRENCY']));
         }
         if (!Sale\Compatible\DiscountCompatibility::isInited()) {
             if (!empty($modeParams)) {
                 Sale\Compatible\DiscountCompatibility::init($mode, $modeParams);
             }
         }
         unset($modeParams, $mode);
         Sale\Compatible\DiscountCompatibility::clearDiscountResult();
         Sale\Compatible\DiscountCompatibility::fillBasketData($arOrder['BASKET_ITEMS']);
         Sale\Compatible\DiscountCompatibility::calculateBasketDiscounts($arOrder['BASKET_ITEMS']);
         Sale\Compatible\DiscountCompatibility::setApplyMode($arOrder['BASKET_ITEMS']);
         $applyMode = Sale\Discount::getApplyMode();
         if ($applyMode == Sale\Discount::APPLY_MODE_FULL_LAST || $applyMode == Sale\Discount::APPLY_MODE_FULL_DISABLE) {
             foreach ($arOrder['BASKET_ITEMS'] as &$basketItem) {
                 if (isset($basketItem['LAST_DISCOUNT']) && $basketItem['LAST_DISCOUNT'] == 'Y') {
                     $checkIds = false;
                     break;
                 }
             }
             unset($basketItem);
         }
     }
     if ($checkIds) {
         $groupDiscountIterator = Sale\Internals\DiscountGroupTable::getList(array('select' => array('DISCOUNT_ID'), 'filter' => array('@GROUP_ID' => CUser::GetUserGroup($arOrder['USER_ID']), '=ACTIVE' => 'Y')));
         while ($groupDiscount = $groupDiscountIterator->fetch()) {
             $groupDiscount['DISCOUNT_ID'] = (int) $groupDiscount['DISCOUNT_ID'];
             if ($groupDiscount['DISCOUNT_ID'] > 0) {
                 $arIDS[$groupDiscount['DISCOUNT_ID']] = true;
             }
         }
     }
     if (!empty($arIDS)) {
         $arIDS = array_keys($arIDS);
         $couponList = Sale\DiscountCouponsManager::getForApply(array('MODULE_ID' => 'sale', 'DISCOUNT_ID' => $arIDS), array(), true);
         //TODO: fix this condition
         $useProps = true;
         $iblockPropList = array();
         $entityList = Sale\Internals\DiscountEntitiesTable::getByDiscount($arIDS, array('=MODULE_ID' => 'catalog', '=ENTITY' => 'ELEMENT_PROPERTY'));
         if (empty($entityList)) {
             $useProps = false;
         } else {
             if (empty($entityList['catalog']['ELEMENT_PROPERTY'])) {
                 $useProps = false;
             } else {
                 foreach ($entityList['catalog']['ELEMENT_PROPERTY'] as $entity) {
                     $entityField = explode(':', $entity['FIELD_TABLE']);
                     if (isset($entityField[1])) {
                         $propId = (int) $entityField[1];
                         if ($propId > 0) {
                             $iblockPropList[$propId] = $propId;
                         }
                         unset($propId);
                     }
                     unset($entityField);
                 }
                 unset($entity);
                 if (empty($iblockPropList)) {
                     $useProps = false;
                 }
             }
         }
         $arExtend = array('catalog' => array('fields' => true, 'props' => $useProps));
         if ($useProps) {
             $arExtend['iblock']['props'] = $iblockPropList;
         }
         unset($iblockPropList, $useProps);
         foreach (GetModuleEvents('sale', 'OnExtendBasketItems', true) as $arEvent) {
             ExecuteModuleEventEx($arEvent, array(&$arOrder['BASKET_ITEMS'], $arExtend));
         }
         foreach ($arOrder['BASKET_ITEMS'] as &$arOneItem) {
             if (array_key_exists('PRODUCT_PROVIDER_CLASS', $arOneItem) && empty($arOneItem['PRODUCT_PROVIDER_CLASS']) && array_key_exists('CALLBACK_FUNC', $arOneItem) && empty($arOneItem['CALLBACK_FUNC']) && (!isset($arOneItem['CUSTOM_PRICE']) || $arOneItem['CUSTOM_PRICE'] != 'Y')) {
                 if (isset($arOneItem['DISCOUNT_PRICE'])) {
                     $arOneItem['PRICE'] += $arOneItem['DISCOUNT_PRICE'];
                     $arOneItem['DISCOUNT_PRICE'] = 0;
                     $arOneItem['BASE_PRICE'] = $arOneItem['PRICE'];
                 }
             }
         }
         if (isset($arOneItem)) {
             unset($arOneItem);
         }
         if (empty(self::$cacheDiscountHandlers)) {
             self::$cacheDiscountHandlers = CSaleDiscount::getDiscountHandlers($arIDS);
         } else {
             $needDiscountHandlers = array();
             foreach ($arIDS as &$discountID) {
                 if (!isset(self::$cacheDiscountHandlers[$discountID])) {
                     $needDiscountHandlers[] = $discountID;
                 }
             }
             unset($discountID);
             if (!empty($needDiscountHandlers)) {
                 $discountHandlersList = CSaleDiscount::getDiscountHandlers($needDiscountHandlers);
                 if (!empty($discountHandlersList)) {
                     foreach ($discountHandlersList as $discountID => $discountHandlers) {
                         self::$cacheDiscountHandlers[$discountID] = $discountHandlers;
                     }
                     unset($discountHandlers, $discountID);
                 }
                 unset($discountHandlersList);
             }
             unset($needDiscountHandlers);
         }
         $currentDatetime = new Main\Type\DateTime();
         $discountSelect = array('ID', 'PRIORITY', 'SORT', 'LAST_DISCOUNT', 'UNPACK', 'APPLICATION', 'USE_COUPONS', 'EXECUTE_MODULE', 'NAME', 'CONDITIONS_LIST', 'ACTIONS_LIST');
         $discountOrder = array('PRIORITY' => 'DESC', 'SORT' => 'ASC', 'ID' => 'ASC');
         $discountFilter = array('@ID' => $arIDS, '=LID' => $arOrder['SITE_ID'], array('LOGIC' => 'OR', 'ACTIVE_FROM' => '', '<=ACTIVE_FROM' => $currentDatetime), array('LOGIC' => 'OR', 'ACTIVE_TO' => '', '>=ACTIVE_TO' => $currentDatetime));
         if (empty($couponList)) {
             $discountFilter['=USE_COUPONS'] = 'N';
         } else {
             $discountFilter[] = array('LOGIC' => 'OR', '=USE_COUPONS' => 'N', array('=USE_COUPONS' => 'Y', '=COUPON.COUPON' => array_keys($couponList)));
             $discountSelect['DISCOUNT_COUPON'] = 'COUPON.COUPON';
         }
         $discountIterator = Sale\Internals\DiscountTable::getList(array('select' => $discountSelect, 'filter' => $discountFilter, 'order' => $discountOrder));
         $discountApply = array();
         $resultDiscountFullList = array();
         $resultDiscountList = array();
         $resultDiscountKeys = array();
         $resultDiscountIndex = 0;
         while ($discount = $discountIterator->fetch()) {
             $discount['ID'] = (int) $discount['ID'];
             if (isset($discountApply[$discount['ID']])) {
                 continue;
             }
             $discount['MODULE'] = 'sale';
             $discount['MODULE_ID'] = 'sale';
             if ($discount['USE_COUPONS'] == 'Y') {
                 $discount['COUPON'] = $couponList[$discount['DISCOUNT_COUPON']];
             }
             $discountApply[$discount['ID']] = true;
             $applyFlag = true;
             if (isset(self::$cacheDiscountHandlers[$discount['ID']])) {
                 $moduleList = self::$cacheDiscountHandlers[$discount['ID']]['MODULES'];
                 if (!empty($moduleList)) {
                     foreach ($moduleList as &$moduleID) {
                         if (!isset(self::$usedModules[$moduleID])) {
                             self::$usedModules[$moduleID] = Loader::includeModule($moduleID);
                         }
                         if (!self::$usedModules[$moduleID]) {
                             $applyFlag = false;
                             break;
                         }
                     }
                     unset($moduleID);
                     if ($applyFlag) {
                         $discount['MODULES'] = $moduleList;
                     }
                 }
                 unset($moduleList);
             }
             if ($isOrderConverted == 'Y') {
                 Sale\Compatible\DiscountCompatibility::setOrderData($arOrder);
             }
             if ($applyFlag && self::__Unpack($arOrder, $discount['UNPACK'])) {
                 $oldOrder = $arOrder;
                 if ($isOrderConverted == 'Y') {
                     Sale\Discount\Actions::clearAction();
                 }
                 self::__ApplyActions($arOrder, $discount['APPLICATION']);
                 if ($isOrderConverted == 'Y') {
                     $resultDiscountFullList[] = $discount;
                     if (Sale\Compatible\DiscountCompatibility::calculateSaleDiscount($arOrder, $discount)) {
                         $resultDiscountList[$resultDiscountIndex] = array('MODULE_ID' => $discount['MODULE_ID'], 'ID' => $discount['ID'], 'NAME' => $discount['NAME'], 'PRIORITY' => $discount['PRIORITY'], 'SORT' => $discount['SORT'], 'LAST_DISCOUNT' => $discount['LAST_DISCOUNT'], 'CONDITIONS' => serialize($discount['CONDITIONS_LIST']), 'UNPACK' => $discount['UNPACK'], 'ACTIONS' => serialize($discount['ACTIONS_LIST']), 'APPLICATION' => $discount['APPLICATION'], 'RESULT' => self::getDiscountResult($oldOrder, $arOrder, false), 'HANDLERS' => self::$cacheDiscountHandlers[$discount['ID']], 'USE_COUPONS' => $discount['USE_COUPONS'], 'COUPON' => $discount['USE_COUPONS'] == 'Y' ? $couponList[$discount['DISCOUNT_COUPON']] : false);
                         $resultDiscountKeys[$discount['ID']] = $resultDiscountIndex;
                         $resultDiscountIndex++;
                         if ($discount['LAST_DISCOUNT'] == 'Y') {
                             break;
                         }
                     }
                     Sale\Discount\Actions::clearAction();
                 } else {
                     $discountResult = self::getDiscountResult($oldOrder, $arOrder, false);
                     if (!empty($discountResult['DELIVERY']) || !empty($discountResult['BASKET'])) {
                         if ($discount['USE_COUPONS'] == 'Y' && !empty($discount['DISCOUNT_COUPON'])) {
                             if ($couponList[$discount['DISCOUNT_COUPON']]['TYPE'] == Sale\Internals\DiscountCouponTable::TYPE_BASKET_ROW) {
                                 self::changeDiscountResult($oldOrder, $arOrder, $discountResult);
                             }
                             $couponApply = Sale\DiscountCouponsManager::setApply($discount['DISCOUNT_COUPON'], $discountResult);
                             unset($couponApply);
                         }
                         $resultDiscountList[$resultDiscountIndex] = array('MODULE_ID' => $discount['MODULE_ID'], 'ID' => $discount['ID'], 'NAME' => $discount['NAME'], 'PRIORITY' => $discount['PRIORITY'], 'SORT' => $discount['SORT'], 'LAST_DISCOUNT' => $discount['LAST_DISCOUNT'], 'CONDITIONS' => serialize($discount['CONDITIONS_LIST']), 'UNPACK' => $discount['UNPACK'], 'ACTIONS' => serialize($discount['ACTIONS_LIST']), 'APPLICATION' => $discount['APPLICATION'], 'RESULT' => $discountResult, 'HANDLERS' => self::$cacheDiscountHandlers[$discount['ID']], 'USE_COUPONS' => $discount['USE_COUPONS'], 'COUPON' => $discount['USE_COUPONS'] == 'Y' ? $couponList[$discount['DISCOUNT_COUPON']] : false);
                         $resultDiscountKeys[$discount['ID']] = $resultDiscountIndex;
                         $resultDiscountIndex++;
                         if ($discount['LAST_DISCOUNT'] == 'Y') {
                             break;
                         }
                     }
                     unset($discountResult);
                 }
             }
         }
         unset($discount, $discountIterator);
         $arOrder["ORDER_PRICE"] = 0;
         $arOrder["ORDER_WEIGHT"] = 0;
         $arOrder["USE_VAT"] = false;
         $arOrder["VAT_RATE"] = 0;
         $arOrder["VAT_SUM"] = 0;
         $arOrder["DISCOUNT_PRICE"] = 0.0;
         $arOrder["DISCOUNT_VALUE"] = $arOrder["DISCOUNT_PRICE"];
         $arOrder["PRICE_DELIVERY"] = roundEx($arOrder["PRICE_DELIVERY"], SALE_VALUE_PRECISION);
         $arOrder["DELIVERY_PRICE"] = $arOrder["PRICE_DELIVERY"];
         foreach ($arOrder['BASKET_ITEMS'] as &$arShoppingCartItem) {
             if (isset($arShoppingCartItem['CATALOG'])) {
                 unset($arShoppingCartItem['CATALOG']);
             }
             if (!CSaleBasketHelper::isSetItem($arShoppingCartItem)) {
                 $customPrice = isset($arShoppingCartItem['CUSTOM_PRICE']) && ($arShoppingCartItem['CUSTOM_PRICE'] = 'Y');
                 if (!$customPrice) {
                     $arShoppingCartItem['DISCOUNT_PRICE'] = roundEx($arShoppingCartItem['DISCOUNT_PRICE'], SALE_VALUE_PRECISION);
                     if ($arShoppingCartItem['DISCOUNT_PRICE'] > 0) {
                         $arShoppingCartItem['PRICE'] = $arShoppingCartItem['BASE_PRICE'] - $arShoppingCartItem['DISCOUNT_PRICE'];
                     } else {
                         $arShoppingCartItem['PRICE'] = roundEx($arShoppingCartItem['PRICE'], SALE_VALUE_PRECISION);
                     }
                 } else {
                     $arShoppingCartItem['DISCOUNT_PRICE'] = 0;
                 }
                 if (isset($arShoppingCartItem['VAT_RATE'])) {
                     $vatRate = (double) $arShoppingCartItem['VAT_RATE'];
                     if ($vatRate > 0) {
                         $arShoppingCartItem['VAT_VALUE'] = $arShoppingCartItem['PRICE'] / ($vatRate + 1) * $vatRate;
                     }
                     unset($vatRate);
                 }
                 $arOrder["ORDER_PRICE"] += $arShoppingCartItem["PRICE"] * $arShoppingCartItem["QUANTITY"];
                 $arOrder["ORDER_WEIGHT"] += $arShoppingCartItem["WEIGHT"] * $arShoppingCartItem["QUANTITY"];
                 $arShoppingCartItem["PRICE_FORMATED"] = CCurrencyLang::CurrencyFormat($arShoppingCartItem["PRICE"], $arShoppingCartItem["CURRENCY"], true);
                 $arShoppingCartItem["DISCOUNT_PRICE_PERCENT"] = 0;
                 if ($arShoppingCartItem["DISCOUNT_PRICE"] + $arShoppingCartItem["PRICE"] > 0) {
                     $arShoppingCartItem["DISCOUNT_PRICE_PERCENT"] = $arShoppingCartItem["DISCOUNT_PRICE"] * 100 / ($arShoppingCartItem["DISCOUNT_PRICE"] + $arShoppingCartItem["PRICE"]);
                 }
                 $arShoppingCartItem["DISCOUNT_PRICE_PERCENT_FORMATED"] = roundEx($arShoppingCartItem["DISCOUNT_PRICE_PERCENT"], SALE_VALUE_PRECISION) . "%";
                 if ($arShoppingCartItem["VAT_RATE"] > 0) {
                     $arOrder["USE_VAT"] = true;
                     if ($arShoppingCartItem["VAT_RATE"] > $arOrder["VAT_RATE"]) {
                         $arOrder["VAT_RATE"] = $arShoppingCartItem["VAT_RATE"];
                     }
                     $arOrder["VAT_SUM"] += $arShoppingCartItem["VAT_VALUE"] * $arShoppingCartItem["QUANTITY"];
                 }
             }
         }
         unset($arShoppingCartItem);
         $arOrder['DISCOUNT_LIST'] = $resultDiscountList;
         $arOrder['FULL_DISCOUNT_LIST'] = $resultDiscountFullList;
         if ($isOrderConverted == 'Y') {
             Sale\Compatible\DiscountCompatibility::setOldDiscountResult($resultDiscountList);
         }
     }
     if ($isOrderConverted == 'Y' && $oldDelivery != '') {
         $arOrder['DELIVERY_ID'] = $oldDelivery;
     }
     $arOrder["ORDER_PRICE"] = roundEx($arOrder["ORDER_PRICE"], SALE_VALUE_PRECISION);
 }
Ejemplo n.º 5
0
 /**
  * Load sale discount from database
  *
  * @return void
  * @throws Main\ArgumentException
  */
 protected function loadDiscountList()
 {
     if (empty($this->discountIds)) {
         $this->discountIds = null;
         return;
     }
     $this->getDiscountModules();
     $couponList = DiscountCouponsManager::getForApply(array('MODULE' => 'sale', 'DISCOUNT_ID' => $this->discountIds), array(), true);
     $this->saleDiscountCacheKey = md5('D' . implode('_', $this->discountIds));
     if (!empty($couponList)) {
         $this->saleDiscountCacheKey .= '-C' . implode('_', array_keys($couponList));
     }
     if (!isset($this->saleDiscountCache[$this->saleDiscountCacheKey])) {
         $currentList = array();
         $discountApply = array();
         $currentDatetime = new Main\Type\DateTime();
         $discountSelect = array('ID', 'PRIORITY', 'SORT', 'LAST_DISCOUNT', 'UNPACK', 'APPLICATION', 'USE_COUPONS', 'EXECUTE_MODULE', 'NAME', 'CONDITIONS_LIST', 'ACTIONS_LIST');
         $discountFilter = array('@ID' => $this->discountIds, '=LID' => $this->orderData['SITE_ID'], '@EXECUTE_MODULE' => array('sale', 'all'), array('LOGIC' => 'OR', 'ACTIVE_FROM' => '', '<=ACTIVE_FROM' => $currentDatetime), array('LOGIC' => 'OR', 'ACTIVE_TO' => '', '>=ACTIVE_TO' => $currentDatetime));
         unset($currentDatetime);
         if (empty($couponList)) {
             $discountFilter['=USE_COUPONS'] = 'N';
         } else {
             $discountFilter[] = array('LOGIC' => 'OR', '=USE_COUPONS' => 'N', array('=USE_COUPONS' => 'Y', '@COUPON.COUPON' => array_keys($couponList)));
             $discountSelect['DISCOUNT_COUPON'] = 'COUPON.COUPON';
         }
         $discountIterator = Internals\DiscountTable::getList(array('select' => $discountSelect, 'filter' => $discountFilter, 'order' => array('PRIORITY' => 'DESC', 'SORT' => 'ASC', 'ID' => 'ASC')));
         unset($discountSelect, $discountFilter);
         while ($discount = $discountIterator->fetch()) {
             $discount['ID'] = (int) $discount['ID'];
             if (isset($discountApply[$discount['ID']])) {
                 continue;
             }
             $discountApply[$discount['ID']] = true;
             if (!$this->loadDiscountModules('sale' . $discount['ID'])) {
                 continue;
             }
             if ($discount['USE_COUPONS'] == 'Y') {
                 $discount['COUPON'] = $couponList[$discount['DISCOUNT_COUPON']];
             }
             $discount['CONDITIONS'] = $discount['CONDITIONS_LIST'];
             $discount['ACTIONS'] = $discount['ACTIONS_LIST'];
             $discount['MODULE_ID'] = 'sale';
             if (isset($this->cacheDiscountModules['sale' . $discount['ID']])) {
                 $discount['MODULES'] = $this->cacheDiscountModules['sale' . $discount['ID']];
             }
             unset($discount['ACTIONS_LIST'], $discount['CONDITIONS_LIST']);
             $currentList[$discount['ID']] = $discount;
         }
         unset($discount, $discountIterator, $discountApply);
         $this->saleDiscountCache[$this->saleDiscountCacheKey] = $currentList;
         unset($currentList);
     }
     unset($couponList);
 }
Ejemplo n.º 6
0
 /**
  * Calculate discount by new order.
  *
  * @return Result
  */
 protected function calculateFull()
 {
     $result = new Result();
     $this->discountIds = array();
     if (!$this->isMixedBasket()) {
         $this->fillEmptyDiscountResult();
     } else {
         $this->discountResult['ORDER'] = array();
     }
     $order = $this->getOrder();
     $basket = $order->getBasket();
     /** @var BasketItem $basketItem */
     foreach ($basket as $basketItem) {
         $code = $basketItem->getBasketCode();
         if ($this->isCustomPriceByCode($code)) {
             if (array_key_exists($code, $this->basketDiscountList)) {
                 unset($this->basketDiscountList[$code]);
             }
         } else {
             if (!isset($this->basketDiscountList[$code])) {
                 $this->basketDiscountList[$code] = $basketItem->getField('DISCOUNT_LIST');
                 if ($this->basketDiscountList[$code] === null) {
                     unset($this->basketDiscountList[$code]);
                 }
             }
         }
     }
     unset($code, $basketItem, $basket);
     $this->resetBasketPrices();
     if ($this->isMixedBasket()) {
         DiscountCouponsManager::clearApply(false);
         $basketDiscountResult = $this->calculateMixedBasketDiscount();
     } else {
         DiscountCouponsManager::clearApply();
         $basketDiscountResult = $this->calculateFullBasketDiscount();
     }
     if (!$basketDiscountResult->isSuccess()) {
         $result->addErrors($basketDiscountResult->getErrors());
         unset($basketDiscountResult);
         return $result;
     }
     unset($basketDiscountResult);
     $this->roundBasketPrices();
     $codeList = array_keys($this->orderData['BASKET_ITEMS']);
     switch (self::getApplyMode()) {
         case self::APPLY_MODE_DISABLE:
             foreach ($codeList as &$code) {
                 if (isset($this->basketDiscountList[$code]) && !empty($this->basketDiscountList[$code])) {
                     $this->orderData['BASKET_ITEMS'][$code]['LAST_DISCOUNT'] = 'Y';
                 }
             }
             unset($code);
             break;
         case self::APPLY_MODE_LAST:
             foreach ($codeList as &$code) {
                 if (!isset($this->basketDiscountList[$code]) || empty($this->basketDiscountList[$code])) {
                     continue;
                 }
                 $lastDiscount = end($this->basketDiscountList[$code]);
                 if (!empty($lastDiscount['LAST_DISCOUNT']) && $lastDiscount['LAST_DISCOUNT'] == 'Y') {
                     $this->orderData['BASKET_ITEMS'][$code]['LAST_DISCOUNT'] = 'Y';
                 }
             }
             unset($code);
             break;
         case self::APPLY_MODE_ADD:
             break;
     }
     unset($codeList);
     $userGroups = \CUser::getUserGroup($this->orderData['USER_ID']);
     Main\Type\Collection::normalizeArrayValuesByInt($userGroups);
     $cacheKey = md5('U' . implode('_', $userGroups));
     if (!isset($this->discountByUserCache[$cacheKey])) {
         $discountCache = array();
         $groupDiscountIterator = Internals\DiscountGroupTable::getList(array('select' => array('DISCOUNT_ID'), 'filter' => array('@GROUP_ID' => $userGroups, '=ACTIVE' => 'Y')));
         while ($groupDiscount = $groupDiscountIterator->fetch()) {
             $groupDiscount['DISCOUNT_ID'] = (int) $groupDiscount['DISCOUNT_ID'];
             if ($groupDiscount['DISCOUNT_ID'] > 0) {
                 $discountCache[$groupDiscount['DISCOUNT_ID']] = $groupDiscount['DISCOUNT_ID'];
             }
         }
         unset($groupDiscount, $groupDiscountIterator);
         if (!empty($discountCache)) {
             Main\Type\Collection::normalizeArrayValuesByInt($discountCache);
             $this->discountByUserCache[$cacheKey] = $discountCache;
         }
         unset($discountCache);
     }
     if (!empty($this->discountByUserCache[$cacheKey])) {
         $this->discountIds = $this->discountByUserCache[$cacheKey];
     }
     if (empty($this->discountIds)) {
         $this->discountIds = null;
     } else {
         $this->getDiscountModules();
         $couponList = DiscountCouponsManager::getForApply(array('MODULE' => 'sale', 'DISCOUNT_ID' => $this->discountIds), array(), true);
         $cacheKey = md5('D' . implode('_', $this->discountIds));
         if (!empty($couponList)) {
             $cacheKey .= '-C' . implode('_', array_keys($couponList));
         }
         $currentList = array();
         if (!isset($this->saleDiscountCache[$cacheKey])) {
             $discountApply = array();
             $currentDatetime = new Main\Type\DateTime();
             $discountSelect = array('ID', 'PRIORITY', 'SORT', 'LAST_DISCOUNT', 'UNPACK', 'APPLICATION', 'USE_COUPONS', 'EXECUTE_MODULE', 'NAME', 'CONDITIONS_LIST', 'ACTIONS_LIST');
             $discountOrder = array('PRIORITY' => 'DESC', 'SORT' => 'ASC', 'ID' => 'ASC');
             $discountFilter = array('@ID' => $this->discountIds, '=LID' => $this->orderData['SITE_ID'], '@EXECUTE_MODULE' => array('sale', 'all'), array('LOGIC' => 'OR', 'ACTIVE_FROM' => '', '<=ACTIVE_FROM' => $currentDatetime), array('LOGIC' => 'OR', 'ACTIVE_TO' => '', '>=ACTIVE_TO' => $currentDatetime));
             unset($currentDatetime);
             if (empty($couponList)) {
                 $discountFilter['=USE_COUPONS'] = 'N';
             } else {
                 $discountFilter[] = array('LOGIC' => 'OR', '=USE_COUPONS' => 'N', array('=USE_COUPONS' => 'Y', '@COUPON.COUPON' => array_keys($couponList)));
                 $discountSelect['DISCOUNT_COUPON'] = 'COUPON.COUPON';
             }
             $discountIterator = Internals\DiscountTable::getList(array('select' => $discountSelect, 'filter' => $discountFilter, 'order' => $discountOrder));
             while ($discount = $discountIterator->fetch()) {
                 $discount['ID'] = (int) $discount['ID'];
                 if (isset($discountApply[$discount['ID']])) {
                     continue;
                 }
                 $discountApply[$discount['ID']] = true;
                 if (!$this->loadDiscountModules('sale' . $discount['ID'])) {
                     continue;
                 }
                 if ($discount['USE_COUPONS'] == 'Y') {
                     $discount['COUPON'] = $couponList[$discount['DISCOUNT_COUPON']];
                 }
                 $discount['CONDITIONS'] = $discount['CONDITIONS_LIST'];
                 $discount['ACTIONS'] = $discount['ACTIONS_LIST'];
                 $discount['MODULE_ID'] = 'sale';
                 if (isset($this->cacheDiscountModules['sale' . $discount['ID']])) {
                     $discount['MODULES'] = $this->cacheDiscountModules['sale' . $discount['ID']];
                 }
                 unset($discount['ACTIONS_LIST'], $discount['CONDITIONS_LIST']);
                 $currentList[] = $discount;
             }
             unset($discount, $discountIterator, $discountApply);
             $this->saleDiscountCache[$cacheKey] = $currentList;
         } else {
             $currentList = $this->saleDiscountCache[$cacheKey];
         }
         unset($couponList);
         $this->discountIds = array();
         if (!empty($currentList)) {
             foreach ($currentList as &$discount) {
                 $this->discountIds[] = $discount['ID'];
             }
             unset($discount);
             $this->extendOrderData();
             foreach ($currentList as $indexDiscount => $discount) {
                 $this->fillCurrentStep(array('discount' => $discount));
                 if (!self::checkDiscountConditions()) {
                     continue;
                 }
                 $actionsResult = $this->applySaleDiscount();
                 if (!$actionsResult->isSuccess()) {
                     $result->addErrors($actionsResult->getErrors());
                     unset($actionsResult);
                     return $result;
                 }
                 if ($this->currentStep['stop']) {
                     break;
                 }
             }
             unset($discount, $indexDiscount, $currentList);
         }
         $this->fillEmptyCurrentStep();
     }
     return $result;
 }