32 private $bundleCollection =
null;
51 public function save()
53 $result = parent::save();
54 if (!$result->isSuccess())
59 $reserveCollection = $this->getReserveQuantityCollection();
60 if ($reserveCollection)
62 $r = $reserveCollection->save();
65 return $result->addErrors($r->getErrors());
79 $basketClassName = $register->getBasketClassName();
81 $itemsFromDbList = $basketClassName::getList(
84 'filter' => [
'SET_PARENT_ID' => $id],
87 while ($itemsFromDbItem = $itemsFromDbList->fetch())
89 if ($itemsFromDbItem[
'ID'] == $id)
92 $itemsFromDb[$itemsFromDbItem[
'ID']] =
true;
97 foreach ($bundleCollection as $bundleItem)
99 $parentId = (int)$bundleItem->getField(
'SET_PARENT_ID');
101 $bundleItem->setFieldNoDemand(
'SET_PARENT_ID', $id);
103 $saveResult = $bundleItem->save();
104 if (!$saveResult->isSuccess())
105 $result->addErrors($saveResult->getErrors());
107 if (isset($itemsFromDb[$bundleItem->getId()]))
108 unset($itemsFromDb[$bundleItem->getId()]);
111 foreach ($itemsFromDb as $id => $value)
128 protected function add()
130 $logFields = $this->getLoggedFields();
132 $result = parent::add();
140 throw new Main\ObjectNotFoundException(
'Entity "Basket" not found');
143 if ($basket->getOrderId() > 0)
147 $orderHistory = $registry->getOrderHistoryClassName();
149 if (!$result->isSuccess())
151 $orderHistory::addAction(
153 $basket->getOrderId(),
154 'BASKET_ITEM_ADD_ERROR',
157 [
"ERROR" => $result->getErrorMessages()]
162 $orderHistory::addLog(
164 $basket->getOrderId(),
169 $orderHistory::SALE_ORDER_HISTORY_LOG_LEVEL_1
172 $orderHistory::addAction(
174 $basket->getOrderId(),
179 $orderHistory::SALE_ORDER_HISTORY_ACTION_LOG_LEVEL_1
196 protected function update()
200 $orderHistory = $registry->getOrderHistoryClassName();
208 throw new Main\ObjectNotFoundException(
'Entity "Basket" not found');
211 $logFields = $this->getLoggedFields();
213 $result = parent::update();
215 if (!$result->isSuccess())
217 if ($basket->getOrderId() > 0)
219 $orderHistory::addAction(
221 $basket->getOrderId(),
222 'BASKET_ITEM_UPDATE_ERROR',
225 [
"ERROR" => $result->getErrorMessages()]
231 $orderHistory::addLog(
233 $basket->getOrderId(),
234 "BASKET_ITEM_UPDATE",
238 $orderHistory::SALE_ORDER_HISTORY_LOG_LEVEL_1
241 $orderHistory::addAction(
243 $basket->getOrderId(),
248 $orderHistory::SALE_ORDER_HISTORY_ACTION_LOG_LEVEL_1
261 private function getLoggedFields()
266 $orderId = $basket->getOrderId();
268 $changeMeaningfulFields = [
281 $originalValues = $itemValues->getOriginalValues();
283 foreach($originalValues as $originalFieldName => $originalFieldValue)
285 if (in_array($originalFieldName, $changeMeaningfulFields) && $this->
getField($originalFieldName) != $originalFieldValue)
287 $logFields[$originalFieldName] = $this->
getField($originalFieldName);
288 $logFields[
'OLD_'.$originalFieldName] = $originalFieldValue;
303 $result =
new Result();
314 foreach ($order->getShipmentCollection() as $shipment)
316 if ($shipment->isSystem())
322 if ($shipmentItemCollection = $shipment->getShipmentItemCollection())
324 if ($shipmentItemCollection->getItemByBasketCode($this->getBasketCode())
325 && $shipment->isShipped()
328 $messageCode =
'SALE_BASKET_ITEM_REMOVE_IMPOSSIBLE_BECAUSE_SHIPPED';
331 $messageCode =
'SALE_BASKET_ITEM_REMOVE_IMPOSSIBLE_BECAUSE_SERVICE_SHIPPED';
339 '#PRODUCT_NAME#' => $this->
getField(
'NAME'),
342 'SALE_BASKET_ITEM_REMOVE_IMPOSSIBLE_BECAUSE_SHIPPED'
361 public function delete()
363 $result =
new Result();
365 $deleteResult = parent::delete();
366 if (!$deleteResult->isSuccess())
368 $result->addErrors($deleteResult->getErrors());
375 if ($bundleCollection)
378 foreach ($bundleCollection as $bundleItem)
380 $deleteResult = $bundleItem->delete();
381 if (!$deleteResult->isSuccess())
383 $result->addErrors($deleteResult->getErrors());
396 $r = $reserve->delete();
397 if (!$r->isSuccess())
399 $result->addErrors($r->getErrors());
415 public function getReserveQuantityCollection()
422 if ($this->reserveQuantityCollection ===
null)
427 $reserveCollectionClassName = $registry->getReserveCollectionClassName();
429 $this->reserveQuantityCollection = $reserveCollectionClassName::load($this);
440 private function clearBundleItemFields(array $fields)
444 $settableFields = static::getAllFields();
446 foreach ($fields as $name => $value)
448 if (!isset($settableFields[$name]))
450 unset($fields[$name]);
481 return $parentBasketItem->getId();
492 return (
int)$this->
getField(
'TYPE') === static::TYPE_SET;
514 public function getBundleBaseQuantity()
524 $bundleChildList = [];
528 $originalValues = $this->fields->getOriginalValues();
529 if (array_key_exists(
'QUANTITY', $originalValues) && $originalValues[
'QUANTITY'] !==
null)
531 $originalQuantity = $originalValues[
'QUANTITY'];
534 foreach ($bundleCollection as $bundleBasketItem)
536 $originalBundleQuantity = $bundleBasketItem->getQuantity();
537 $originalBundleValues = $bundleBasketItem->getFields()->getOriginalValues();
538 if (array_key_exists(
'QUANTITY', $originalBundleValues) && $originalBundleValues[
'QUANTITY'] !==
null)
540 $originalBundleQuantity = $originalBundleValues[
'QUANTITY'];
543 if ($originalQuantity > 0)
545 $bundleQuantity = $originalBundleQuantity / $originalQuantity;
552 $bundleChildList[][
"ITEMS"][] = [
553 "PRODUCT_ID" => $bundleBasketItem->getProductId(),
554 "QUANTITY" => $bundleQuantity
559 if (empty($bundleChildList))
562 foreach ($bundleChildList as $bundleBasketListDat)
564 foreach ($bundleBasketListDat[
"ITEMS"] as $bundleDat)
566 $result[$bundleDat[
'PRODUCT_ID']] = $bundleDat[
'QUANTITY'];
589 if ($this->bundleCollection ===
null)
591 if ($this->getId() > 0)
597 $this->bundleCollection = $this->loadBundleCollectionFromProvider();
601 return $this->bundleCollection;
609 public function createBundleCollection()
611 if ($this->bundleCollection ===
null)
615 $bundleClassName = $registry->getBundleCollectionClassName();
617 $this->bundleCollection = $bundleClassName::createBundleCollectionObject();
618 $this->bundleCollection->setParentBasketItem($this);
620 $this->
setField(
'TYPE', static::TYPE_SET);
623 return $this->bundleCollection;
636 if ($this->getId() > 0)
638 return $collection->loadFromDb([
"SET_PARENT_ID" => $this->getId(),
"TYPE" =>
false]);
655 protected function loadBundleCollectionFromProvider()
659 $bundleChildList = [];
668 $order = $basket->getOrder();
672 'SITE_ID' => $order->getSiteId(),
673 'USER_ID' => $order->getUserId(),
674 'CURRENCY' => $order->getCurrency(),
680 'SITE_ID' => SITE_ID,
681 'USER_ID' => $USER && $USER->GetID() > 0 ? $USER->GetID() : 0,
682 'CURRENCY' => CurrencyManager::getBaseCurrency(),
686 $creator = Internals\ProviderCreator::create($context);
687 $creator->addBasketItem($this);
688 $r = $creator->getBundleItems();
691 $resultProductListData = $r->getData();
692 if (!empty($resultProductListData[
'BUNDLE_LIST']))
694 $bundleChildList = $resultProductListData[
'BUNDLE_LIST'];
698 if (empty($bundleChildList))
703 $this->bundleCollection = $this->setItemsAfterGetBundle($bundleChildList);
704 return $this->bundleCollection;
718 private function setItemsAfterGetBundle(array $items)
721 $bundleCollection = $this->createBundleCollection();
722 foreach ($items as $providerClassName => $products)
724 foreach ($products as $productId => $bundleBasketListDat)
726 foreach ($bundleBasketListDat[
"ITEMS"] as $bundleDat)
728 $bundleFields = $this->clearBundleItemFields($bundleDat);
729 unset($bundleFields[
'ID']);
733 if ($this->getId() > 0)
735 $bundleFields[
'SET_PARENT_ID'] = $this->getId();
739 $bundleBasketItem = static::create($bundleCollection, $bundleFields[
'MODULE'], $bundleFields[
'PRODUCT_ID']);
741 if (!empty($bundleDat[
"PROPS"]) && is_array($bundleDat[
"PROPS"]))
744 $property = $bundleBasketItem->getPropertyCollection();
745 $property->setProperty($bundleDat[
"PROPS"]);
748 $bundleQuantity = $bundleFields[
'QUANTITY'] * $this->
getQuantity();
749 unset($bundleFields[
'QUANTITY']);
751 $bundleBasketItem->setFieldsNoDemand($bundleFields);
752 $bundleBasketItem->setField(
'QUANTITY', $bundleQuantity);
753 $bundleCollection->addItem($bundleBasketItem);
758 return $bundleCollection;
775 $item = parent::findItemByBasketCode($basketCode);
785 $item = $basketItem->findItemByBasketCode($basketCode);
808 $item = parent::findItemById($id);
818 $item = $basketItem->findItemById($id);
834 protected function addChangesToHistory($name, $oldValue =
null, $value =
null)
836 if ($this->getId() > 0)
842 throw new ObjectNotFoundException(
'Entity "Basket" not found');
845 if ($basket->getOrder() && $basket->getOrderId() > 0)
847 if ($name ==
"QUANTITY")
849 if (floatval($value) == 0)
863 $orderHistory = $registry->getOrderHistoryClassName();
864 $orderHistory::addField(
866 $basket->getOrderId(),
886 $format = Config\Option::get(
'sale',
'format_quantity',
'AUTO');
887 if ($format ==
'AUTO' || intval($format) <= 0)
889 $quantity = round($quantity, SALE_VALUE_PRECISION);
893 $quantity = number_format($quantity, intval($format),
'.',
'');
904 return Internals\BasketTable::getMap();
909 $isChanged = parent::isChanged();
911 if ($isChanged ===
false)
913 $reserveCollection = $this->getReserveQuantityCollection();
914 if ($reserveCollection)
916 $isChanged = $reserveCollection->isChanged();
937 public function createClone(\SplObjectStorage $cloneEntity)
939 if ($this->
isClone() && $cloneEntity->contains($this))
941 return $cloneEntity[$this];
945 $basketItemClone = parent::createClone($cloneEntity);
950 $basketItemClone->calculatedFields =
$calculatedFields->createClone($cloneEntity);
953 if (!$cloneEntity->contains($this))
955 $cloneEntity[$this] = $basketItemClone;
973 if ($reservedCollection = $this->getReserveQuantityCollection())
975 if (!$cloneEntity->contains($reservedCollection))
977 $cloneEntity[$reservedCollection] = $reservedCollection->createClone($cloneEntity);
980 if ($cloneEntity->contains($reservedCollection))
982 $basketItemClone->reserveQuantityCollection = $cloneEntity[$reservedCollection];
991 if (!$cloneEntity->contains($bundleCollection))
993 $cloneEntity[$bundleCollection] = $bundleCollection->createClone($cloneEntity);
996 if ($cloneEntity->contains($bundleCollection))
998 $basketItemClone->bundleCollection = $cloneEntity[$bundleCollection];
1003 return $basketItemClone;
1021 $result =
new Result();
1023 $r = parent::onFieldModify($name, $oldValue, $value);
1024 if (!$r->isSuccess())
1026 $result->addErrors($r->getErrors());
1029 elseif ($r->hasWarnings())
1031 $result->addWarnings($r->getWarnings());
1037 if ($name ===
'QUANTITY')
1039 $deltaQuantity = $value - $oldValue;
1040 if ($deltaQuantity != 0)
1044 $bundleBaseQuantity = $this->getBundleBaseQuantity();
1047 foreach ($bundleCollection as $bundleItem)
1049 $bundleProductId = $bundleItem->getProductId();
1051 if (!isset($bundleBaseQuantity[$bundleProductId]))
1052 throw new ArgumentOutOfRangeException(
'bundle product id');
1054 $quantity = $bundleBaseQuantity[$bundleProductId] * $value;
1056 $r = $bundleItem->setField(
'QUANTITY', $quantity);
1057 if (!$r->isSuccess())
1059 $result->addErrors($r->getErrors());
1065 elseif ($name ==
"DELAY")
1071 foreach ($bundleCollection as $bundleItem)
1073 $r = $bundleItem->setField(
'DELAY', $value);
1074 if (!$r->isSuccess())
1076 $result->addErrors($r->getErrors());
1081 elseif ($name ==
"CAN_BUY")
1087 foreach ($bundleCollection as $bundleItem)
1089 $r = $bundleItem->setField(
'CAN_BUY', $value);
1090 if (!$r->isSuccess())
1092 $result->addErrors($r->getErrors());
1111 public static function load(BasketItemCollection $basket, $data)
1114 if (isset($data[
'ITEMS']))
1116 $bundleItems = $data[
'ITEMS'];
1117 unset($data[
'ITEMS']);
1121 $basketItem = parent::load($basket, $data);
1125 $bundleCollection = $basketItem->createBundleCollection();
1126 $bundleCollection->loadFromArray($bundleItems);
1139 return Internals\BasketTable::add($fields);
1150 return Internals\BasketTable::update($primary, $fields);
1160 return Internals\BasketTable::delete($primary);
1186 $quantity = parent::getNotPurchasedQuantity();
1192 $quantity -= $order->getShipmentCollection()->getBasketItemShippedQuantity($this);
1203 return (
int)$this->
getField(
'TYPE') === static::TYPE_SERVICE;