示例#1
0
 /**
  * Create sale action.
  *
  * @param array &$discount			Discount data.
  * @param array $params				Manager parameters.
  * @return void
  */
 protected static function createSaleAction(&$discount, $params)
 {
     $data = array('TYPE' => $discount['VALUE_TYPE'], 'VALUE' => $discount['VALUE'], 'CURRENCY' => $discount['CURRENCY'], 'USE_BASE_PRICE' => $params['USE_BASE_PRICE']);
     if ($discount['TYPE'] == Catalog\DiscountTable::VALUE_TYPE_PERCENT) {
         $data['MAX_VALUE'] = $discount['MAX_VALUE'];
     }
     $action = '\\Bitrix\\Catalog\\Discount\\DiscountManager::applyDiscount(' . $params['BASKET_ITEM'] . ', ' . var_export($data, true) . ');';
     $discount['APPLICATION'] = 'function (&' . $params['BASKET_ITEM'] . '){' . $action . '};';
     $discount['ACTIONS'] = $data;
     if (Loader::includeModule('sale')) {
         $type = '';
         $descr = array('VALUE_ACTION' => $discount['TYPE'] == Catalog\DiscountTable::TYPE_DISCOUNT_SAVE ? Sale\OrderDiscountManager::DESCR_VALUE_ACTION_ACCUMULATE : Sale\OrderDiscountManager::DESCR_VALUE_ACTION_DISCOUNT, 'VALUE' => $discount['VALUE']);
         switch ($discount['VALUE_TYPE']) {
             case Catalog\DiscountTable::VALUE_TYPE_PERCENT:
                 $type = $discount['MAX_VALUE'] > 0 ? Sale\OrderDiscountManager::DESCR_TYPE_LIMIT_VALUE : Sale\OrderDiscountManager::DESCR_TYPE_VALUE;
                 $descr['VALUE_TYPE'] = Sale\OrderDiscountManager::DESCR_VALUE_TYPE_PERCENT;
                 if ($discount['MAX_VALUE'] > 0) {
                     $descr['LIMIT_TYPE'] = Sale\OrderDiscountManager::DESCR_LIMIT_MAX;
                     $descr['LIMIT_UNIT'] = $discount['CURRENCY'];
                     $descr['LIMIT_VALUE'] = $discount['MAX_VALUE'];
                 }
                 break;
             case Catalog\DiscountTable::VALUE_TYPE_FIX:
                 $type = Sale\OrderDiscountManager::DESCR_TYPE_VALUE;
                 $descr['VALUE_TYPE'] = Sale\OrderDiscountManager::DESCR_VALUE_TYPE_CURRENCY;
                 $descr['VALUE_UNIT'] = $discount['CURRENCY'];
                 break;
             case Catalog\DiscountTable::VALUE_TYPE_SALE:
                 $type = Sale\OrderDiscountManager::DESCR_TYPE_FIXED;
                 $descr['VALUE_UNIT'] = $discount['CURRENCY'];
                 break;
         }
         $descrResult = Sale\OrderDiscountManager::prepareDiscountDescription($type, $descr);
         if ($descrResult->isSuccess()) {
             $discount['ACTIONS_DESCR'] = array('BASKET' => array(0 => $descrResult->getData()));
         }
         unset($descrResult, $descr, $type);
     }
     unset($action, $data);
 }
