public function runOperation()
 {
     $found = false;
     $filter = array('>ID' => $this->lastID, 'ORDER_DISCOUNT_DATA.ID' => null);
     if (!empty($this->filter)) {
         foreach ($this->filter as $filterKey => $filterValue) {
             $filter[$filterKey] = $filterValue;
         }
         unset($filterKey, $filterValue);
     }
     $ordersIterator = Sale\Internals\OrderTable::getList(array('select' => array('ID', 'CURRENCY', 'LID'), 'filter' => $filter, 'order' => array('ID' => 'ASC'), 'limit' => $this->maxOperationCounter));
     while ($order = $ordersIterator->fetch()) {
         $found = true;
         $migrateResult = Sale\OrderDiscountManager::migrateOrderDiscounts($order);
         $this->lastID = $order['ID'];
         $this->allOperationCounter++;
         if (!$migrateResult->isSuccess()) {
             $this->errorCounter++;
             $this->errors[] = Loc::getMessage('SALE_BASKET_DISCOUNT_ORDER_ERROR_REPORT', array('#URL#' => str_replace('#ID#', $order['ID'], $this->orderViewUrl), '#TITLE#' => $order['ID'], '#ERRORS#' => implode('; ', $migrateResult->getErrorMessages())));
         }
         unset($migrateResult);
         if ($this->maxExecutionTime > 0 && time() - $this->startOperationTime > $this->maxExecutionTime) {
             break;
         }
     }
     unset($order, $ordersIterator);
     if (!$found) {
         $this->finishOperation = true;
     }
 }
 /**
  * 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);
 }
 /**
  * Returns result after one discount in old format.
  *
  * @param array $currentOrder			Current order data.
  * @return array
  */
 protected static function getStepResultOld($currentOrder)
 {
     $publicMode = self::usedByClient();
     $result = array();
     if (isset(self::$previousOrderData['PRICE_DELIVERY']) && isset($currentOrder['PRICE_DELIVERY'])) {
         if (self::$previousOrderData['PRICE_DELIVERY'] != $currentOrder['PRICE_DELIVERY']) {
             $descr = Sale\OrderDiscountManager::createSimpleDescription($currentOrder['PRICE_DELIVERY'], self::$previousOrderData['PRICE_DELIVERY'], self::$previousOrderData['CURRENCY']);
             $result['DELIVERY'] = array('APPLY' => 'Y', 'DELIVERY_ID' => isset($currentOrder['DELIVERY_ID']) ? $currentOrder['DELIVERY_ID'] : false, 'SHIPMENT_CODE' => isset($order['SHIPMENT_CODE']) ? $order['SHIPMENT_CODE'] : false, 'DESCR' => Sale\OrderDiscountManager::formatArrayDescription($descr), 'DESCR_DATA' => $descr);
             unset($descr);
             if (is_array($result['DELIVERY']['DESCR'])) {
                 $result['DELIVERY']['DESCR'] = implode(', ', $result['DELIVERY']['DESCR']);
             }
         }
     }
     if (!empty(self::$previousOrderData['BASKET_ITEMS']) && !empty($currentOrder['BASKET_ITEMS'])) {
         foreach (self::$previousOrderData['BASKET_ITEMS'] as $basketCode => $item) {
             if (!isset($currentOrder['BASKET_ITEMS'][$basketCode])) {
                 continue;
             }
             $code = $publicMode ? $currentOrder['BASKET_ITEMS'][$basketCode]['ID'] : $basketCode;
             if ($item['PRICE'] != $currentOrder['BASKET_ITEMS'][$basketCode]['PRICE']) {
                 if (!isset($result['BASKET'])) {
                     $result['BASKET'] = array();
                 }
                 $descr = Sale\OrderDiscountManager::createSimpleDescription($currentOrder['BASKET_ITEMS'][$basketCode]['PRICE'], $item['PRICE'], self::$previousOrderData['CURRENCY']);
                 $result['BASKET'][$code] = array('APPLY' => 'Y', 'DESCR' => Sale\OrderDiscountManager::formatArrayDescription($descr), 'DESCR_DATA' => $descr, 'MODULE' => $currentOrder['BASKET_ITEMS'][$basketCode]['MODULE'], 'PRODUCT_ID' => $currentOrder['BASKET_ITEMS'][$basketCode]['PRODUCT_ID'], 'BASKET_ID' => $code);
                 unset($descr);
                 if (is_array($result['BASKET'][$basketCode]['DESCR'])) {
                     $result['BASKET'][$basketCode]['DESCR'] = implode(', ', $result['BASKET'][$basketCode]['DESCR']);
                 }
             }
         }
     }
     return $result;
 }
Beispiel #4
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);
     }
 }
Beispiel #5
0
 /**
  * Return formatted discount description.
  *
  * @param array $descr				Description.
  * @return array
  */
 protected static function formatDescription($descr)
 {
     $result = array();
     if (empty($descr) || !is_array($descr)) {
         return $result;
     }
     if (isset($descr['DELIVERY'])) {
         $result['DELIVERY'] = array();
         foreach ($descr['DELIVERY'] as $index => $value) {
             $result['DELIVERY'][$index] = OrderDiscountManager::formatDescription($value);
             if ($result['DELIVERY'][$index] == false) {
                 unset($result['DELIVERY'][$index]);
             }
         }
         unset($value, $index);
         if (!empty($result['DELIVERY'])) {
             $result['DELIVERY'] = implode(', ', $result['DELIVERY']);
         }
     }
     if (isset($descr['BASKET'])) {
         $result['BASKET'] = array();
         foreach ($descr['BASKET'] as $index => $value) {
             $result['BASKET'][$index] = OrderDiscountManager::formatDescription($value);
             if ($result['BASKET'][$index] == false) {
                 unset($result['BASKET'][$index]);
             }
         }
         unset($value, $index);
         if (!empty($result['BASKET'])) {
             $result['BASKET'] = implode(', ', $result['BASKET']);
         }
     }
     return $result;
 }