43 public function resetCollection()
47 $deliveryInfo =
array();
49 if (
count($this->collection) > 0)
52 foreach ($this->collection as $shipment)
54 if (empty($deliveryInfo))
56 if ($shipment->isSystem() && $shipment->getDeliveryId() > 0)
58 foreach (static::getClonedFields() as $field)
60 if (strval(trim($shipment->getField($field))) !=
'')
61 $deliveryInfo[$field] = trim($shipment->getField($field));
69 $systemShipment = $this->getSystemShipment();
72 $systemShipmentItemCollection = $systemShipment->getShipmentItemCollection();
75 $basket = $this->
getOrder()->getBasket();
76 $systemShipmentItemCollection->resetCollection($basket);
78 if (!empty($deliveryInfo))
80 $systemShipment->setFieldsNoDemand($deliveryInfo);
88 $r = $this->tryReserve();
91 $result->addErrors($r->getErrors());
117 $shipmentClassName = static::getItemCollectionClassName();
118 $shipment = $shipmentClassName::create($this, $delivery);
119 $this->addItem($shipment);
131 protected function addItem(Internals\CollectableEntity $shipment)
134 $shipment = parent::addItem($shipment);
154 public function deleteItem($index)
158 $oldItem = parent::deleteItem($index);
161 if ($oldItem->getId() > 0 && !$oldItem->isSystem() && ($systemShipment = $this->getSystemShipment()) && $systemShipment->getId() == 0)
163 $r = $this->cloneShipment($oldItem, $systemShipment);
164 if (!$r->isSuccess())
166 $result->addErrors($r->getErrors());
190 public function onItemModify(Internals\CollectableEntity $item,
$name =
null, $oldValue =
null, $value =
null)
195 if ($item instanceof Shipment)
219 public static function load(Order
$order)
222 $shipmentCollection = static::createShipmentCollectionObject();
223 $shipmentCollection->setOrder(
$order);
228 $shipmentClassName = static::getItemCollectionClassName();
229 $shipmentList = $shipmentClassName::loadForOrder(
$order->getId());
231 foreach ($shipmentList as $shipment)
233 $shipment->setCollection($shipmentCollection);
234 $shipmentCollection->bindItem($shipment);
237 $controller = Internals\CustomFieldsController::getInstance();
238 $controller->initializeCollection($shipmentCollection);
241 return $shipmentCollection;
247 private static function createShipmentCollectionObject()
250 $className = $registry->getShipmentCollectionClassName();
252 return new $className();
268 public function getSystemShipment()
271 foreach ($this->collection as $shipment)
273 if ($shipment->isSystem())
280 $shipmentClassName = static::getItemCollectionClassName();
281 $shipment = $shipmentClassName::createSystem($this);
282 $this->addItem($shipment);
292 public function isExistsSystemShipment()
295 foreach ($this->collection as $shipment)
297 if ($shipment->isSystem())
312 public function save()
319 throw new Main\ObjectNotFoundException(
'Entity "Order" not found');
322 $itemsFromDb =
array();
325 $itemsFromDbList = static::getList(
328 "select" =>
array(
"ID" ,
"DELIVERY_NAME",
"DELIVERY_ID")
331 while ($itemsFromDbItem = $itemsFromDbList->fetch())
332 $itemsFromDb[$itemsFromDbItem[
"ID"]] = $itemsFromDbItem;
336 foreach ($this->collection as $shipment)
338 if ($shipment->isSystem())
341 if (($systemShipment = $this->getSystemShipment()) && $systemShipment->getId() == 0)
344 $r = $this->cloneShipment($shipment, $systemShipment);
351 $result->addErrors($r->getErrors());
356 $changeMeaningfulFields =
array(
359 "CUSTOM_PRICE_DELIVERY",
370 "BASE_PRICE_DELIVERY",
375 foreach ($this->collection as $shipment)
377 $isNew = (bool)($shipment->getId() <= 0);
380 if (
$order->getId() > 0 && $isChanged)
382 $logFields =
array();
385 $fields = $shipment->getFields();
386 $originalValues =
$fields->getOriginalValues();
388 foreach($originalValues as $originalFieldName => $originalFieldValue)
390 if (in_array($originalFieldName, $changeMeaningfulFields) && $shipment->getField($originalFieldName) != $originalFieldValue)
392 $logFields[$originalFieldName] = $shipment->getField($originalFieldName);
394 $logFields[
'OLD_'.$originalFieldName] = $originalFieldValue;
400 $r = $shipment->save();
410 $orderHistory = $registry->getOrderHistoryClassName();
411 $orderHistory::addLog(
414 $isNew ?
'SHIPMENT_ADD' :
'SHIPMENT_UPDATE',
418 $orderHistory::SALE_ORDER_HISTORY_LOG_LEVEL_1
421 $orderHistory::addAction(
436 $result->addErrors($r->getErrors());
439 if (isset($itemsFromDb[$shipment->getId()]))
440 unset($itemsFromDb[$shipment->getId()]);
443 foreach ($itemsFromDb as
$k => $v)
445 $v[
'ENTITY_REGISTRY_TYPE'] = static::getRegistryType();
448 $event =
new Main\Event(
'sale',
"OnBeforeSaleShipmentDeleted",
array(
457 $event =
new Main\Event(
'sale',
"OnSaleShipmentDeleted",
array(
467 $orderHistory = $registry->getOrderHistoryClassName();
468 $orderHistory::addAction(
476 'DELIVERY_NAME' => $v[
'DELIVERY_NAME'],
477 'DELIVERY_ID' => $v[
'DELIVERY_ID'],
484 $entityMarker = $registry->getEntityMarkerClassName();
485 $entityMarker::deleteByFilter(
array(
486 '=ORDER_ID' =>
$order->getId(),
487 '=ENTITY_TYPE' => $entityMarker::ENTITY_TYPE_SHIPMENT,
499 $orderHistory = $registry->getOrderHistoryClassName();
500 $orderHistory::collectEntityFields(
'SHIPMENT',
$order->getId());
523 public function cloneShipment(
Shipment $parentShipment,
Shipment $childShipment)
525 foreach (static::getClonedFields() as $fieldName)
528 $childShipment->
setFieldNoDemand($fieldName, $parentShipment->getField($fieldName));
556 public function isShipped()
558 if (!empty($this->collection) && is_array($this->collection))
561 foreach ($this->collection as $shipment)
563 if ($shipment->isSystem())
565 if (!$shipment->isEmpty())
573 if (!$shipment->isShipped() && !$shipment->isEmpty())
590 public function hasShipped()
592 if (!empty($this->collection) && is_array($this->collection))
595 foreach ($this->collection as $shipment)
597 if ($shipment->isSystem())
602 if ($shipment->isShipped() && !$shipment->isEmpty())
617 public function isMarked()
619 if (!empty($this->collection) && is_array($this->collection))
622 foreach ($this->collection as $shipment)
624 if ($shipment->isSystem())
627 if ($shipment->isMarked())
640 public function isReserved()
642 if (!empty($this->collection) && is_array($this->collection))
645 foreach ($this->collection as $shipment)
647 if ($shipment->isSystem())
649 if (
count($this->collection) == 1)
650 return $shipment->isReserved();
655 if (!$shipment->isReserved())
670 public function isAllowDelivery()
672 if (!empty($this->collection) && is_array($this->collection))
675 foreach ($this->collection as $shipment)
677 if ($shipment->isSystem())
679 if (!$shipment->isEmpty())
687 if (!$shipment->isAllowDelivery() && !$shipment->isEmpty())
702 public function hasAllowDelivery()
707 foreach ($collection as $shipment)
709 if ($shipment->isAllowDelivery())
725 return $this->getSystemShipment()->isEmpty();
733 public function allowDelivery()
740 foreach ($collection as $shipment)
742 $r = $shipment->allowDelivery();
743 if (!$r->isSuccess())
745 $result->addErrors($r->getErrors());
755 public function disallowDelivery()
762 foreach ($collection as $shipment)
764 $r = $shipment->disallowDelivery();
765 if (!$r->isSuccess())
767 $result->addErrors($r->getErrors());
778 public function tryReserve()
783 foreach ($this->collection as $shipment)
785 if ($shipment->isReserved() || $shipment->isShipped())
788 $r = $shipment->tryReserve();
789 if (!$r->isSuccess())
791 $result->addErrors($r->getErrors());
793 elseif ($r->hasWarnings())
795 $result->addWarnings($r->getWarnings());
799 $entityMarker = $registry->getEntityMarkerClassName();
800 $entityMarker::addMarker($this->
getOrder(), $shipment, $r);
801 if (!$shipment->isSystem())
803 $shipment->setField(
'MARKED',
'Y');
819 public function tryUnreserve()
825 throw new Main\ObjectNotFoundException(
'Entity "Order" not found');
828 foreach ($this->collection as $shipment)
830 if ($shipment->isShipped())
833 !Internals\ActionEntity::isTypeExists(
839 Internals\ActionEntity::add(
843 'METHOD' =>
'Bitrix\Sale\Shipment::updateReservedFlag',
844 'PARAMS' =>
array($shipment)
852 $r = $shipment->tryUnreserve();
853 if (!$r->isSuccess())
855 if (!$shipment->isSystem())
860 $entityMarker = $registry->getEntityMarkerClassName();
861 $entityMarker::addMarker(
$order, $shipment, $r);
863 $shipment->setField(
'MARKED',
'Y');
865 $result->addErrors($r->getErrors());
867 elseif ($r->hasWarnings())
869 $result->addWarnings($r->getWarnings());
888 public function onBeforeBasketItemDelete(BasketItem $basketItem)
893 foreach ($this->collection as $shipment)
895 $r = $shipment->onBeforeBasketItemDelete($basketItem);
896 if (!$r->isSuccess())
898 $result->addErrors($r->getErrors());
919 public function onBasketModify(
$action, BasketItemBase $basketItem,
$name =
null, $oldValue =
null, $value =
null) : Result
923 if (!($basketItem instanceof BasketItem))
931 if (
$order->getId() == 0 && !
$order->isMathActionOnly())
940 return $this->getSystemShipment()->onBasketModify(
$action, $basketItem,
$name, $oldValue, $value);
947 if (
$name ==
'QUANTITY')
949 if (!$this->isAllowAutoEdit($basketItem))
951 $result = $this->checkDistributedQuantity($basketItem, $value);
958 $shipment = $this->getItemForAutoEdit($basketItem);
960 if ($value - $oldValue > 0)
962 $r = $this->getSystemShipment()->onBasketModify(
$action, $basketItem,
$name, $oldValue, $value);
963 if (!$r->isSuccess())
965 return $result->addErrors($r->getErrors());
971 $r = $shipment->onBasketModify(
$action, $basketItem,
$name, $oldValue, $value);
972 if (!$r->isSuccess())
974 $result->addErrors($r->getErrors());
979 if ($value - $oldValue < 0)
981 $r = $this->getSystemShipment()->onBasketModify(
$action, $basketItem,
$name, $oldValue, $value);
982 if (!$r->isSuccess())
984 return $result->addErrors($r->getErrors());
993 $shipment->onBasketModify(
$action, $basketItem,
$name, $value, $oldValue);
1006 private function getItemForAutoEdit(BasketItem $basketItem)
1008 if ($this->isAllowAutoEdit($basketItem))
1026 protected function isAllowAutoEdit(BasketItem $basketItem)
1028 if ($this->
count() === 1
1031 $this->
count() === 2
1033 $this->isExistsSystemShipment()
1037 if (!$this->getSystemShipment()->isExistBasketItem($basketItem)
1038 || (
int)$basketItem->getId() === 0
1043 if (!$shipment->isAllowDelivery()
1044 && !$shipment->isCanceled()
1045 && !$shipment->isShipped()
1049 if ($deliveryService = $shipment->getDelivery())
1051 return $deliveryService->isAllowEditShipment();
1069 private function checkDistributedQuantity(BasketItem $basketItem, $value)
1073 $basketItemQuantity = $this->getBasketItemDistributedQuantity($basketItem);
1074 if ($basketItemQuantity > $value)
1076 $result->addError(
new ResultError(
1077 Loc::getMessage(
'SALE_ORDER_SYSTEM_SHIPMENT_LESS_QUANTITY',
1079 '#PRODUCT_NAME#' => $basketItem->getField(
"NAME"),
1080 '#BASKET_ITEM_QUANTITY#' => $basketItemQuantity,
1081 '#BASKET_ITEM_MEASURE#' => $basketItem->getField(
"MEASURE_NAME"),
1082 '#QUANTITY#' => $basketItemQuantity - $value
1085 'SALE_ORDER_SYSTEM_SHIPMENT_LESS_QUANTITY')
1103 public function onOrderModify(
$name, $oldValue, $value)
1114 foreach ($this->collection as $shipment)
1116 if ($shipment->isShipped())
1127 Loc::getMessage(
'SALE_ORDER_CANCEL_SHIPMENT_EXIST_SHIPPED_MSGVER_1'),
1128 'SALE_ORDER_CANCEL_SHIPMENT_EXIST_SHIPPED'
1135 $this->tryUnreserve();
1140 foreach ($this->collection as $shipment)
1142 if ($shipment->needReservation())
1145 $r = $shipment->tryReserve();
1146 if (!$r->isSuccess())
1151 $entityMarker = $registry->getEntityMarkerClassName();
1152 $entityMarker::addMarker($this->
getOrder(), $shipment, $r);
1153 if (!$shipment->isSystem())
1155 $shipment->setField(
'MARKED',
'Y');
1158 $result->addErrors($r->getErrors());
1170 foreach ($this->collection as $shipment)
1172 if ($shipment->isSystem())
1175 $shipment->setField(
'MARKED', $value);
1194 $r = $this->calculateDelivery();
1195 if (!$r->isSuccess())
1197 $result->addErrors($r->getErrors());
1206 public function calculateDelivery()
1211 $calculatedDeliveries = [];
1216 foreach ($collection as $shipment)
1218 if ($shipment->getDeliveryId() == 0)
1221 if ($shipment->isCustomPrice())
1223 $priceDelivery = $shipment->getPrice();
1226 $calcResult->setDeliveryPrice($priceDelivery);
1231 $calcResult = $shipment->calculateDelivery();
1232 if (!$calcResult->isSuccess())
1234 $result->addErrors($calcResult->getErrors());
1238 $priceDelivery = $calcResult->getPrice();
1239 if ($priceDelivery < 0)
1241 $result->addError(
new ResultError(Loc::getMessage(
'SALE_ORDER_SHIPMENT_WRONG_DELIVERY_PRICE'),
'WRONG_DELIVERY_PRICE'));
1247 $shipment->setField(
'BASE_PRICE_DELIVERY', $priceDelivery);
1249 $calculatedDeliveries[] = $calcResult;
1252 $result->setData([
'CALCULATED_DELIVERIES' => $calculatedDeliveries]);
1260 public function resetData()
1265 foreach ($collection as $shipment)
1267 $shipment->resetData();
1278 public function getBasketItemDistributedQuantity(BasketItem $basketItem)
1285 foreach ($collection as $shipment)
1287 $allQuantity += $shipment->getBasketItemQuantity($basketItem);
1290 return $allQuantity;
1300 public function getBasketItemShippedQuantity(BasketItem $basketItem)
1305 foreach ($this->collection as $shipment)
1307 if ($shipment->isShipped())
1309 $quantity += $shipment->getShipmentItemCollection()->getBasketItemQuantity($basketItem);
1323 public function isExistBasketItem(BasketItem $basketItem, $includeSystemShipment =
false)
1326 foreach ($this->collection as $shipment)
1328 if (!$includeSystemShipment && $shipment->isSystem())
1333 return $shipment->isExistBasketItem($basketItem);
1341 public function getBasePriceDelivery()
1347 foreach ($collection as $shipment)
1349 $sum += $shipment->getField(
'BASE_PRICE_DELIVERY');
1358 public function getPriceDelivery()
1364 foreach ($collection as $shipment)
1366 $sum += $shipment->getPrice();
1377 public function getItemByShipmentCode($itemCode)
1380 foreach ($this->collection as $shipment)
1382 $shipmentCode = $shipment->getShipmentCode();
1383 if ($itemCode == $shipmentCode)
1399 public function verify()
1404 foreach ($this->collection as $shipment)
1406 if ($shipment->isSystem())
1411 $r = $shipment->verify();
1412 if (!$r->isSuccess())
1414 $result->addErrors($r->getErrors());
1419 $entityMarker = $registry->getEntityMarkerClassName();
1420 $entityMarker::addMarker($this->
getOrder(), $shipment, $r);
1422 $shipment->setField(
'MARKED',
'Y');
1435 public function createClone(\SplObjectStorage $cloneEntity)
1437 if ($this->isClone() && $cloneEntity->contains($this))
1439 return $cloneEntity[$this];
1443 $shipmentCollectionClone = parent::createClone($cloneEntity);
1447 if ($cloneEntity->contains($this->order))
1449 $shipmentCollectionClone->order = $cloneEntity[
$this->order];
1453 return $shipmentCollectionClone;
1461 public function getErrorEntity($value)
1465 foreach ($this->collection as $shipment)
1467 if ($className = $shipment->getErrorEntity($value))
1481 public function canAutoFixError($value)
1486 foreach ($this->collection as $shipment)
1488 if ($autoFix = $shipment->canAutoFixError($value))
1501 public static function updateReservedFlag(ShipmentCollection $collection)
1505 foreach ($collection as $shipment)
1508 $shipmentClassName = static::getItemCollectionClassName();
1509 $r = $shipmentClassName::updateReservedFlag($shipment);
1510 if (!$r->isSuccess())
1512 $result->addErrors($r->getErrors());
1515 if ($r->hasWarnings())
1517 $result->addWarnings($r->getWarnings());
1527 private static function getItemCollectionClassName()
1530 return $registry->getShipmentClassName();
1539 return Internals\ShipmentTable::getList($parameters);
1565 $callback =
function (
Shipment $shipment)
1567 return !$shipment->isSystem();