Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
discount.php
1<?php
8namespace Bitrix\Sale;
9
10use Bitrix\Main,
14
15Loc::loadMessages(__FILE__);
16
18{
19 /* Sale objects */
21 protected $shipment = null;
23 protected $shipmentIds = array();
24
26 protected $enableCheckingPrediction = false;
27
32 public function enableCheckingPrediction()
33 {
34 $this->enableCheckingPrediction = true;
35 $this->saleOptions = array(
36 'APPLY_MODE' => $this::APPLY_MODE_ADD,
37 );
38 }
39
44 public function disableCheckingPrediction()
45 {
46 $this->enableCheckingPrediction = false;
47 }
48
56 public static function loadByFuser($fuser, $site)
57 {
58 $instanceIndex = static::getInstanceIndexByFuser((int)$fuser, (string)$site);
59 if (!static::instanceExists($instanceIndex))
60 return null;
61 return static::getInstance($instanceIndex);
62 }
63
70 public static function getRegistryType()
71 {
72 return Registry::REGISTRY_TYPE_ORDER;
73 }
74
81 public function setCalculateShipments(Shipment $shipment = null)
82 {
83 $this->shipment = $shipment;
84 }
85
91 public function getShipmentsIds()
92 {
93 return $this->shipmentIds;
94 }
95
104 public function createClone(\SplObjectStorage $cloneEntity)
105 {
107 $discountClone = parent::createClone($cloneEntity);
108
109 if ($this->isShipmentExists())
110 {
111 if ($cloneEntity->contains($this->shipment))
112 $discountClone->shipment = $cloneEntity[$this->shipment];
113 }
114
115 return $discountClone;
116 }
117
118 /* apply result methods */
119
126 public function setApplyResult($applyResult)
127 {
128 parent::setApplyResult($applyResult);
129
130 if (!empty($this->applyResult['DISCOUNT_LIST']))
131 {
132 if (!empty($this->applyResult['DELIVERY']) && is_array($this->applyResult['DELIVERY']))
133 {
134 foreach ($this->applyResult['DELIVERY'] as $orderDiscountId => $apply)
135 {
136 if ($apply == 'Y')
137 $this->applyResult['DISCOUNT_LIST'][$orderDiscountId] = 'Y';
138 }
139 unset($apply, $orderDiscountId);
140 }
141 }
142 }
143
150 public function getApplyResult($extMode = false)
151 {
152 if (Compatible\DiscountCompatibility::isUsed())
153 return Compatible\DiscountCompatibility::getApplyResult($extMode);
154
155 $extMode = ($extMode === true);
156
157 $result = parent::getApplyResult($extMode);
158 $result = $this->getApplyDeliveryList() + $result;
159
160 $result['CONVERTED_ORDER'] = (!$this->isValidState() ? 'Y' : 'N');
161
162 if (!$extMode)
163 {
164 /* for compatibility only */
165 if (isset($this->discountResult['APPLY_BLOCKS'][0]['BASKET']))
166 $result['BASKET'] = $this->discountResult['APPLY_BLOCKS'][0]['BASKET'];
167 if (isset($this->discountResult['APPLY_BLOCKS'][0]['ORDER']))
168 $result['ORDER'] = $this->discountResult['APPLY_BLOCKS'][0]['ORDER'];
169 }
170 return $result;
171 }
172
178 public function getShowPrices()
179 {
180 $result = parent::getShowPrices();
181 $result['DELIVERY'] = $this->getApplyDeliveryPrice();
182
183 return $result;
184 }
185
191 public function save()
192 {
193 $result = new Result;
194 if (!$this->isOrderExists() || !$this->isBasketNotEmpty())
195 return $result;
196
197 if ($this->isUsedDiscountCompatibility())
198 {
200 return $result;
201 $compatibleResult = Compatible\DiscountCompatibility::getResult();
202 if ($compatibleResult === false)
203 return $result;
204 if (empty($compatibleResult))
205 return $result;
206
207 $this->setUseMode($compatibleResult['CALCULATE']['USE_MODE']);
208 $this->newOrder = $compatibleResult['CALCULATE']['NEW_ORDER'];
209 $this->discountsCache = $compatibleResult['DISCOUNT_LIST'];
210 $this->couponsCache = $compatibleResult['COUPONS_LIST'];
211 $this->discountResult = $compatibleResult['DISCOUNT_RESULT'];
212 $this->forwardBasketTable = $compatibleResult['FORWARD_BASKET_TABLE'];
213 $this->reverseBasketTable = $compatibleResult['REVERSE_BASKET_TABLE'];
214 if ($this->isOrderNew())
215 {
216 $shipmentResult = $this->loadShipment();
217 if (!$shipmentResult->isSuccess())
218 {
219 $result->addErrors($shipmentResult->getErrors());
220 unset($shipmentResult);
221 return $result;
222 }
223 unset($shipmentResult);
224 $this->fillShipmentData();
225 }
226 unset($compatibleResult);
227 }
228
229 $result = parent::save();
230
231 return $result;
232 }
233
239 protected function getOrderConfig()
240 {
241 $shipmentClassName = $this->getShipmentClassName();
242 $config = parent::getOrderConfig();
243 $config['DELIVERY'] = [
244 'DELIVERY_ID' => $this->orderData['DELIVERY_ID'],
245 'CUSTOM_PRICE_DELIVERY' => $this->orderData['CUSTOM_PRICE_DELIVERY'],
246 'SHIPMENT_ID' => 0
247 ];
248 if ($this->shipment instanceof $shipmentClassName)
249 $config['DELIVERY']['SHIPMENT_ID'] = $this->shipment->getId();
250 unset($shipmentClassName);
251 return $config;
252 }
253
254 /* instance tools */
255
264 protected static function getInstanceIndexByFuser($fuser, $site)
265 {
266 return '0|'.$fuser.'|'.$site;
267 }
268
276 protected function getExecuteFieldList()
277 {
278 if (!$this->enableCheckingPrediction)
279 return parent::getExecuteFieldList();
280 return ['PREDICTIONS_APP', 'APPLICATION'];
281 }
282
290 protected function getConditionField()
291 {
292 if (!$this->enableCheckingPrediction)
293 return parent::getConditionField();
294 return 'PREDICTIONS_APP';
295 }
296
303 protected static function getStepResult(array $order)
304 {
305 $result = parent::getStepResult($order);;
306 $stepResult = &$order['DISCOUNT_RESULT'];
307 if (!empty($stepResult['DELIVERY']) && is_array($stepResult['DELIVERY']))
308 {
309 $result['DELIVERY'] = array(
310 'APPLY' => 'Y',
311 'DELIVERY_ID' => (isset($order['DELIVERY_ID']) ? $order['DELIVERY_ID'] : false),
312 'SHIPMENT_CODE' => (isset($order['SHIPMENT_CODE']) ? $order['SHIPMENT_CODE'] : false),
313 'DESCR' => Discount\Formatter::formatList($stepResult['DELIVERY']),
314 'DESCR_DATA' => $stepResult['DELIVERY'],
315 'ACTION_BLOCK_LIST' => array_keys($stepResult['DELIVERY'])
316 );
317 if (is_array($result['DELIVERY']['DESCR']))
318 $result['DELIVERY']['DESCR'] = implode(', ', $result['DELIVERY']['DESCR']);
319 }
320 unset($stepResult);
321
322 return $result;
323 }
324
331 protected function normalizeDiscountResult()
332 {
333 parent::normalizeDiscountResult();
334
335 if (empty($this->orderData))
336 {
337 return;
338 }
339
340 $customPrice = isset($this->orderData['CUSTOM_PRICE_DELIVERY']) && $this->orderData['CUSTOM_PRICE_DELIVERY'] == 'Y';
341 $this->orderData['PRICE_DELIVERY_DIFF'] = (!$customPrice
342 ? PriceMaths::roundPrecision($this->orderData['PRICE_DELIVERY_DIFF'])
343 : 0
344 );
345 if (!$customPrice)
346 {
347 if ($this->orderData['PRICE_DELIVERY_DIFF'] > 0)
348 $this->orderData['PRICE_DELIVERY'] = $this->orderData['BASE_PRICE_DELIVERY'] - $this->orderData['PRICE_DELIVERY_DIFF'];
349 else
350 $this->orderData['PRICE_DELIVERY'] = PriceMaths::roundPrecision($this->orderData['PRICE_DELIVERY']);
351 }
352 unset($customPrice);
353 }
354
360 protected function getApplyPrices()
361 {
362 parent::getApplyPrices();
363 $this->discountResult['PRICES']['DELIVERY'] = $this->getApplyDeliveryPrice();
364 }
365
371 protected function remakingDiscountResult()
372 {
373 parent::remakingDiscountResult();
374
375 $delivery = [];
376 if (!empty($this->discountResult['APPLY_BLOCKS']))
377 {
378 foreach ($this->discountResult['APPLY_BLOCKS'] as $counter => $applyBlock)
379 {
380 if (!empty($applyBlock['ORDER']))
381 {
382 foreach ($applyBlock['ORDER'] as $discount)
383 {
384 if (!empty($discount['RESULT']['DELIVERY']))
385 {
386 $delivery[] = [
387 'DISCOUNT_ID' => $discount['DISCOUNT_ID'],
388 'COUPON_ID' => $discount['COUPON_ID'],
389 'DELIVERY_ID' => $discount['RESULT']['DELIVERY']['DELIVERY_ID'],
390 'APPLY' => $discount['RESULT']['DELIVERY']['APPLY'],
391 'DESCR' => $discount['RESULT']['DELIVERY']['DESCR']
392 ];
393 }
394 }
395 unset($discount);
396 }
397 }
398 unset($counter, $applyBlock);
399 }
400 $this->discountResult['RESULT']['DELIVERY'] = $delivery;
401 unset($delivery);
402 }
403
409 protected function getApplyDeliveryPrice()
410 {
411 return array(
412 'BASE_PRICE' => $this->orderData['BASE_PRICE_DELIVERY'] ?? 0.0,
413 'PRICE' => $this->orderData['PRICE_DELIVERY'] ?? 0.0,
414 'DISCOUNT' => $this->orderData['PRICE_DELIVERY_DIFF'] ?? 0.0,
415 );
416 }
417
423 protected function getApplyDeliveryList()
424 {
425 $result = array();
426
427 $delivery = array();
428 if (!empty($this->discountResult['APPLY_BLOCKS']))
429 {
430 foreach ($this->discountResult['APPLY_BLOCKS'] as $counter => $applyBlock)
431 {
432 if (!empty($applyBlock['ORDER']))
433 {
434 foreach ($applyBlock['ORDER'] as $discount)
435 {
436 if (empty($discount['RESULT']['DELIVERY']))
437 continue;
438 $id = $discount['RESULT']['DELIVERY']['DELIVERY_ID'];
439 $delivery[$id] = $id;
440 }
441 unset($id, $discount);
442 }
443 }
444 unset($counter, $applyBlock);
445 }
446 $result['DELIVERY_LIST'] = (empty($delivery) ? array() : array_values($delivery));
447 unset($delivery);
448
449 $shipmentClassName = $this->getShipmentClassName();
450 $shipment = [];
451 if ($this->shipment instanceof $shipmentClassName)
452 $shipment[] = $this->shipment->getShipmentCode();
453 $result['SHIPMENT_LIST'] = $shipment;
454 unset($shipment);
455
456 return $result;
457 }
458
464 protected function fillEmptyDiscountResult()
465 {
466 parent::fillEmptyDiscountResult();
467 $this->discountResult['DELIVERY_LIST'] = [];
468 $this->discountResult['SHIPMENT_LIST'] = [];
469 }
470
476 protected function fillDiscountResult()
477 {
478 $result = parent::fillDiscountResult();
479
480 $orderKeys = ['PRICE_DELIVERY', 'PRICE_DELIVERY_DIFF'];
481 foreach ($orderKeys as $key)
482 {
483 if (isset($this->orderData[$key]))
484 $result[$key] = $this->orderData[$key];
485 }
486 unset($key, $orderKeys);
487 if (isset($result['PRICE_DELIVERY_DIFF']))
488 {
489 $result['DISCOUNT_PRICE'] = $result['PRICE_DELIVERY_DIFF'];
490 unset($result['PRICE_DELIVERY_DIFF']);
491 }
492
493 $shipmentClassName = $this->getShipmentClassName();
494 $result['SHIPMENT'] = null;
495 if ($this->shipment instanceof $shipmentClassName)
496 $result['SHIPMENT'] = $this->shipment->getShipmentCode();
497 unset($shipmentClassName);
498
499 return $result;
500 }
501
507 protected function resetPrices()
508 {
509 parent::resetPrices();
510 $this->resetDeliveryPrices();
511 }
512
518 protected function resetDeliveryPrices()
519 {
520 if ($this->orderData['CUSTOM_PRICE_DELIVERY'] !== 'N')
521 return;
522 $this->orderData['PRICE_DELIVERY'] = $this->orderData['BASE_PRICE_DELIVERY'];
523 $this->orderData['PRICE_DELIVERY_DIFF'] = 0;
524 }
525
531 protected function loadOrderData()
532 {
533 $result = parent::loadOrderData();
534 if (!$result->isSuccess())
535 return $result;
536
537 if (!$this->isShipmentExists())
538 {
539 $this->shipmentIds = [];
540 $shipmentResult = $this->loadShipment();
541 if (!$shipmentResult->isSuccess())
542 {
543 $result->addErrors($shipmentResult->getErrors());
544 return $result;
545 }
546 unset($shipmentResult);
547 }
548 $this->fillShipmentData();
549
550 return $result;
551 }
552
558 protected function fillEmptyOrderData()
559 {
560 parent::fillEmptyOrderData();
561 $this->orderData += [
562 'BASE_PRICE_DELIVERY' => 0,
563 'PRICE_DELIVERY' => 0,
564 'PRICE_DELIVERY_DIFF' => 0,
565 'DELIVERY_ID' => 0,
566 'CUSTOM_PRICE_DELIVERY' => 'N',
567 'SHIPMENT_CODE' => 0,
568 'SHIPMENT_ID' => 0,
569 'PAY_SYSTEM_ID' => 0
570 ];
571
572 if ($this->isOrderExists())
573 {
575 $order = $this->getOrder();
576
577 $this->orderData['PAY_SYSTEM_ID'] = null;
578 $paymentCollection = $order->getPaymentCollection();
580 foreach ($paymentCollection as $payment)
581 {
582 if ($payment->isInner())
583 continue;
584 if (!isset($this->orderData['PAY_SYSTEM_ID']))
585 {
586 $this->orderData['PAY_SYSTEM_ID'] = (int)$payment->getPaymentSystemId();
587 break;
588 }
589 }
590 unset($payment, $paymentCollection);
591 if (!isset($this->orderData['PAY_SYSTEM_ID']))
592 $this->orderData['PAY_SYSTEM_ID'] = 0;
593
594 unset($order);
595 }
596 }
597
604 protected function loadBasket()
605 {
606 $result = parent::loadBasket();
607 if (!$result->isSuccess())
608 return $result;
609
610 if ($this->isBasketNotEmpty())
611 {
613 $basket = $this->getBasket();
615 foreach ($basket as $basketItem)
616 {
617 if (
618 !$basketItem->canBuy()
619 || !$basketItem->isBundleParent()
620 )
621 continue;
622
623 $bundle = $basketItem->getBundleCollection();
624 if ($bundle->count() == 0)
625 {
626 $result->addError(new Main\Entity\EntityError(
627 Loc::getMessage('BX_SALE_DISCOUNT_ERR_BASKET_BUNDLE_EMPTY'),
628 self::ERROR_ID
629 ));
630 break;
631 }
633 foreach ($bundle as $bundleItem)
634 {
635 $item = $this->getBasketItemFields($bundleItem);
636 $item['IN_SET'] = 'Y';
637 $this->orderData['BASKET_ITEMS'][$bundleItem->getBasketCode()] = $item;
638 }
639 unset($item, $bundle, $bundleItem);
640 }
641 unset($basketItem);
642 }
643
644 return $result;
645 }
646
652 protected function loadDefaultOrderConfig()
653 {
654 parent::loadDefaultOrderConfig();
655
656 $this->shipment = null;
657
659 }
660
665 protected function applyLoadedOrderConfig(array $data)
666 {
667 parent::applyLoadedOrderConfig($data);
668
669 if (isset($data['OLD_ORDER']))
670 $this->setValidState(false);
671
673 $order = $this->getOrder();
674 if (!empty($data['DELIVERY']))
675 {
676 $delivery = $data['DELIVERY'];
677 $this->orderData['DELIVERY_ID'] = $delivery['DELIVERY_ID'];
678 if (isset($delivery['CUSTOM_PRICE_DELIVERY']))
679 $this->orderData['CUSTOM_PRICE_DELIVERY'] = $delivery['CUSTOM_PRICE_DELIVERY'];
680 if (isset($delivery['SHIPMENT_ID']))
681 {
682 $delivery['SHIPMENT_ID'] = (int)$delivery['SHIPMENT_ID'];
683 if ($delivery['SHIPMENT_ID'] > 0)
684 {
685 $this->shipmentIds[] = $delivery['SHIPMENT_ID'];
687 $orderShipmentList = $order->getShipmentCollection();
688 $this->shipment = $orderShipmentList->getItemById($delivery['SHIPMENT_ID']);
689 if (empty($this->shipment))
690 {
691 $this->shipment = null;
692 $this->shipmentIds = array();
693 }
694 }
695 }
696 unset($delivery);
697 }
698
700 }
701
707 protected function isShipmentExists()
708 {
709 $shipmentClassName = $this->getShipmentClassName();
710 return ($this->shipment instanceof $shipmentClassName);
711 }
712
718 protected function fillShipmentData()
719 {
720 if (!$this->isShipmentExists())
721 return;
722
723 $this->orderData['DELIVERY_ID'] = $this->shipment->getDeliveryId();
724 $this->orderData['CUSTOM_PRICE_DELIVERY'] = ($this->shipment->isCustomPrice() ? 'Y' : 'N');
725 $this->orderData['BASE_PRICE_DELIVERY'] = $this->shipment->getField('BASE_PRICE_DELIVERY');
726 $this->orderData['PRICE_DELIVERY'] = $this->shipment->getPrice();
727 $this->orderData['PRICE_DELIVERY_DIFF'] = $this->shipment->getField('DISCOUNT_PRICE');
728 $this->orderData['SHIPMENT_CODE'] = $this->shipment->getShipmentCode();
729 $this->orderData['SHIPMENT_ID'] = (int)$this->shipment->getId();
730 }
731
737 protected function loadShipment()
738 {
739 $result = new Result;
740 if (!$this->isOrderExists())
741 return $result;
742 if (!$this->isShipmentExists())
743 {
744 $loadDelivery = false;
746 $order = $this->getOrder();
748 $orderShipmentList = $order->getShipmentCollection();
750 if ($this->isOrderNew())
751 {
752 foreach ($orderShipmentList as $shipment)
753 {
754 if ($shipment->isSystem())
755 continue;
756
757 if (!$loadDelivery)
758 {
759 $this->shipment = $shipment;
760 $loadDelivery = true;
761 break;
762 }
763 }
764 }
765 else
766 {
767 $shipmentId = false;
768 foreach ($orderShipmentList as $shipment)
769 {
770 if ($shipment->isSystem())
771 continue;
772
773 $currentShipmentId = (int)$shipment->getId();
774 if ($shipmentId === false || $shipmentId > $currentShipmentId)
775 $shipmentId = $currentShipmentId;
776 }
777 unset($currentShipmentId, $shipment);
778 if (!empty($shipmentId))
779 {
780 $this->shipment = $orderShipmentList->getItemById($shipmentId);
781 $loadDelivery = true;
782 }
783 unset($shipmentId);
784 }
785 unset($loadDelivery);
786 }
787 return $result;
788 }
789
795 protected function initInstanceFromOrder()
796 {
797 parent::initInstanceFromOrder();
798 $this->loadShipment();
799 $this->fillShipmentData();
800 }
801
802 /* entities id tools */
803
810 protected function getEntitySaveIdentifier(array $entity)
811 {
812 $result = null;
813
814 switch ($entity['ENTITY_TYPE'])
815 {
816 case self::ENTITY_DELIVERY:
817 $result = [
818 'ENTITY_TYPE' => self::ENTITY_DELIVERY,
819 'ENTITY_ID' => (int)$entity['ENTITY_CODE'],
820 'ENTITY_VALUE' => (string)$entity['ENTITY_CODE']
821 ];
822 break;
823 default:
824 $result = parent::getEntitySaveIdentifier($entity);
825 break;
826 }
827
828 return $result;
829 }
830
831 /* entities id tools finish */
832
833 /* compatibility tools */
839 private function isUsedDiscountCompatibility()
840 {
841 return (Compatible\DiscountCompatibility::isUsed() && Compatible\DiscountCompatibility::isInited());
842 }
843
849 protected function fillCompatibleOrderFields()
850 {
851 $this->orderData['USE_BASE_PRICE'] = $this->saleOptions['USE_BASE_PRICE'];
852 }
853
854 /* compatibility tools finish */
855
856 /* deprecated methods */
857
867 public function setBasketItemBasePrice($code, $price, $currency) {}
868
876 public function setBasketBasePrice($basket) {}
877
885 public function getBasketItemBasePrice($code)
886 {
887 return (isset($this->orderData[$code]) ? $this->orderData[$code]['BASE_PRICE'] : null);
888 }
889
898 public function setBasketItemDiscounts($code, $discountList) {}
899
908 public function setBasketItemData($code, $providerData) {}
909
917 public function clearBasketItemData($code) {}
918
928 public static function loadByBasket(Basket $basket)
929 {
930 $order = $basket->getOrder();
931 if ($order instanceof Order)
932 return static::buildFromOrder($order);
933
934 return self::buildFromBasket($basket, new Context\Fuser($basket->getFUserId(true)));
935 }
936
946 public static function load(Order $order)
947 {
948 return static::buildFromOrder($order);
949 }
950
959 public function saveExternalLastApplyblock(BasketItem $basketItem, $orderDiscountId)
960 {
962 $basket = $basketItem->getCollection();
963 $this->order = $basket->getOrder();
964
965 $this->loadOrderData();
966
967 $listItems[$basketItem->getBasketCode()] = array('APPLY'=>'Y', 'ACTION_BLOCK_LIST'=>array(), 'DESCR_DATA'=>array(), 'DESCR'=>array());
968
969 $this->discountsCache[$orderDiscountId]['MODULE_ID'] = 'sale';
970 $applyBlock = &$this->discountResult['APPLY_BLOCKS'][$this->discountResultCounter];
971 $applyBlock['ORDER'][] = array(
972 'DISCOUNT_ID' => $orderDiscountId,
973 'COUPON_ID' => 0,
974 'RESULT' => array('BASKET' => $listItems)
975 );
976
977 $this->saveLastApplyBlock();
978 }
979
987 protected function getBasketCurrency($basketCode)
988 {
989 return $this->getCurrency();
990 }
991
992 /* deprecated methods finish */
993}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static formatList(array $actionList)
getBasketItemFields(BasketItemBase $basketItem)
static getInstanceIndexByFuser($fuser, $site)
Definition discount.php:264
setBasketItemDiscounts($code, $discountList)
Definition discount.php:898
getBasketCurrency($basketCode)
Definition discount.php:987
setBasketItemData($code, $providerData)
Definition discount.php:908
getEntitySaveIdentifier(array $entity)
Definition discount.php:810
static loadByBasket(Basket $basket)
Definition discount.php:928
getApplyResult($extMode=false)
Definition discount.php:150
static load(Order $order)
Definition discount.php:946
setApplyResult($applyResult)
Definition discount.php:126
setCalculateShipments(Shipment $shipment=null)
Definition discount.php:81
setBasketBasePrice($basket)
Definition discount.php:876
static loadByFuser($fuser, $site)
Definition discount.php:56
static getStepResult(array $order)
Definition discount.php:303
setBasketItemBasePrice($code, $price, $currency)
Definition discount.php:867
static getRegistryType()
Definition discount.php:70
getBasketItemBasePrice($code)
Definition discount.php:885