Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
orderdiscountmigrator.php
1<?php
3
8
9Loc::loadMessages(__FILE__);
10
12{
13 const ERROR_ID = 'BX_SALE_ORDER_DISCOUNT_MIGRATOR';
14
15 private static $catalogIncluded = null;
16 private static $migrateDiscountsCache = array();
17 private static $migrateCouponsCache = array();
18 private static $catalogDiscountsCache = array();
19
26 public static function processing(array $order)
27 {
28 static $useBasePrice = null;
29 if ($useBasePrice === null)
30 $useBasePrice = (string)Main\Config\Option::get('sale', 'get_discount_percent_from_base_price');
31
32 $process = true;
33 $result = new Sale\Result();
34
35 if (empty($order['ID']) || (int)$order['ID'] <= 0)
36 {
37 $process = false;
38 $result->addError(new Main\Entity\EntityError(
39 Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_ERR_EMPTY_ORDER_ID'),
40 self::ERROR_ID
41 ));
42 }
43
44 $catalogOrder = false;
45 $basketData = array();
46 if ($process)
47 {
48 $order['ID'] = (int)$order['ID'];
49 $basePrices = array();
50
51 $basketIterator = Sale\Internals\BasketTable::getList(array(
52 'select' => array(
53 'ID', 'DISCOUNT_COUPON', 'DISCOUNT_NAME', 'DISCOUNT_VALUE',
54 'MODULE', 'PRICE', 'DISCOUNT_PRICE', 'CURRENCY', 'SET_PARENT_ID', 'TYPE'
55 ),
56 'filter' => array('=ORDER_ID' => $order['ID'])
57 ));
58 while ($basket = $basketIterator->fetch())
59 {
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')
67 {
68 $basePrices[$basket['ID']] = array(
69 'BASE_PRICE' => $basket['PRICE'] + $basket['DISCOUNT_PRICE'],
70 'BASE_PRICE_CURRENCY' => $basket['CURRENCY']
71 );
72 }
73
74 if ($basket['MODULE'] != 'catalog' || ($basket['DISCOUNT_NAME'] == '' && $basket['DISCOUNT_COUPON'] == ''))
75 continue;
76 if ($basket['SET_PARENT_ID'] > 0 && $basket['TYPE'] <= 0)
77 continue;
78
79 $catalogOrder = true;
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'],
85 'ITEMS' => array()
86 );
87 $basketData[$hash]['ITEMS'][$basket['ID']] = $basket;
88 }
89 unset($basket, $basketIterator);
90 }
91
92 if ($process && $catalogOrder)
93 {
94 Sale\OrderDiscount::setManagerConfig(array(
95 'CURRENCY' => $order['CURRENCY'],
96 'SITE_ID' => $order['LID'],
97 'USE_BASE_PRICE' => $useBasePrice
98 ));
99 foreach ($basketData as $row)
100 {
101 if (!self::migrateDiscount($order['ID'], $row))
102 {
103 $process = false;
104 $result->addError(new Main\Entity\EntityError(
105 Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_ERR_SAVE_MIGRATE_DISCOUNT'),
106 self::ERROR_ID
107 ));
108 break;
109 }
110 }
111 unset($row);
112 }
113 unset($basketData);
114
115 Sale\Internals\OrderDiscountDataTable::clearByOrder($order['ID']);
116 if ($process)
117 {
118 if (!empty($basePrices))
119 {
120 foreach ($basePrices as $basketId => $price)
121 {
122 $fields = array(
123 'ORDER_ID' => $order['ID'],
124 'ENTITY_TYPE' => Sale\Internals\OrderDiscountDataTable::ENTITY_TYPE_BASKET_ITEM,
125 'ENTITY_ID' => $basketId,
126 'ENTITY_VALUE' => $basketId,
127 'ENTITY_DATA' => $price,
128 );
129 $operationResult = Sale\Internals\OrderDiscountDataTable::add($fields);
130 if (!$operationResult->isSuccess())
131 {
132 $process = false;
133 $result->addErrors($operationResult->getErrors());
134 }
135 unset($operationResult);
136 }
137 unset($basketId, $price);
138 }
139 }
140
141 if ($process)
142 {
143 $fields = array(
144 'ORDER_ID' => $order['ID'],
145 'ENTITY_TYPE' => Sale\Internals\OrderDiscountDataTable::ENTITY_TYPE_ORDER,
146 'ENTITY_ID' => $order['ID'],
147 'ENTITY_VALUE' => $order['ID'],
148 'ENTITY_DATA' => array(
149 'OLD_ORDER' => 'Y'
150 )
151 );
152 $operationResult = Sale\Internals\OrderDiscountDataTable::add($fields);
153 if (!$operationResult->isSuccess())
154 {
155 $process = false;
156 $result->addErrors($operationResult->getErrors());
157 }
158 unset($operationResult);
159 }
160 unset($process);
161
162 return $result;
163 }
164
174 private static function migrateDiscount($orderId, array &$data)
175 {
176 if (self::$catalogIncluded === null)
177 self::$catalogIncluded = Main\Loader::includeModule('catalog');
178 if (!self::$catalogIncluded)
179 return false;
180
181 $discountData = array(
182 'COUPON' => '',
183 'NAME' => '',
184 'DISCOUNT_ID' => 0
185 );
186 if ($data['DISCOUNT_NAME'] != '')
187 {
188 $discountName = array();
189 if (preg_match('/^\[(\d+)\][ ](.+)$/', $data['DISCOUNT_NAME'], $discountName) == 1)
190 {
191 $discountData['NAME'] = $discountName[2];
192 $discountData['DISCOUNT_ID'] = $discountName[1];
193 }
194 unset($discountName);
195 }
196 if ($data['DISCOUNT_COUPON'] != '')
197 {
198 $discountData['COUPON'] = $data['DISCOUNT_COUPON'];
199 if (!self::checkMigrateCoupon($discountData['COUPON']))
200 return false;
201
202 if ($discountData['DISCOUNT_ID'] == 0)
203 {
204 $discountData['NAME'] = self::$migrateCouponsCache[$discountData['COUPON']]['DISCOUNT_NAME'];
205 $discountData['DISCOUNT_ID'] = self::$migrateCouponsCache[$discountData['COUPON']]['DISCOUNT_ID'];
206 }
207 else
208 {
209 if (
210 self::$migrateCouponsCache[$discountData['COUPON']]['TYPE'] != Sale\Internals\DiscountCouponTable::TYPE_ARCHIVED
211 && self::$migrateCouponsCache[$discountData['COUPON']]['DISCOUNT_ID'] >= 0
212 && $discountData['DISCOUNT_ID'] != self::$migrateCouponsCache[$discountData['COUPON']]['DISCOUNT_ID']
213 )
214 $discountData['DISCOUNT_ID'] = 0;
215 }
216 }
217 if ($discountData['DISCOUNT_ID'] == 0)
218 {
219 if ($discountData['COUPON'] == '')
220 return false;
221 self::createEmptyDiscount($discountData);
222 }
223 else
224 {
225 self::checkMigrateDiscount($discountData);
226 }
227 $saveResult = self::saveMigrateDiscount($discountData);
228 if (!$saveResult->isSuccess())
229 return false;
230
231 $migrateDiscountData = $saveResult->getData();
232 unset($saveResult);
233 $orderDiscountId = $migrateDiscountData['ORDER_DISCOUNT_ID'];
234 $orderCouponId = 0;
235 $discountDescr = current($migrateDiscountData['ACTIONS_DESCR']['BASKET']);
236 if ($discountData['COUPON'] != '')
237 {
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']);
246
247 $saveResult = Sale\OrderDiscount::saveCoupon($couponData);
248 if (!$saveResult->isSuccess())
249 return false;
250 $migrateCoupon = $saveResult->getData();
251 $orderCouponId = $migrateCoupon['ID'];
252 }
253
254 foreach ($data['ITEMS'] as $basketItem)
255 {
256 $applyDescr = $discountDescr;
257 if ($basketItem['DISCOUNT_VALUE'] != '')
258 {
259 if ($applyDescr['TYPE'] == Sale\Discount\Formatter::TYPE_SIMPLE)
260 {
261 $applyDescr['DESCR'] .= ' ('.$basketItem['DISCOUNT_VALUE'].')';
262 }
263 else
264 {
265 $valueData = array();
266 if (preg_match('/^(|\+|-)(\d+|[.,]\d+|\d+[.,]\d+)\s?%$/', $basketItem['DISCOUNT_VALUE'], $valueData) == 1)
267 {
268 $applyDescr['RESULT_VALUE'] = (float)$basketItem['DISCOUNT_VALUE'];
269 $applyDescr['RESULT_UNIT'] = Sale\Discount\Formatter::VALUE_TYPE_PERCENT;
270 }
271 unset($valueData);
272 }
273 }
274 $ruleRow = array(
275 'MODULE_ID' => 'catalog',
276 'ORDER_DISCOUNT_ID' => $orderDiscountId,
277 'ORDER_ID' => $orderId,
278 'ENTITY_TYPE' => Sale\Internals\OrderRulesTable::ENTITY_TYPE_BASKET_ITEM,
279 'ENTITY_ID' => $basketItem['ID'],
280 'ENTITY_VALUE' => $basketItem['ID'],
281 'COUPON_ID' => $orderCouponId,
282 'APPLY' => 'Y'
283 );
284 $ruleDescr = array(
285 'MODULE_ID' => 'catalog',
286 'ORDER_DISCOUNT_ID' => $orderDiscountId,
287 'ORDER_ID' => $orderId,
288 'DESCR' => array($applyDescr)
289 );
290 $ruleResult = Sale\Internals\OrderRulesTable::add($ruleRow);
291 if ($ruleResult->isSuccess())
292 {
293 $ruleDescr['RULE_ID'] = $ruleResult->getId();
294 $descrResult = Sale\Internals\OrderRulesDescrTable::add($ruleDescr);
295 if (!$descrResult->isSuccess())
296 return false;
297 }
298 else
299 {
300 return false;
301 }
302 unset($ruleResult);
303 }
304 unset($basketItem);
305
306 return true;
307 }
308
317 private static function checkMigrateCoupon($coupon)
318 {
319 if (self::$catalogIncluded === null)
320 self::$catalogIncluded = Main\Loader::includeModule('catalog');
321 if (!self::$catalogIncluded)
322 return false;
323
324 static $catalogCouponTypes = null;
325 if ($catalogCouponTypes === null)
326 $catalogCouponTypes = array(
330 );
331
332 if (!isset(self::$migrateCouponsCache[$coupon]))
333 {
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)
338 ));
339 $existCoupon = $couponIterator->fetch();
340 unset($couponIterator);
341 if (!empty($existCoupon))
342 {
343 $existCoupon['TYPE'] = (
344 isset($catalogCouponTypes[$existCoupon['TYPE']])
345 ? $catalogCouponTypes[$existCoupon['TYPE']]
346 : Sale\Internals\DiscountCouponTable::TYPE_ARCHIVED
347 );
348 $existCoupon['DATA'] = array(
350 'MODULE' => 'catalog',
351 'DISCOUNT_ID' => 0,
352 'TYPE' => Sale\Internals\DiscountCouponTable::TYPE_ARCHIVED,
353 'USER_INFO' => array(),
354 );
355 self::$migrateCouponsCache[$coupon] = $existCoupon;
356 }
357 else
358 {
359 self::$migrateCouponsCache[$coupon] = self::createEmptyCoupon($coupon);
360 }
361 unset($existCoupon);
362 }
363 return true;
364 }
365
373 private static function createEmptyCoupon($coupon)
374 {
375 return array(
376 'COUPON' => $coupon,
377 'TYPE' => Sale\Internals\DiscountCouponTable::TYPE_ARCHIVED,
378 'COUPON_ID' => 0,
379 'DATA' => array(
380 'COUPON' => $coupon,
382 'MODULE' => 'catalog',
383 'DISCOUNT_ID' => 0,
384 'TYPE' => Sale\Internals\DiscountCouponTable::TYPE_ARCHIVED,
385 'USER_INFO' => array(),
386 )
387 );
388 }
389
398 private static function createEmptyDiscount(array &$discountData, $accumulate = false)
399 {
400 $accumulate = ($accumulate === true);
401 static $emptyFields = null;
402 if ($emptyFields === null)
403 {
404 $emptyFields = array(
405 'DISCOUNT_ID' => 0,
406 'NAME' => Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_MESS_CATALOG_DISCOUNT_NAME'),
407 'SORT' => 100,
408 'PRIORITY' => 1,
409 'LAST_DISCOUNT' => 'Y',
410 'USE_COUPONS' => 'N'
411 );
412 }
413
414 static $replaceFields = null;
415 static $replaceKeys = null;
416 if ($replaceFields === null)
417 {
418 $replaceFields = array(
419 'MODULE_ID' => 'catalog',
420 'CONDITIONS' => array(
421 'CLASS_ID' => 'CondGroup',
422 'DATA' => array('All' => 'AND', 'True' => 'True'),
423 'CHILDREN' => array()
424 ),
425 'UNPACK' => '((1 == 1))',
426 'ACTIONS' => array(),
427 'APPLICATION' => '0'
428 );
429 $replaceKeys = array(
430 'MODULE_ID',
431 'CONDITIONS',
432 'UNPACK',
433 'ACTIONS',
434 'APPLICATION'
435 );
436 }
437 static $discountDescr = null;
438 if ($discountDescr === null)
439 {
440 $discountDescr = Sale\Discount\Formatter::prepareRow(
442 Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_MESS_CATALOG_DISCOUNT_SIMPLE_MESS')
443 );
444 }
445 static $accumulateDescr = null;
446 if ($accumulateDescr === null)
447 {
448 $accumulateDescr = Sale\Discount\Formatter::prepareRow(
450 Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_MESS_TYPE_ACCUMULATE_EMPTY')
451 );
452 }
453 foreach ($replaceKeys as $key)
454 {
455 if (array_key_exists($key, $discountData))
456 unset($discountData[$key]);
457 }
458 unset($key);
459 $discountData = array_merge($emptyFields, $discountData);
460 foreach ($replaceFields as $key => $value)
461 {
462 $discountData[$key] = $value;
463 }
464 unset($key, $value);
465 if (empty($discountData['ACTIONS_DESCR']))
466 $discountData['ACTIONS_DESCR'] = array(
467 'BASKET' => array(
468 0 => ($accumulate ? $accumulateDescr : $discountDescr)
469 )
470 );
471 if (!$accumulate)
472 $discountData['USE_COUPONS'] = ($discountData['COUPON'] != '' ? 'Y' : 'N');
473 }
474
484 private static function checkMigrateDiscount(&$discountData)
485 {
486 if (self::$catalogIncluded === null)
487 self::$catalogIncluded = Main\Loader::includeModule('catalog');
488 if (!self::$catalogIncluded)
489 return;
490
491 $coupon = $discountData['COUPON'];
492 $hash = md5($discountData['DISCOUNT_ID'].'|'.$discountData['NAME']);
493 if (!isset(self::$catalogDiscountsCache[$hash]))
494 {
495 $discountIterator = Catalog\DiscountTable::getList(array(
496 'select' => array('*'),
497 'filter' => array('=ID' => $discountData['DISCOUNT_ID'], '=NAME' => $discountData['NAME'])
498 ));
499 $existDiscount = $discountIterator->fetch();
500 unset($discountIterator);
501 if (!empty($existDiscount))
502 {
503 if ($existDiscount['NAME'] != $discountData['NAME'])
504 {
505 self::createEmptyDiscount($discountData);
506 }
507 else
508 {
509 if ($existDiscount['TYPE'] == Catalog\DiscountTable::TYPE_DISCOUNT_SAVE)
510 {
511 self::createEmptyDiscount($discountData, true);
512 }
513 else
514 {
515 $existDiscount['COUPON'] = $discountData['COUPON'];
516 $discountData = Catalog\Discount\DiscountManager::prepareData(
517 $existDiscount, Sale\OrderDiscount::getManagerConfig()
518 );
519 }
520 }
521 }
522 else
523 {
524 self::createEmptyDiscount($discountData);
525 }
526 unset($existDiscount);
527 self::$catalogDiscountsCache[$hash] = $discountData;
528 }
529 else
530 {
531 $discountData = self::$catalogDiscountsCache[$hash];
532 }
533 $discountData['COUPON'] = $coupon;
534 }
535
544 private static function saveMigrateDiscount(array $discountData)
545 {
546 $result = new Sale\Result();
547 $process = true;
548 $hash = false;
549 $resultData = array();
550 $fields = Sale\Internals\OrderDiscountTable::prepareDiscountData($discountData);
551 if (empty($fields) || !is_array($fields))
552 {
553 $process = false;
554 $result->addError(new Main\Entity\EntityError(
555 Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_ERR_BAD_PREPARE_DISCOUNT'),
556 self::ERROR_ID
557 ));
558 }
559
560 if ($process)
561 {
562 $hash = Sale\Internals\OrderDiscountTable::calculateHash($fields);
563 if ($hash === false)
564 {
565 $process = false;
566 $result->addError(new Main\Entity\EntityError(
567 Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_ERR_BAD_DISCOUNT_HASH'),
568 self::ERROR_ID
569 ));
570 }
571 }
572
573 if ($process)
574 {
575 if (!isset(self::$migrateDiscountsCache[$hash]))
576 {
577 $orderDiscountIterator = Sale\Internals\OrderDiscountTable::getList(array(
578 'select' => array('*'),
579 'filter' => array('=DISCOUNT_HASH' => $hash)
580 ));
581 if ($orderDiscount = $orderDiscountIterator->fetch())
582 self::$migrateDiscountsCache[$hash] = $orderDiscount;
583 unset($orderDiscount, $orderDiscountIterator);
584 }
585 if (!empty(self::$migrateDiscountsCache[$hash]))
586 {
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']);
592 }
593 else
594 {
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())
601 {
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']);
607 }
608 else
609 {
610 $process = false;
611 $result->addErrors($tableResult->getErrors());
612 }
613 unset($tableResult, $fields);
614
615 if ($process)
616 {
617 $moduleList = Sale\Internals\OrderDiscountTable::getDiscountModules($discountData);
618 if (!empty($moduleList))
619 {
620 $resultModule = Sale\Internals\OrderModulesTable::saveOrderDiscountModules(
621 $resultData['ORDER_DISCOUNT_ID'],
622 $moduleList
623 );
624 if (!$resultModule)
625 {
626 Sale\Internals\OrderDiscountTable::clearList($resultData['ORDER_DISCOUNT_ID']);
627 $resultData = array();
628 $process = false;
629 $result->addError(new Main\Entity\EntityError(
630 Loc::getMessage('SALE_ORDER_DISCOUNT_MIGRATOR_ERR_SAVE_DISCOUNT_MODULES'),
631 self::ERROR_ID
632 ));
633 }
634 unset($resultModule);
635 }
636 unset($needDiscountModules, $moduleList);
637 }
638 }
639 }
640
641 if ($process)
642 $result->setData($resultData);
643 unset($resultData, $process);
644
645 return $result;
646 }
647}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29