34 private $isLoadForFUserId =
false;
48 isset($this->basketItemIndexMap[$code])
49 && isset($this->collection[$this->basketItemIndexMap[$code]])
52 return $this->collection[$this->basketItemIndexMap[$code]];
55 return parent::getItemByBasketCode($code);
71 private static function createBasketObject()
74 $basketClassName = $registry->getBasketClassName();
76 return new $basketClassName;
90 $basket = static::create(
$siteId);
94 $basket->isLoadForFUserId =
true;
97 return $basket->loadFromDb([
114 "ID",
"LID",
"MODULE",
"PRODUCT_ID",
"QUANTITY",
"WEIGHT",
115 "DELAY",
"CAN_BUY",
"PRICE",
"CUSTOM_PRICE",
"BASE_PRICE",
116 'PRODUCT_PRICE_ID',
'PRICE_TYPE_ID',
"CURRENCY",
'BARCODE_MULTI',
117 "RESERVED",
"RESERVE_QUANTITY",
"NAME",
"CATALOG_XML_ID",
118 "VAT_RATE",
"NOTES",
"DISCOUNT_PRICE",
"PRODUCT_PROVIDER_CLASS",
119 "CALLBACK_FUNC",
"ORDER_CALLBACK_FUNC",
"PAY_CALLBACK_FUNC",
120 "CANCEL_CALLBACK_FUNC",
"DIMENSIONS",
"TYPE",
"SET_PARENT_ID",
121 "DETAIL_PAGE_URL",
"FUSER_ID",
'MEASURE_CODE',
'MEASURE_NAME',
122 'ORDER_ID',
'DATE_INSERT',
'DATE_UPDATE',
'PRODUCT_XML_ID',
123 'SUBSCRIBE',
'RECOMMENDATION',
'VAT_INCLUDED',
'SORT',
124 'DATE_REFRESH',
'DISCOUNT_NAME',
'DISCOUNT_VALUE',
'DISCOUNT_COUPON',
125 'XML_ID',
'MARKING_CODE_GROUP'
131 $res = static::getList([
134 "order" => [
'SORT' =>
'ASC',
'ID' =>
'ASC'],
136 while ($item = $res->fetch())
145 $itemList[$item[
'ID']] = $item;
148 foreach ($itemList as $id => $item)
150 if ($item[
'SET_PARENT_ID'] > 0)
152 $itemList[$item[
'SET_PARENT_ID']][
'ITEMS'][$id] = &$itemList[$id];
157 foreach ($itemList as $id => $item)
159 if ($item[
'SET_PARENT_ID'] == 0)
161 $result[$id] = $item;
165 $this->loadFromArray($result);
198 $itemSort = (int)$item->
getField(
'SORT') ?: 100;
200 if ($this->maxItemSort ===
null)
202 $this->maxItemSort = $itemSort;
206 if ($itemSort > $this->maxItemSort)
208 $this->maxItemSort = $itemSort;
212 $this->maxItemSort += 100 + $this->maxItemSort % 100;
227 $basket = static::createBasketObject();
239 public function getPrice()
244 foreach ($this->collection as $basketItem)
246 $orderPrice += $basketItem->getFinalPrice();
258 public function getBasePrice()
263 foreach ($this->collection as $basketItem)
277 public function getVatSum()
282 foreach ($this->collection as $basketItem)
285 if ($basketItem->getQuantity() == 0)
290 $vatSum += $basketItem->getVat();
302 public function getVatRate()
307 foreach ($this->collection as $basketItem)
310 if ($basketItem->getQuantity() == 0)
315 if ($basketItem->getVatRate() > $vatRate)
317 $vatRate = $basketItem->getVatRate();
332 $result =
new Result();
335 foreach ($this->collection as $basketItem)
337 $r = $basketItem->verify();
338 if (!$r->isSuccess())
340 $result->addErrors($r->getErrors());
348 $entityMarker = $registry->getEntityMarkerClassName();
349 $entityMarker::addMarker(
$order, $basketItem, $r);
350 $order->setField(
'MARKED',
'Y');
363 public function getWeight()
368 foreach ($this->collection as $basketItem)
370 $orderWeight += $basketItem->getWeight() * $basketItem->getQuantity();
379 private function getOriginalItemsValues()
390 $filter[
'ORDER_ID'] =
$order->getId();
394 if ($this->isLoadForFUserId)
409 if (intval($userId) > 0)
421 $dbRes = static::getList(
423 "select" => array(
"ID",
'TYPE',
'SET_PARENT_ID',
'PRODUCT_ID',
'NAME',
'QUANTITY',
'FUSER_ID',
'ORDER_ID'),
428 while ($item = $dbRes->fetch())
430 if ((
int)$item[
'SET_PARENT_ID'] > 0 && (
int)$item[
'SET_PARENT_ID'] != $item[
'ID'])
435 $result[$item[
"ID"]] = $item;
457 public function save()
459 $this->checkCallingContext();
463 $this->isSaveExecuting =
true;
470 if (!$r->isSuccess())
472 return $result->addErrors($r->getErrors());
475 $r = $this->callEventOnSaleBasketBeforeSaved();
476 if (!$r->isSuccess())
478 $this->isSaveExecuting =
false;
480 return $result->addErrors($r->getErrors());
484 $originalItemsValues = $this->getOriginalItemsValues();
487 foreach ($this->collection as $basketItem)
489 $r = $basketItem->save();
490 if (!$r->isSuccess())
492 $result->addErrors($r->getErrors());
495 if (isset($originalItemsValues[$basketItem->getId()]))
497 unset($originalItemsValues[$basketItem->getId()]);
501 if ($originalItemsValues)
503 foreach ($originalItemsValues as $itemValues)
505 $this->callEventOnBeforeSaleBasketItemDeleted($itemValues);
515 $r = $this->callEventOnSaleBasketSaved();
516 if (!$r->isSuccess())
518 $result->addErrors($r->getErrors());
524 $this->isSaveExecuting =
false;
532 private function checkCallingContext() : void
538 && !
$order->isSaveRunning()
541 trigger_error(
"Incorrect call to the save process. Use method save() on \Bitrix\Sale\Order entity.", E_USER_WARNING);
549 private function callEventOnBeforeSaleBasketItemDeleted($itemValues)
551 $itemValues[
'ENTITY_REGISTRY_TYPE'] = static::getRegistryType();
553 $event =
new Main\Event(
'sale',
"OnBeforeSaleBasketItemDeleted", array(
'VALUES' => $itemValues));
563 $itemValues[
'ENTITY_REGISTRY_TYPE'] = static::getRegistryType();
565 $event =
new Main\Event(
'sale',
"OnSaleBasketItemDeleted", array(
'VALUES' => $itemValues));
572 protected function callEventOnSaleBasketBeforeSaved()
580 array(
'ENTITY' => $this)
584 if ($event->getResults())
587 foreach ($event->getResults() as $eventResult)
589 if ($eventResult->getType() == Main\EventResult::ERROR)
592 Main\Localization\
Loc::getMessage(
'SALE_EVENT_ON_BEFORE_BASKET_SAVED'),
593 'SALE_EVENT_ON_BEFORE_BASKET_SAVED'
595 if ($eventResultData = $eventResult->getParameters())
597 if (isset($eventResultData) && $eventResultData instanceof
ResultError)
600 $errorMsg = $eventResultData;
604 $result->addError($errorMsg);
615 protected function callEventOnSaleBasketSaved()
617 $result =
new Result();
625 if ($event->getResults())
628 foreach($event->getResults() as $eventResult)
630 if($eventResult->getType() == Main\EventResult::ERROR)
632 $errorMsg =
new ResultError(
634 'SALE_EVENT_ON_BASKET_SAVED'
636 if ($eventResultData = $eventResult->getParameters())
638 if (isset($eventResultData) && $eventResultData instanceof ResultError)
641 $errorMsg = $eventResultData;
645 $result->addError($errorMsg);
681 if ($this->fUserId ===
null)
703 public static function getList(array $parameters = array())
727 if (!$r->isSuccess())
729 $result->addErrors($r->getErrors());
731 elseif ($r->hasWarnings())
733 $result->addWarnings($r->getWarnings());
744 public function refresh(RefreshStrategy $strategy =
null)
752 $r =
$order->onBeforeBasketRefresh();
753 if (!$r->isSuccess())
759 if ($strategy ===
null)
761 $strategy = RefreshFactory::create();
764 $result = $strategy->refresh($this);
768 $r =
$order->onAfterBasketRefresh();
769 if (!$r->isSuccess())
775 $changedBasketItems = $result->get(
'CHANGED_BASKET_ITEMS');
776 if (!empty($changedBasketItems))
782 $r =
$order->refreshData(array(
'PRICE',
'PRICE_DELIVERY'));
783 if (!$r->isSuccess())
785 $result->addErrors($r->getErrors());
796 if (!$r->isSuccess())
798 $result->addErrors($r->getErrors());
809 public function getOrderableItems()
812 $basket = static::create($this->
getSiteId());
814 if ($this->isLoadForFUserId)
821 $basket->setOrder(
$order);
825 usort($sortedCollection,
function(BasketItemBase $a, BasketItemBase $b){
826 return (
int)$a->getField(
'SORT') - (
int)$b->getField(
'SORT');
830 foreach ($sortedCollection as $item)
832 if (!$item->canBuy() || $item->isDelay())
835 $item->setCollection($basket);
836 $basket->addItem($item);
873 public function getContext()
881 $context[
'USER_ID'] =
$order->getUserId();
882 $context[
'SITE_ID'] =
$order->getSiteId();
883 $context[
'CURRENCY'] =
$order->getCurrency();
887 $context = parent::getContext();
899 public function getQuantityList()
901 $quantityList = array();
907 foreach ($this->collection as $basketKey => $basketItem)
909 $quantityList[$basketItem->getBasketCode()] = $basketItem->getQuantity();
912 return $quantityList;
925 public function deleteItem($index)
927 $oldItem = parent::deleteItem($index);
929 unset($this->basketItemIndexMap[$oldItem->getBasketCode()]);
949 public function applyDiscount(array $basketRows)
951 $result =
new Result();
953 if ($this->
count() == 0 || empty($basketRows))
957 foreach ($this->collection as $basketItem)
959 if ($basketItem->isCustomPrice())
961 $basketCode = $basketItem->getBasketCode();
962 if (!isset($basketRows[$basketCode]))
965 $fields = $basketRows[$basketCode];
967 if (isset($fields[
'PRICE']) && isset($fields[
'DISCOUNT_PRICE']))
969 $fields[
'PRICE'] = (float)$fields[
'PRICE'];
970 $fields[
'DISCOUNT_PRICE'] = (float)$fields[
'DISCOUNT_PRICE'];
972 if ($fields[
'PRICE'] >= 0
973 && $basketItem->getPrice() != $fields[
'PRICE'])
976 $basketItem->setFieldNoDemand(
'PRICE', $fields[
'PRICE']);
979 if ($basketItem->getDiscountPrice() != $fields[
'DISCOUNT_PRICE'])
982 $basketItem->setFieldNoDemand(
'DISCOUNT_PRICE', $fields[
'DISCOUNT_PRICE']);
985 if (isset($fields[
'DISCOUNT_VALUE']))
986 $basketItem->setFieldNoDemand(
'DISCOUNT_VALUE', $fields[
'DISCOUNT_VALUE']);
989 unset($fields, $basketCode, $basketItem);
1000 public function createClone(\SplObjectStorage $cloneEntity =
null)
1002 if ($cloneEntity ===
null)
1004 $cloneEntity = new \SplObjectStorage();
1008 $basketClone = parent::createClone($cloneEntity);
1012 if ($cloneEntity->contains($this->order))
1018 return $basketClone;
1033 public function copy()
1035 if($this->order !==
null)
1037 throw new Main\SystemException(
'Could not clone basket which has order.');
1040 $basket = static::create($this->siteId);
1042 foreach($this as $originalItem)
1044 $item = $basket->createItem($originalItem->getField(
"MODULE"), $originalItem->getProductId());
1045 $item->initFields($originalItem->getFields()->getValues());
1064 $basket = static::createBasketObject();
1065 $basket->setOrder(
$order);
1066 $basket->setSiteId(
$order->getSiteId());
1068 return $basket->loadFromDb(array(
"=ORDER_ID" =>
$order->getId()));
1086 $basketItem = parent::addItem($basketItem);
1088 $this->basketItemIndexMap[$basketItem->getBasketCode()] = $basketItem->getInternalIndex();
1092 $basketItem->setCollection($this);
1111 if ($refreshItem !==
null)
1113 $strategy = RefreshFactory::createSingle($refreshItem->getBasketCode());
1117 $strategy = RefreshFactory::create(RefreshFactory::TYPE_FULL);
1120 return $this->refresh($strategy);
1135 $propertyCollection = $item->getPropertyCollection();
1136 if ($propertyCollection)
1138 $propertyList = $propertyCollection->getPropertyValues();