Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
basketbuilder.php
1<?
3
20
26abstract class BasketBuilder
27{
28 const BASKET_CODE_NEW = 'new';
29
31 protected $delegate = null;
33 protected $builder = null;
35 protected $maxBasketCodeIdx = 0;
37 protected $formData = [];
39 protected $needDataUpdate = array();
41 protected $basketCodeMap = [];
43 protected $cacheProductProviderData = false;
45 protected $catalogProductsIds = [];
47 protected $catalogProductsData = [];
49 protected $providerData = [];
51 protected $trustData = [];
53 protected $isProductAdded = false;
54
56 {
57 $this->builder = $builder;
58 $this->cacheProductProviderData = $this->builder->getSettingsContainer()->getItemValue('cacheProductProviderData');
59 }
60
61 public function initBasket()
62 {
63 $this->formData = $this->builder->getFormData();
64 $this->delegate = $this->getDelegate($this->formData['ID']);
65 \Bitrix\Sale\ProviderBase::setUsingTrustData(true);
66 return $this;
67 }
68
73 protected function getDelegate($orderId)
74 {
75 return (int)$orderId > 0 ? new BasketBuilderExist($this) : new BasketBuilderNew($this);
76 }
77
82 {
83 return $this->builder->getSettingsContainer()->getItemValue('needUpdateNewProductPrice');
84 }
85
86 public function checkProductData(array $productData)
87 {
88 $result = true;
89
90 if((float)$productData['QUANTITY'] <= 0)
91 {
92 $this->getErrorsContainer()->addError(
93 new Error(
95 "SALE_HLP_ORDERBUILDER_QUANTITY_ERROR",
96 ['#PRODUCT_NAME#' => $productData['NAME']]
97 )));
98
99 $result = false;
100 }
101
102 if((int)$productData['PRICE'] < 0)
103 {
104 $this->getErrorsContainer()->addError(
105 new Error(
107 "SALE_HLP_ORDERBUILDER_PRICE_ERROR",
108 ['#PRODUCT_NAME#' => $productData['NAME']]
109 )));
110
111 $result = false;
112 }
113
114 return $result;
115 }
116
118 {
119 foreach($this->formData["PRODUCT"] as $basketCode => $productData)
120 {
121 if(!$this->checkProductData($productData))
122 {
123 throw new BuildingException();
124 }
125
126 if(self::isBasketItemNew($basketCode))
127 {
128 $basketInternalId = intval(mb_substr($basketCode, 1));
129
130 if($basketInternalId > $this->maxBasketCodeIdx)
131 $this->maxBasketCodeIdx = $basketInternalId;
132
133 // by the way let's mark rows for update data if need
134 if($this->isNeedUpdateNewProductPrice()) //???is it right for edit orders
135 {
136 $this->needDataUpdate[] = $basketCode; //???is it needed by new orders
137 unset($this->formData["PRODUCT"][$basketCode]["PROVIDER_DATA"]);
138 unset($this->formData["PRODUCT"][$basketCode]["SET_ITEMS_DATA"]);
139 }
140 }
141 }
142
143 /*
144 * Because of one of discounts, require that the first product must be the most expencsve.
145 * If we want to save the sorting of the products we must use field "SORT" - fill it earlier
146 * and use it during layout.
147 */
148
149 sortByColumn($this->formData["PRODUCT"], array("BASE_PRICE" => SORT_DESC, "PRICE" => SORT_DESC), '', null, true);
150 return $this;
151 }
152
156 protected function getExistsItem($moduleId, $productId, array $properties = array())
157 {
158 return $this->getBasket()->getExistsItem($moduleId, $productId, $properties);
159 }
160
161 public function removeDeletedItems()
162 {
163 $deleteBasketItemsIfNotExists = $this->builder->getSettingsContainer()->getItemValue('deleteBasketItemsIfNotExists');
164 $itemsBasketCodes = [];
165
166 foreach($this->formData["PRODUCT"] as $basketCode => $productData)
167 {
168 if (!isset($productData["PROPS"]))
169 {
170 $productData["PROPS"] = array();
171 }
172
173 $item = null;
174 if ($basketCode != \Bitrix\Sale\Helpers\Admin\OrderEdit::BASKET_CODE_NEW)
175 {
176 $item = $this->getBasket()->getItemByBasketCode($basketCode);
177 }
178
179 if ($item == null && $deleteBasketItemsIfNotExists)
180 {
182 }
183
184 if($item && $item->isBundleChild())
185 {
186 continue;
187 }
188
189 if(!$item)
190 {
191 continue;
192 }
193
194 $itemsBasketCodes[] = $item->getBasketCode();
195 }
196
198 $basketItems = $this->getBasket()->getBasketItems();
199
200 foreach($basketItems as $item)
201 {
202 if(!in_array($item->getBasketCode(), $itemsBasketCodes))
203 {
204 if ($deleteBasketItemsIfNotExists)
205 {
206 $itemDeleteResult = $item->delete();
207
208 if (!$itemDeleteResult->isSuccess())
209 {
210 $this->builder->getErrorsContainer()->addErrors($itemDeleteResult->getErrors());
211 throw new BuildingException();
212 }
213 }
214 elseif ($this->getSettingsContainer()->getItemValue('clearReservesIfEmpty') === true)
215 {
216 $this->clearReservesForItem($item);
217 }
218 }
219 }
220
221 return $this;
222 }
223
224 public function itemsDataPreparation()
225 {
226 foreach($this->formData["PRODUCT"] as $basketCode => $productData)
227 {
228 if (isset($productData["IS_SET_ITEM"]) && $productData["IS_SET_ITEM"] === "Y")
229 {
230 continue;
231 }
232
233 if(!isset($productData["PROPS"]) || !is_array($productData["PROPS"]))
234 $productData["PROPS"] = array();
235
237 $item = $this->getItemFromBasket($basketCode, $productData);
238
239 if($item)
240 {
241 $this->setItemData($basketCode, $productData, $item);
242 }
243 else
244 {
245 $item = $this->createItem($basketCode, $productData);
246
247 if(!$this->isProductAdded)
248 {
249 $this->isProductAdded = true;
250 }
251 }
252
253 /*
254 * Could be deleted and than added one more time product.
255 * Or just added product.
256 */
257 if($basketCode != $item->getBasketCode())
258 $this->basketCodeMap[$basketCode] = $item->getBasketCode();
259
260 if(!empty($productData["PROPS"]) && is_array($productData["PROPS"]))
261 {
263 $property = $item->getPropertyCollection();
264 if(!$property->isPropertyAlreadyExists($productData["PROPS"]))
265 {
266 $property->setProperty($productData["PROPS"]);
267 }
268 }
269 }
270
271 return $this;
272 }
273
274 public function basketCodeMap()
275 {
276 if(!empty($this->basketCodeMap))
277 {
278 foreach($this->basketCodeMap as $old => $new)
279 {
280 $this->formData['PRODUCT'][$new] = $this->formData['PRODUCT'][$old];
281 unset($this->formData['PRODUCT'][$old]);
282 }
283 }
284
285 return $this;
286 }
287
288 // Preparing fields needed by provider
289 protected function setItemsFieldsByFormData()
290 {
292 $basketItems = $this->getBasket()->getBasketItems();
293
294 foreach($basketItems as $item)
295 {
296 $basketCode = $item->getBasketCode();
297
298 if(empty($this->formData['PRODUCT'][$basketCode]))
299 continue;
300
301 $productData = $this->formData['PRODUCT'][$basketCode];
302 $isProductDataNeedUpdate = in_array($basketCode, $this->needDataUpdate);
303
304 if(isset($productData["PRODUCT_PROVIDER_CLASS"]) && $productData["PRODUCT_PROVIDER_CLASS"] <> '')
305 {
306 $item->setField("PRODUCT_PROVIDER_CLASS", trim($productData["PRODUCT_PROVIDER_CLASS"]));
307 }
308
309 /*
310 * Let's extract cached provider product data from field
311 * in case activity is through ajax.
312 */
313 if($this->cacheProductProviderData && !$isProductDataNeedUpdate)
314 {
315 self::sendProductCachedDataToProvider($item, $this->getOrder(), $productData);
316 }
317
318 if (isset($productData['NAME']))
319 {
320 $item->setField('NAME', $productData['NAME']);
321 }
322
323 $item->setField('TYPE', $productData['TYPE'] ?? null);
324
325 if (isset($productData['CUSTOM_PRICE']) && $productData['CUSTOM_PRICE'] === 'Y')
326 {
327 $item->markFieldCustom('PRICE');
328 }
329
330 $res = $item->setField("QUANTITY", $productData["QUANTITY"]);
331
332 if(!$res->isSuccess())
333 {
334 $this->getErrorsContainer()->addErrors($res->getErrors());
335 throw new BuildingException();
336 }
337
338 if (isset($productData['VAT_RATE']))
339 {
340 $item->markFieldCustom('VAT_RATE');
341 $item->setField('VAT_RATE', $productData['VAT_RATE']);
342 }
343
344 if (isset($productData['VAT_INCLUDED']))
345 {
346 $item->markFieldCustom('VAT_INCLUDED');
347 $item->setField('VAT_INCLUDED', $productData['VAT_INCLUDED']);
348 }
349
350 if(isset($productData["MODULE"]) && $productData["MODULE"] == "catalog")
351 {
352 $this->catalogProductsIds[] = $item->getField('PRODUCT_ID');
353 }
354 elseif(empty($productData["PRODUCT_PROVIDER_CLASS"]))
355 {
356 $availableFields = BasketItemBase::getAvailableFields();
357 $availableFields = array_fill_keys($availableFields, true);
358 $fillFields = array_intersect_key($productData, $availableFields);
359
360 $orderCurrency = $this->getOrder()->getCurrency();
361 if (
362 isset($fillFields['CURRENCY'])
363 && $fillFields['CURRENCY'] !== $orderCurrency
364 )
365 {
366 $fillFields['PRICE'] = \CCurrencyRates::ConvertCurrency(
367 (float)$fillFields['PRICE'],
368 $fillFields['CURRENCY'],
369 $orderCurrency
370 );
371 $fillFields['BASE_PRICE'] = \CCurrencyRates::ConvertCurrency(
372 (float)$fillFields['BASE_PRICE'],
373 $fillFields['CURRENCY'],
374 $orderCurrency
375 );
376 $fillFields['CURRENCY'] = $orderCurrency;
377 }
378
379 if (!empty($fillFields))
380 {
381 $r = $item->setFields($fillFields);
382
383 if(!$r->isSuccess())
384 {
385 $this->getErrorsContainer()->getErrors($r->addErrors());
386 }
387 }
388 }
389 }
390 }
391
392 protected function obtainCatalogProductsData(array $fields = array())
393 {
394 if(empty($this->catalogProductsIds))
395 return;
396
397 $order = $this->getOrder();
398 //$this->catalogProductsIds = array();
399
400 foreach($this->catalogProductsIds as $id)
401 {
402 $details = OrderEdit::getProductDetails($id, $order->getUserId(), $order->getSiteId());
403
404 if($details !== false)
405 $this->catalogProductsData[$id] = $details;
406 }
407
408 $noCachedProductIds = array_diff($this->catalogProductsIds, array_keys($this->catalogProductsData));
409
410 if(!empty($noCachedProductIds))
411 {
412 $noCachedData = \Bitrix\Sale\Helpers\Admin\Product::getData($noCachedProductIds, $order->getSiteId(), array_keys($fields));
413
414 foreach($noCachedData as $productId => $productData)
415 {
416 $this->catalogProductsData[$productId] = $productData;
417 OrderEdit::setProductDetails($productId, $order->getUserId(), $order->getSiteId(), $this->catalogProductsData[$productId]);
418 }
419
420 $emptyData = array_diff($this->catalogProductsIds, array_keys($this->catalogProductsData));
421
422 foreach($emptyData as $productId)
423 $this->catalogProductsData[$productId] = array();
424 }
425 }
426
427 protected function obtainProviderProductsData()
428 {
429 $order = $this->getOrder();
430 $basketItems = $this->getBasket()->getBasketItems();
431
432 if($this->cacheProductProviderData && empty($this->needDataUpdate) && !$this->isNeedUpdateNewProductPrice())
433 return;
434
435 $params = array("AVAILABLE_QUANTITY");
436
437 if($order->getId() <= 0)
438 $params[] = "PRICE";
439
440 $this->providerData = Provider::getProductData($this->getBasket(), $params);
441
443 foreach($basketItems as $item)
444 {
445 $basketCode = $item->getBasketCode();
446
447 if($order->getId() <= 0 && !empty($this->providerData[$basketCode]) && empty($this->providerData[$basketCode]['QUANTITY']))
448 {
449
450 $this->getErrorsContainer()->addError(
451 new Error(
453 "SALE_ORDEREDIT_PRODUCT_QUANTITY_IS_EMPTY",
454 array(
455 "#NAME#" => $item->getField('NAME')
456 )
457 ),
458 'SALE_ORDEREDIT_PRODUCT_QUANTITY_IS_EMPTY'
459 )
460 );
461
462 throw new BuildingException();
463 }
464 }
465 }
466
467 protected function isProductAvailable($basketCode, $productFormData, $productProviderData, $isProductDataNeedUpdate)
468 {
469 $result = true;
470
471 if($this->getOrder()->getId() <= 0 && (empty($productProviderData[$basketCode]) || !$this->cacheProductProviderData || $isProductDataNeedUpdate))
472 {
473 if(empty($productProviderData[$basketCode]) && $productFormData["PRODUCT_PROVIDER_CLASS"] <> '')
474 {
475 $result = false;
476 }
477 }
478
479 return $result;
480 }
481
482 //todo: \Bitrix\Catalog\Product\Basket::addProductToBasket()
483 public function setItemsFields()
484 {
485 $order = $this->getOrder();
486 $basketItems = $this->getBasket()->getBasketItems();
487
488 $this->setItemsFieldsByFormData();
490 $this->obtainProviderProductsData();
491
492 $productProviderData = array();
493
495 foreach($basketItems as $item)
496 {
497 $basketCode = $item->getBasketCode();
498 $productFormData = $this->formData['PRODUCT'][$basketCode] ?? [];
499 $isProductDataNeedUpdate = in_array($basketCode, $this->needDataUpdate);
500 $productProviderData[$basketCode] = $item->getFieldValues();
501
502 if(empty($productFormData))
503 continue;
504
505 if(!empty($this->providerData[$basketCode]))
506 {
507 if ($this->builder->getSettingsContainer()->getItemValue('isRefreshData') === true)
508 {
509 unset($this->providerData[$basketCode]['QUANTITY']);
510 }
511
512 $productProviderData[$basketCode] = $this->providerData[$basketCode];
513 }
514 elseif(!empty($trustData[$basketCode]))
515 {
516 $productProviderData[$basketCode] = $trustData[$basketCode];
517 }
518 else
519 {
520 $productProviderData = Provider::getProductData($this->getBasket(), array("PRICE", "AVAILABLE_QUANTITY"), $item);
521
522 if(is_array($productProviderData[$basketCode]) && !empty($productProviderData[$basketCode]))
523 OrderEdit::setProviderTrustData($item, $order, $productProviderData[$basketCode]);
524 }
525
526 /* Get actual info from provider
527 * cases:
528 * 1) add new product to basket;
529 * 2) saving operation;
530 * 3) changing quantity;
531 * 4) changing buyerId
532 */
533
534 if(!$this->isProductAvailable($basketCode, $productFormData, $productProviderData, $isProductDataNeedUpdate))
535 {
536 $this->getErrorsContainer()->addError(
537 new Error(
539 "SALE_HLP_ORDERBUILDER_PRODUCT_NOT_AVILABLE",
540 array(
541 "#NAME#" => $productFormData["NAME"] . (!empty($productFormData["PRODUCT_ID"]) ? " (".$productFormData['PRODUCT_ID'].")" : "")
542 )
543 )
544 )
545 );
546 }
547
548 $product = array();
549
550 //merge catalog data
551 if($item->getField("MODULE") == "catalog")
552 {
553 if(!empty($catalogData[$item->getProductId()]))
554 {
555 $product = array_merge($product, $catalogData[$item->getProductId()]);
556 unset($productFormData["CURRENCY"]);
557 }
558 }
559
560 //merge form data
561 if(!$this->cacheProductProviderData || $isProductDataNeedUpdate)
562 {
563 $product = array_merge($productFormData, $product);
564 }
565 else
566 {
567 $basePrice = (float)($productFormData['BASE_PRICE'] ?? 0);
568 $price = (float)($productFormData['PRICE'] ?? 0);
569
570 $needUpdateItemPrice = $this->isNeedUpdateNewProductPrice() && $this->isBasketItemNew($basketCode);
571 $isPriceCustom = isset($productFormData['CUSTOM_PRICE']) && $productFormData['CUSTOM_PRICE'] == 'Y';
572
573 if ($isPriceCustom)
574 {
575 $productFormData['DISCOUNT_PRICE'] = 0;
576 if ($basePrice > $price)
577 {
578 $productFormData['DISCOUNT_PRICE'] = $basePrice - $price;
579 }
580 }
581
582 if (($order->getId() === 0 && !$isPriceCustom) || $needUpdateItemPrice)
583 {
584 unset($productFormData['PRICE'], $productFormData['PRICE_BASE'], $productFormData['BASE_PRICE']);
585 }
586
587 $product = array_merge($product, $productFormData);
588 }
589
590 if (isset($product["OFFER_ID"]) && intval($product["OFFER_ID"]) > 0)
591 {
592 $product["PRODUCT_ID"] = $product["OFFER_ID"];
593 }
594
595 //discard BasketItem redundant fields
596 $product = array_intersect_key($product, array_flip($item::getAvailableFields()));
597
598 if (isset($product["MEASURE_CODE"]) && $product["MEASURE_CODE"] <> '')
599 {
600 $measures = OrderBasket::getCatalogMeasures();
601
602 if (!empty($measures[$product["MEASURE_CODE"]]))
603 {
604 $product["MEASURE_NAME"] = $measures[$product["MEASURE_CODE"]];
605 }
606 }
607
608 if (empty($product["CURRENCY"]))
609 {
610 $product["CURRENCY"] = $order->getCurrency();
611 }
612
613 if (
614 isset($productFormData["IS_SET_PARENT"])
615 && $productFormData["IS_SET_PARENT"] === "Y"
616 )
617 {
618 $product["TYPE"] = BasketItem::TYPE_SET;
619 }
620
622 $productFormData["OFFER_ID"],
623 $order->getUserId(),
624 $order->getSiteId(),
625 array_merge($product, $productFormData)
626 );
627
628 if ($product["CURRENCY"] !== $order->getCurrency())
629 {
630 $product["PRICE"] = \CCurrencyRates::ConvertCurrency($product["PRICE"], $product["CURRENCY"], $order->getCurrency());
631 if ($product["BASE_PRICE"] > 0)
632 {
633 $product["BASE_PRICE"] = \CCurrencyRates::ConvertCurrency($product["BASE_PRICE"], $product["CURRENCY"], $order->getCurrency());
634 }
635 if ($product["DISCOUNT_PRICE"] > 0)
636 {
637 $product["DISCOUNT_PRICE"] = \CCurrencyRates::ConvertCurrency($product["DISCOUNT_PRICE"], $product["CURRENCY"], $order->getCurrency());
638 }
639 if ($product["VAT_RATE"] > 0)
640 {
641 $product["VAT_RATE"] = \CCurrencyRates::ConvertCurrency($product["VAT_RATE"], $product["CURRENCY"], $order->getCurrency());
642 }
643
644 $product["CURRENCY"] = $order->getCurrency();
645 }
646
647 $this->setBasketItemFields($item, $product);
648
649 if ($item->isReservableItem())
650 {
651 if (!empty($productFormData['RESERVE']) && is_array($productFormData['RESERVE']))
652 {
653 $reserveData = $productFormData['RESERVE'];
654 $this->setReserveDataForItem($item, $reserveData);
655 }
656 elseif ($this->getSettingsContainer()->getItemValue('clearReservesIfEmpty') === true)
657 {
658 $this->clearReservesForItem($item);
659 }
660 }
661 }
662
663 return $this;
664 }
665
666 protected function clearReservesForItem(BasketItem $item)
667 {
668 if (!$item->isReservableItem())
669 {
670 return;
671 }
672
674 $reserveCollection = $item->getReserveQuantityCollection();
675 if ($reserveCollection)
676 {
677 $reserveCollection->clearCollection();
678 }
679 }
680
681 protected function setReserveDataForItem(BasketItem $item, array $reserveData)
682 {
683 if (!$item->isReservableItem())
684 {
685 return;
686 }
687
688 $reserveCollection = $item->getReserveQuantityCollection();
689 if (!$reserveCollection)
690 {
691 return;
692 }
693
694 // if some reserves were created upon order creation, we have to clear them and set the manual reserves
695 if ($this->getOrder()->isNew())
696 {
697 $this->clearReservesForItem($item);
698 }
699
700 foreach ($reserveData as $reserveCode => $reserve)
701 {
702 $isNewReserve = mb_strpos($reserveCode, 'n') === 0;
703 if ($isNewReserve)
704 {
705 $reserveCollectionItem = $reserveCollection->create();
706 }
707 else
708 {
709 $reserveCollectionItem = $reserveCollection->getItemById($reserveCode);
710 if (!$reserveCollectionItem)
711 {
712 continue;
713 }
714 }
715
716 if (isset($reserve['STORE_ID']) && (int)$reserve['STORE_ID'] !== $reserveCollectionItem->getStoreId())
717 {
718 if (!$isNewReserve)
719 {
720 // drop the old reserve and create a new one instead since we can't just change the store id like that
721 $deleteResult = $reserveCollectionItem->delete();
722 if (!$deleteResult->isSuccess())
723 {
724 $this->getErrorsContainer()->addErrors($deleteResult->getErrors());
725 continue;
726 }
727
728 $reserveCollectionItem = $reserveCollection->create();
729 }
730
731 $reserveCollectionItem->setStoreId((int)$reserve['STORE_ID']);
732 }
733
734 if (isset($reserve['QUANTITY']))
735 {
736 $quantity = (float)$reserve['QUANTITY'];
737 if ($quantity < 0)
738 {
739 $quantity = 0;
740 }
741 $reserveCollectionItem->setQuantity($quantity);
742 }
743
744 if (isset($reserve['DATE_RESERVE_END']) && $reserve['DATE_RESERVE_END'] !== '')
745 {
746 $dateReserveEnd = new Date($reserve['DATE_RESERVE_END']);
747 $reserveCollectionItem->setField('DATE_RESERVE_END', $dateReserveEnd);
748 }
749
750 if (isset($reserve['RESERVED_BY']))
751 {
752 $reserveCollectionItem->setField('RESERVED_BY', $reserve['RESERVED_BY']);
753 }
754 }
755 }
756
757 public function getOrder()
758 {
759 return $this->builder->getOrder();
760 }
761
762 public function getSettingsContainer()
763 {
764 return $this->builder->getSettingsContainer();
765 }
766
767 public function getErrorsContainer()
768 {
769 return $this->builder->getErrorsContainer();
770 }
771
772 public function getFormData()
773 {
774 return $this->formData;
775 }
776
777 public function getBasket()
778 {
779 return $this->builder->getOrder()->getBasket();
780 }
781
782 public static function isBasketItemNew($basketCode)
783 {
784 return (mb_strpos($basketCode, 'n') === 0) && ($basketCode != self::BASKET_CODE_NEW);
785 }
786
787 protected function getItemFromBasket($basketCode, $productData)
788 {
790 $item = $this->delegate->getItemFromBasket($basketCode, $productData);
791
792 if($item && $item->isBundleChild())
793 $item = null;
794
795 return $item;
796 }
797
798 protected function setItemData($basketCode, &$productData, &$item)
799 {
800 return $this->delegate->setItemData($basketCode, $productData, $item);
801 }
802
803 protected function createItem($basketCode, &$productData)
804 {
805 //todo: is it stil working?
806 if($basketCode != self::BASKET_CODE_NEW)
807 $setBasketCode = $basketCode;
808 elseif(intval($this->maxBasketCodeIdx) > 0)
809 $setBasketCode = 'n'.strval($this->maxBasketCodeIdx+1); //Fix collision part 2.
810 else
811 $setBasketCode = null;
812
813 $item = $this->getBasket()->createItem(
814 $productData["MODULE"] ?? '',
815 $productData["OFFER_ID"],
816 $setBasketCode
817 );
818
819 if ($basketCode != $productData["BASKET_CODE"])
820 $productData["BASKET_CODE"] = $item->getBasketCode();
821
822 if($basketCode == self::BASKET_CODE_NEW)
823 {
824 //$result->setData(array("NEW_ITEM_BASKET_CODE" => $productData["BASKET_CODE"]));
825 $this->needDataUpdate[] = $item->getBasketCode();
826 }
827
828 if(!empty($productData['REPLACED']) && $productData['REPLACED'] == 'Y')
829 $this->needDataUpdate[] = $item->getBasketCode();
830
831 return $item;
832 }
833
834 public static function getCatalogMeasures()
835 {
836 static $result = null;
837 $catalogIncluded = null;
838
839 if(!is_array($result))
840 {
841 $result = array();
842
843 if ($catalogIncluded === null)
844 {
845 $catalogIncluded = Loader::includeModule('catalog');
846 }
847
848 if ($catalogIncluded)
849 {
850 $dbList = \CCatalogMeasure::getList();
851
852 while($arList = $dbList->Fetch())
853 {
854 $result[$arList["CODE"]] = ($arList["SYMBOL_RUS"] != '' ? $arList["SYMBOL_RUS"] : $arList["SYMBOL_INTL"]);
855 }
856 }
857
858 if (empty($result))
859 {
860 $result[796] = GetMessage("SALE_ORDER_BASKET_SHTUKA");
861 }
862 }
863
864 return $result;
865 }
866
867 public function sendProductCachedDataToProvider(BasketItem $item, Order $order, array &$productData)
868 {
869 if(empty($productData["PROVIDER_DATA"]) || !CheckSerializedData($productData["PROVIDER_DATA"]))
870 return;
871
872 $trustData = unserialize($productData["PROVIDER_DATA"], ['allowed_classes' => false]);
873
874 //quantity was changed so data must be changed
875 if(empty($trustData) || $trustData["QUANTITY"] == $productData["QUANTITY"])
876 return;
877
878 Provider::setTrustData($order->getSiteId(), $item->getField('MODULE'), $item->getProductId(), $trustData);
879
880 if ($item->isBundleParent())
881 {
882 if ($bundle = $item->getBundleCollection())
883 {
885 foreach ($bundle as $bundleItem)
886 {
887 $bundleItemData = $bundleItem->getFields()->getValues();
888 Provider::setTrustData($order->getSiteId(), $bundleItem->getField('MODULE'), $bundleItem->getProductId(), $bundleItemData);
889 }
890 }
891 }
892
893 $this->trustData[$item->getBasketCode()] = $trustData;
894 }
895
896 public function setBasketItemFields(\Bitrix\Sale\BasketItem &$item, array $fields = array())
897 {
898 $result = $item->setFields($fields);
899
900 if(!$result->isSuccess())
901 {
902 foreach($result->getErrors() as $error)
903 {
904 $containerErrors = $this->getErrorsContainer()->getErrors();
905
906 //avoid duplication
907 if(is_array($containerErrors) && !empty($containerErrors))
908 {
909 foreach($this->getErrorsContainer()->getErrors() as $existError)
910 {
911 if($error->getMessage() !== $existError->getMessage())
912 {
913 $this->getErrorsContainer()->addError($error);
914 }
915 }
916 }
917 else
918 {
919 $this->getErrorsContainer()->addError($error);
920 }
921 }
922
923 throw new BuildingException();
924 }
925 }
926
927 public function finalActions()
928 {
929 $this->delegate->finalActions();
930 return $this;
931 }
932
933 public function isProductAdded()
934 {
936 }
937
945 public function fillFUser()
946 {
947 $basket = $this->getBasket();
948 if ($basket && !$basket->getFUserId(true))
949 {
950 $fuserId = null;
951
952 $order = $this->getOrder();
953 if ($order && $order->getUserId())
954 {
955 $fuserId = Fuser::getUserIdById($order->getUserId());
956 }
957
958 $basket->setFUserId(
959 $fuserId ?: Fuser::getId(false)
960 );
961 }
962
963 return $this;
964 }
965}
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getId($skipCreate=false)
Definition fuser.php:33
static getUserIdById($fuserId)
Definition fuser.php:177
static getProductDetails($productId, $userId, $siteId)
static setProductDetails($productId, $userId, $siteId, array $params)
setBasketItemFields(\Bitrix\Sale\BasketItem &$item, array $fields=array())
isProductAvailable($basketCode, $productFormData, $productProviderData, $isProductDataNeedUpdate)
setReserveDataForItem(BasketItem $item, array $reserveData)
setItemData($basketCode, &$productData, &$item)
getExistsItem($moduleId, $productId, array $properties=array())
static getProductData(BasketItemCollection $basketCollection, array $select=array(), BasketItem $refreshItem=null)
static setTrustData($siteId, $module, $productId, array $fields)