示例#2
0
 /**
  * Apply discount to basket.
  *
  * @param array &$order			Order data.
  * @param callable $func		Filter function.
  * @param float $value			Discount value.
  * @param string $unit			Value unit.
  * @return void
  */
 public static function ApplyBasketDiscount(&$order, $func, $value, $unit)
 {
     if (empty($order['BASKET_ITEMS']) || !is_array($order['BASKET_ITEMS'])) {
         return;
     }
     $manualMode = self::isManualMode($order);
     if (self::$getPercentFromBasePrice === null) {
         if ($manualMode) {
             self::$getPercentFromBasePrice = isset($order['USE_BASE_PRICE']) && $order['USE_BASE_PRICE'] == 'Y';
         } else {
             self::$getPercentFromBasePrice = (string) Option::get('sale', 'get_discount_percent_from_base_price') == 'Y';
         }
     }
     if ($manualMode) {
         $discountBasket = array_filter($order['BASKET_ITEMS'], 'CSaleDiscountActionApply::filterApplied');
     } else {
         $discountBasket = is_callable($func) ? array_filter($order['BASKET_ITEMS'], $func) : $order['BASKET_ITEMS'];
     }
     if (empty($discountBasket)) {
         return;
     }
     $allBasket = count($order['BASKET_ITEMS']) == count($discountBasket);
     $clearBasket = array_filter($discountBasket, 'CSaleDiscountActionApply::ClearBasket');
     if (empty($clearBasket)) {
         return;
     }
     unset($discountBasket);
     $unit = (string) $unit;
     $value = (double) $value;
     $type = Sale\OrderDiscountManager::DESCR_TYPE_VALUE;
     $discountDescr = array('VALUE' => abs($value), 'VALUE_ACTION' => $value < 0 ? Sale\OrderDiscountManager::DESCR_VALUE_ACTION_DISCOUNT : Sale\OrderDiscountManager::DESCR_VALUE_ACTION_EXTRA);
     switch ($unit) {
         case self::VALUE_TYPE_SUMM:
             $discountDescr['VALUE_TYPE'] = $allBasket ? Sale\OrderDiscountManager::DESCR_VALUE_TYPE_SUMM_BASKET : Sale\OrderDiscountManager::DESCR_VALUE_TYPE_SUMM;
             if (isset($order['CURRENCY'])) {
                 $discountDescr['VALUE_UNIT'] = $order['CURRENCY'];
             }
             break;
         case self::VALUE_TYPE_PERCENT:
             $discountDescr['VALUE_TYPE'] = Sale\OrderDiscountManager::DESCR_VALUE_TYPE_PERCENT;
             break;
         case self::VALUE_TYPE_FIX:
         default:
             $discountDescr['VALUE_TYPE'] = Sale\OrderDiscountManager::DESCR_VALUE_TYPE_CURRENCY;
             if (isset($order['CURRENCY'])) {
                 $discountDescr['VALUE_UNIT'] = $order['CURRENCY'];
             }
             break;
     }
     unset($allBasket);
     if ($unit == self::VALUE_TYPE_SUMM) {
         $dblSumm = 0.0;
         if (self::$getPercentFromBasePrice) {
             foreach ($clearBasket as &$arOneRow) {
                 if (!isset($arOneRow['DISCOUNT_PRICE'])) {
                     $arOneRow['DISCOUNT_PRICE'] = 0;
                 }
                 $dblSumm += (double) (isset($arOneRow['BASE_PRICE']) ? $arOneRow['BASE_PRICE'] : $arOneRow['PRICE'] + $arOneRow['DISCOUNT_PRICE']) * (double) $arOneRow['QUANTITY'];
             }
             unset($arOneRow);
         } else {
             foreach ($clearBasket as &$arOneRow) {
                 $dblSumm += (double) $arOneRow['PRICE'] * (double) $arOneRow['QUANTITY'];
             }
             unset($arOneRow);
         }
         $value = $dblSumm > 0 ? $value * 100 / $dblSumm : 0.0;
         $unit = self::VALUE_TYPE_PERCENT;
     }
     if ($value != 0) {
         if (!$manualMode) {
             $prepareResult = Sale\OrderDiscountManager::prepareDiscountDescription($type, $discountDescr);
             if ($prepareResult->isSuccess()) {
                 if (!isset($order['DISCOUNT_DESCR'])) {
                     $order['DISCOUNT_DESCR'] = array();
                 }
                 if (!isset($order['DISCOUNT_DESCR']['BASKET'])) {
                     $order['DISCOUNT_DESCR']['BASKET'] = array();
                 }
                 $order['DISCOUNT_DESCR']['BASKET'][] = $prepareResult->getData();
             }
             unset($prepareResult);
         }
         $applyResultList = array();
         foreach ($clearBasket as $basketCode => $arOneRow) {
             $calculateValue = $value;
             if ($unit == self::VALUE_TYPE_PERCENT) {
                 if (self::$getPercentFromBasePrice) {
                     if (!isset($arOneRow['DISCOUNT_PRICE'])) {
                         $arOneRow['DISCOUNT_PRICE'] = 0;
                     }
                     $calculateValue = (isset($arOneRow['BASE_PRICE']) ? $arOneRow['BASE_PRICE'] : $arOneRow['PRICE'] + $arOneRow['DISCOUNT_PRICE']) * $value / 100;
                 } else {
                     $calculateValue = $arOneRow['PRICE'] * $value / 100;
                 }
                 $calculateValue = roundEx($calculateValue, SALE_VALUE_PRECISION);
             }
             $dblResult = $arOneRow['PRICE'] + $calculateValue;
             if (abs($dblResult) < self::EPS) {
                 $dblResult = 0;
             }
             if ($dblResult >= 0 && (!$manualMode || isset($arOneRow[self::BASKET_APPLIED_FIELD]))) {
                 $arOneRow['PRICE'] = $dblResult;
                 if (isset($arOneRow['PRICE_DEFAULT'])) {
                     $arOneRow['PRICE_DEFAULT'] = $dblResult;
                 }
                 if (isset($arOneRow['DISCOUNT_PRICE'])) {
                     $arOneRow['DISCOUNT_PRICE'] = (double) $arOneRow['DISCOUNT_PRICE'];
                     $arOneRow['DISCOUNT_PRICE'] -= $calculateValue;
                 } else {
                     $arOneRow['DISCOUNT_PRICE'] = -$calculateValue;
                 }
                 if ($arOneRow['DISCOUNT_PRICE'] < 0) {
                     $arOneRow['DISCOUNT_PRICE'] = 0;
                 }
                 if (isset($arOneRow['VAT_RATE'])) {
                     $dblVatRate = (double) $arOneRow['VAT_RATE'];
                     if ($dblVatRate > 0) {
                         $arOneRow['VAT_VALUE'] = $arOneRow['PRICE'] / ($dblVatRate + 1) * $dblVatRate;
                     }
                 }
                 foreach (self::$resetFields as &$fieldName) {
                     if (isset($arOneRow[$fieldName]) && !is_array($arOneRow[$fieldName])) {
                         $arOneRow['~' . $fieldName] = $arOneRow[$fieldName];
                     }
                 }
                 unset($fieldName);
                 $order['BASKET_ITEMS'][$basketCode] = $arOneRow;
                 $applyResultList[$basketCode] = $discountDescr;
                 $applyResultList[$basketCode]['RESULT_VALUE'] = abs($calculateValue);
                 if (isset($arOneRow['CURRENCY'])) {
                     $applyResultList[$basketCode]['RESULT_UNIT'] = $arOneRow['CURRENCY'];
                 }
             }
         }
         unset($basketCode);
         if (!isset($order['DISCOUNT_RESULT'])) {
             $order['DISCOUNT_RESULT'] = array();
         }
         if (!isset($order['DISCOUNT_RESULT']['BASKET'])) {
             $order['DISCOUNT_RESULT']['BASKET'] = array();
         }
         foreach ($applyResultList as $basketCode => $applyResult) {
             $prepareResult = Sale\OrderDiscountManager::prepareDiscountDescription($type, $applyResult);
             if ($prepareResult->isSuccess()) {
                 if (!isset($order['DISCOUNT_RESULT']['BASKET'][$basketCode])) {
                     $order['DISCOUNT_RESULT']['BASKET'][$basketCode] = array();
                 }
                 $order['DISCOUNT_RESULT']['BASKET'][$basketCode][] = $prepareResult->getData();
             }
             unset($prepareResult);
         }
         unset($basketCode, $applyResult, $applyResultList);
     }
 }