13 const ERROR_ID =
'BX_SALE_ORDER_DISCOUNT_MIGRATOR';
15 private static $catalogIncluded =
null;
16 private static $migrateDiscountsCache = array();
17 private static $migrateCouponsCache = array();
18 private static $catalogDiscountsCache = array();
28 static $useBasePrice =
null;
29 if ($useBasePrice ===
null)
30 $useBasePrice = (string)Main\
Config\Option::get(
'sale',
'get_discount_percent_from_base_price');
35 if (empty($order[
'ID']) || (
int)$order[
'ID'] <= 0)
44 $catalogOrder =
false;
45 $basketData = array();
48 $order[
'ID'] = (int)$order[
'ID'];
49 $basePrices = array();
51 $basketIterator = Sale\Internals\BasketTable::getList(array(
53 'ID',
'DISCOUNT_COUPON',
'DISCOUNT_NAME',
'DISCOUNT_VALUE',
54 'MODULE',
'PRICE',
'DISCOUNT_PRICE',
'CURRENCY',
'SET_PARENT_ID',
'TYPE'
56 'filter' => array(
'=ORDER_ID' => $order[
'ID'])
58 while ($basket = $basketIterator->fetch())
60 $basket[
'ID'] = (int)$basket[
'ID'];
61 $basket[
'MODULE'] = (string)$basket[
'MODULE'];
62 $basket[
'DISCOUNT_COUPON'] = trim((
string)$basket[
'DISCOUNT_COUPON']);
63 $basket[
'DISCOUNT_NAME'] = trim((
string)$basket[
'DISCOUNT_NAME']);
64 $basket[
'SET_PARENT_ID'] = (int)$basket[
'SET_PARENT_ID'];
65 $basket[
'TYPE'] = (int)$basket[
'TYPE'];
66 if ($basket[
'MODULE'] ==
'catalog')
68 $basePrices[$basket[
'ID']] = array(
69 'BASE_PRICE' => $basket[
'PRICE'] + $basket[
'DISCOUNT_PRICE'],
70 'BASE_PRICE_CURRENCY' => $basket[
'CURRENCY']
74 if ($basket[
'MODULE'] !=
'catalog' || ($basket[
'DISCOUNT_NAME'] ==
'' && $basket[
'DISCOUNT_COUPON'] ==
''))
76 if ($basket[
'SET_PARENT_ID'] > 0 && $basket[
'TYPE'] <= 0)
80 $hash = md5($basket[
'DISCOUNT_NAME'].
'|'.$basket[
'DISCOUNT_COUPON']);
81 if (!isset($basketData[$hash]))
82 $basketData[$hash] = array(
83 'DISCOUNT_NAME' => $basket[
'DISCOUNT_NAME'],
84 'DISCOUNT_COUPON' => $basket[
'DISCOUNT_COUPON'],
87 $basketData[$hash][
'ITEMS'][$basket[
'ID']] = $basket;
89 unset($basket, $basketIterator);
92 if ($process && $catalogOrder)
94 Sale\OrderDiscount::setManagerConfig(array(
95 'CURRENCY' => $order[
'CURRENCY'],
96 'SITE_ID' => $order[
'LID'],
97 'USE_BASE_PRICE' => $useBasePrice
99 foreach ($basketData as $row)
101 if (!self::migrateDiscount($order[
'ID'], $row))
105 Loc::getMessage(
'SALE_ORDER_DISCOUNT_MIGRATOR_ERR_SAVE_MIGRATE_DISCOUNT'),
115 Sale\Internals\OrderDiscountDataTable::clearByOrder($order[
'ID']);
118 if (!empty($basePrices))
120 foreach ($basePrices as $basketId => $price)
123 'ORDER_ID' => $order[
'ID'],
125 'ENTITY_ID' => $basketId,
126 'ENTITY_VALUE' => $basketId,
127 'ENTITY_DATA' => $price,
129 $operationResult = Sale\Internals\OrderDiscountDataTable::add($fields);
130 if (!$operationResult->isSuccess())
133 $result->addErrors($operationResult->getErrors());
135 unset($operationResult);
137 unset($basketId, $price);
144 'ORDER_ID' => $order[
'ID'],
146 'ENTITY_ID' => $order[
'ID'],
147 'ENTITY_VALUE' => $order[
'ID'],
148 'ENTITY_DATA' => array(
152 $operationResult = Sale\Internals\OrderDiscountDataTable::add($fields);
153 if (!$operationResult->isSuccess())
156 $result->addErrors($operationResult->getErrors());
158 unset($operationResult);
174 private static function migrateDiscount($orderId, array &$data)
176 if (self::$catalogIncluded ===
null)
177 self::$catalogIncluded = Main\Loader::includeModule(
'catalog');
178 if (!self::$catalogIncluded)
181 $discountData = array(
186 if ($data[
'DISCOUNT_NAME'] !=
'')
188 $discountName = array();
189 if (preg_match(
'/^\[(\d+)\][ ](.+)$/', $data[
'DISCOUNT_NAME'], $discountName) == 1)
191 $discountData[
'NAME'] = $discountName[2];
192 $discountData[
'DISCOUNT_ID'] = $discountName[1];
194 unset($discountName);
196 if ($data[
'DISCOUNT_COUPON'] !=
'')
198 $discountData[
'COUPON'] = $data[
'DISCOUNT_COUPON'];
199 if (!self::checkMigrateCoupon($discountData[
'COUPON']))
202 if ($discountData[
'DISCOUNT_ID'] == 0)
204 $discountData[
'NAME'] = self::$migrateCouponsCache[$discountData[
'COUPON']][
'DISCOUNT_NAME'];
205 $discountData[
'DISCOUNT_ID'] = self::$migrateCouponsCache[$discountData[
'COUPON']][
'DISCOUNT_ID'];
211 && self::$migrateCouponsCache[$discountData[
'COUPON']][
'DISCOUNT_ID'] >= 0
212 && $discountData[
'DISCOUNT_ID'] != self::$migrateCouponsCache[$discountData[
'COUPON']][
'DISCOUNT_ID']
214 $discountData[
'DISCOUNT_ID'] = 0;
217 if ($discountData[
'DISCOUNT_ID'] == 0)
219 if ($discountData[
'COUPON'] ==
'')
221 self::createEmptyDiscount($discountData);
225 self::checkMigrateDiscount($discountData);
227 $saveResult = self::saveMigrateDiscount($discountData);
228 if (!$saveResult->isSuccess())
231 $migrateDiscountData = $saveResult->getData();
233 $orderDiscountId = $migrateDiscountData[
'ORDER_DISCOUNT_ID'];
235 $discountDescr = current($migrateDiscountData[
'ACTIONS_DESCR'][
'BASKET']);
236 if ($discountData[
'COUPON'] !=
'')
238 $couponData = self::$migrateCouponsCache[$discountData[
'COUPON']];
239 $couponData[
'ORDER_ID'] = $orderId;
240 $couponData[
'ORDER_DISCOUNT_ID'] = $migrateDiscountData[
'ORDER_DISCOUNT_ID'];
241 $couponData[
'DATA'][
'DISCOUNT_ID'] = $migrateDiscountData[
'DISCOUNT_ID'];
242 if (array_key_exists(
'DISCOUNT_ID', $couponData))
243 unset($couponData[
'DISCOUNT_ID']);
244 if (array_key_exists(
'DISCOUNT_NAME', $couponData))
245 unset($couponData[
'DISCOUNT_NAME']);
247 $saveResult = Sale\OrderDiscount::saveCoupon($couponData);
248 if (!$saveResult->isSuccess())
250 $migrateCoupon = $saveResult->getData();
251 $orderCouponId = $migrateCoupon[
'ID'];
254 foreach ($data[
'ITEMS'] as $basketItem)
256 $applyDescr = $discountDescr;
257 if ($basketItem[
'DISCOUNT_VALUE'] !=
'')
261 $applyDescr[
'DESCR'] .=
' ('.$basketItem[
'DISCOUNT_VALUE'].
')';
265 $valueData = array();
266 if (preg_match(
'/^(|\+|-)(\d+|[.,]\d+|\d+[.,]\d+)\s?%$/', $basketItem[
'DISCOUNT_VALUE'], $valueData) == 1)
268 $applyDescr[
'RESULT_VALUE'] = (float)$basketItem[
'DISCOUNT_VALUE'];
269 $applyDescr[
'RESULT_UNIT'] = Sale\Discount\Formatter::VALUE_TYPE_PERCENT;
275 'MODULE_ID' =>
'catalog',
276 'ORDER_DISCOUNT_ID' => $orderDiscountId,
277 'ORDER_ID' => $orderId,
279 'ENTITY_ID' => $basketItem[
'ID'],
280 'ENTITY_VALUE' => $basketItem[
'ID'],
281 'COUPON_ID' => $orderCouponId,
285 'MODULE_ID' =>
'catalog',
286 'ORDER_DISCOUNT_ID' => $orderDiscountId,
287 'ORDER_ID' => $orderId,
288 'DESCR' => array($applyDescr)
290 $ruleResult = Sale\Internals\OrderRulesTable::add($ruleRow);
291 if ($ruleResult->isSuccess())
293 $ruleDescr[
'RULE_ID'] = $ruleResult->getId();
294 $descrResult = Sale\Internals\OrderRulesDescrTable::add($ruleDescr);
295 if (!$descrResult->isSuccess())
317 private static function checkMigrateCoupon($coupon)
319 if (self::$catalogIncluded ===
null)
320 self::$catalogIncluded = Main\Loader::includeModule(
'catalog');
321 if (!self::$catalogIncluded)
324 static $catalogCouponTypes =
null;
325 if ($catalogCouponTypes ===
null)
326 $catalogCouponTypes = array(
332 if (!isset(self::$migrateCouponsCache[$coupon]))
334 self::$migrateCouponsCache[$coupon] =
false;
335 $couponIterator = Catalog\DiscountCouponTable::getList(array(
336 'select' => array(
'COUPON_ID' =>
'ID',
'COUPON',
'TYPE',
'DISCOUNT_ID',
'DISCOUNT_NAME' =>
'DISCOUNT.NAME'),
337 'filter' => array(
'=COUPON' => $coupon)
339 $existCoupon = $couponIterator->fetch();
340 unset($couponIterator);
341 if (!empty($existCoupon))
343 $existCoupon[
'TYPE'] = (
344 isset($catalogCouponTypes[$existCoupon[
'TYPE']])
345 ? $catalogCouponTypes[$existCoupon[
'TYPE']]
346 : Sale\Internals\DiscountCouponTable::TYPE_ARCHIVED
348 $existCoupon[
'DATA'] = array(
350 'MODULE' =>
'catalog',
353 'USER_INFO' => array(),
355 self::$migrateCouponsCache[$coupon] = $existCoupon;
359 self::$migrateCouponsCache[$coupon] = self::createEmptyCoupon($coupon);
373 private static function createEmptyCoupon($coupon)
382 'MODULE' =>
'catalog',
385 'USER_INFO' => array(),
398 private static function createEmptyDiscount(array &$discountData, $accumulate =
false)
400 $accumulate = ($accumulate ===
true);
401 static $emptyFields =
null;
402 if ($emptyFields ===
null)
404 $emptyFields = array(
406 'NAME' =>
Loc::getMessage(
'SALE_ORDER_DISCOUNT_MIGRATOR_MESS_CATALOG_DISCOUNT_NAME'),
409 'LAST_DISCOUNT' =>
'Y',
414 static $replaceFields =
null;
415 static $replaceKeys =
null;
416 if ($replaceFields ===
null)
418 $replaceFields = array(
419 'MODULE_ID' =>
'catalog',
420 'CONDITIONS' => array(
421 'CLASS_ID' =>
'CondGroup',
422 'DATA' => array(
'All' =>
'AND',
'True' =>
'True'),
423 'CHILDREN' => array()
425 'UNPACK' =>
'((1 == 1))',
426 'ACTIONS' => array(),
429 $replaceKeys = array(
437 static $discountDescr =
null;
438 if ($discountDescr ===
null)
440 $discountDescr = Sale\Discount\Formatter::prepareRow(
442 Loc::getMessage(
'SALE_ORDER_DISCOUNT_MIGRATOR_MESS_CATALOG_DISCOUNT_SIMPLE_MESS')
445 static $accumulateDescr =
null;
446 if ($accumulateDescr ===
null)
448 $accumulateDescr = Sale\Discount\Formatter::prepareRow(
450 Loc::getMessage(
'SALE_ORDER_DISCOUNT_MIGRATOR_MESS_TYPE_ACCUMULATE_EMPTY')
453 foreach ($replaceKeys as $key)
455 if (array_key_exists($key, $discountData))
456 unset($discountData[$key]);
459 $discountData = array_merge($emptyFields, $discountData);
460 foreach ($replaceFields as $key => $value)
462 $discountData[$key] = $value;
465 if (empty($discountData[
'ACTIONS_DESCR']))
466 $discountData[
'ACTIONS_DESCR'] = array(
468 0 => ($accumulate ? $accumulateDescr : $discountDescr)
472 $discountData[
'USE_COUPONS'] = ($discountData[
'COUPON'] !=
'' ?
'Y' :
'N');
484 private static function checkMigrateDiscount(&$discountData)
486 if (self::$catalogIncluded ===
null)
487 self::$catalogIncluded = Main\Loader::includeModule(
'catalog');
488 if (!self::$catalogIncluded)
491 $coupon = $discountData[
'COUPON'];
492 $hash = md5($discountData[
'DISCOUNT_ID'].
'|'.$discountData[
'NAME']);
493 if (!isset(self::$catalogDiscountsCache[$hash]))
495 $discountIterator = Catalog\DiscountTable::getList(array(
496 'select' => array(
'*'),
497 'filter' => array(
'=ID' => $discountData[
'DISCOUNT_ID'],
'=NAME' => $discountData[
'NAME'])
499 $existDiscount = $discountIterator->fetch();
500 unset($discountIterator);
501 if (!empty($existDiscount))
503 if ($existDiscount[
'NAME'] != $discountData[
'NAME'])
505 self::createEmptyDiscount($discountData);
509 if ($existDiscount[
'TYPE'] == Catalog\DiscountTable::TYPE_DISCOUNT_SAVE)
511 self::createEmptyDiscount($discountData,
true);
515 $existDiscount[
'COUPON'] = $discountData[
'COUPON'];
516 $discountData = Catalog\Discount\DiscountManager::prepareData(
524 self::createEmptyDiscount($discountData);
526 unset($existDiscount);
527 self::$catalogDiscountsCache[$hash] = $discountData;
531 $discountData = self::$catalogDiscountsCache[$hash];
533 $discountData[
'COUPON'] = $coupon;
544 private static function saveMigrateDiscount(array $discountData)
546 $result =
new Sale\Result();
549 $resultData = array();
550 $fields = Sale\Internals\OrderDiscountTable::prepareDiscountData($discountData);
551 if (empty($fields) || !is_array($fields))
554 $result->addError(
new Main\Entity\EntityError(
555 Loc::getMessage(
'SALE_ORDER_DISCOUNT_MIGRATOR_ERR_BAD_PREPARE_DISCOUNT'),
562 $hash = Sale\Internals\OrderDiscountTable::calculateHash($fields);
566 $result->addError(
new Main\Entity\EntityError(
575 if (!isset(self::$migrateDiscountsCache[$hash]))
577 $orderDiscountIterator = Sale\Internals\OrderDiscountTable::getList(array(
578 'select' => array(
'*'),
579 'filter' => array(
'=DISCOUNT_HASH' => $hash)
581 if ($orderDiscount = $orderDiscountIterator->fetch())
582 self::$migrateDiscountsCache[$hash] = $orderDiscount;
583 unset($orderDiscount, $orderDiscountIterator);
585 if (!empty(self::$migrateDiscountsCache[$hash]))
587 $resultData = self::$migrateDiscountsCache[$hash];
588 $resultData[
'ID'] = (int)$resultData[
'ID'];
589 $resultData[
'NAME'] = (string)$resultData[
'NAME'];
590 $resultData[
'ORDER_DISCOUNT_ID'] = $resultData[
'ID'];
591 $result->setId($resultData[
'ID']);
595 $fields[
'DISCOUNT_HASH'] = $hash;
596 $fields[
'ACTIONS_DESCR'] = array();
597 if (isset($discountData[
'ACTIONS_DESCR']))
598 $fields[
'ACTIONS_DESCR'] = $discountData[
'ACTIONS_DESCR'];
599 $tableResult = Sale\Internals\OrderDiscountTable::add($fields);
600 if ($tableResult->isSuccess())
602 $resultData = $fields;
603 $resultData[
'ID'] = (int)$tableResult->getId();
604 $resultData[
'NAME'] = (string)$resultData[
'NAME'];
605 $resultData[
'ORDER_DISCOUNT_ID'] = $resultData[
'ID'];
606 $result->setId($resultData[
'ID']);
611 $result->addErrors($tableResult->getErrors());
613 unset($tableResult, $fields);
617 $moduleList = Sale\Internals\OrderDiscountTable::getDiscountModules($discountData);
618 if (!empty($moduleList))
620 $resultModule = Sale\Internals\OrderModulesTable::saveOrderDiscountModules(
621 $resultData[
'ORDER_DISCOUNT_ID'],
626 Sale\Internals\OrderDiscountTable::clearList($resultData[
'ORDER_DISCOUNT_ID']);
627 $resultData = array();
629 $result->addError(
new Main\Entity\EntityError(
630 Loc::getMessage(
'SALE_ORDER_DISCOUNT_MIGRATOR_ERR_SAVE_DISCOUNT_MODULES'),
634 unset($resultModule);
636 unset($needDiscountModules, $moduleList);
642 $result->setData($resultData);
643 unset($resultData, $process);