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; }
/** * 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); } }
/** * 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; }