31 return [
'QUANTITY',
'RESERVED_QUANTITY',
'XML_ID'];
55 'XML_ID' => static::generateXmlId(),
56 'RESERVED_QUANTITY' => 0
64 $shipmentItem = static::createShipmentItemObject($fields);
89 public function delete()
95 $oldEntityValues = $this->fields->getOriginalValues();
99 'VALUES' => $oldEntityValues,
103 foreach(
$event->getResults() as $eventResult)
105 if($eventResult->getType() ==
Main\EventResult::ERROR)
108 Loc::getMessage(
'SALE_EVENT_ON_BEFORE_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'),
109 'SALE_EVENT_ON_BEFORE_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'
111 if ($eventResultData = $eventResult->getParameters())
113 if (isset($eventResultData) && $eventResultData instanceof
ResultError)
123 if (!$result->isSuccess())
129 if (!$shipment->isSystem())
131 if ($shipment->isShipped())
136 throw new Main\ObjectNotFoundException(
'Entity "BasketItem" not found');
141 Loc::getMessage(
'SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'),
142 'SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'
149 $r = $this->
setField(
"QUANTITY", 0);
151 if (!$r->isSuccess())
153 return $result->addErrors($r->getErrors());
156 elseif ($shipment->isSystem() && $this->getQuantity() > 1e-10)
158 throw new \ErrorException(
'System shipment not empty');
161 $r = parent::delete();
162 if (!$r->isSuccess())
164 $result->addErrors($r->getErrors());
168 $event =
new Main\Event(
'sale',
"OnSaleShipmentItemEntityDeleted", [
170 'VALUES' => $oldEntityValues,
174 foreach(
$event->getResults() as $eventResult)
176 if($eventResult->getType() == Main\EventResult::ERROR)
179 Loc::getMessage(
'SALE_EVENT_ON_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'),
180 'SALE_EVENT_ON_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'
182 $eventResultData = $eventResult->getParameters();
183 if (isset($eventResultData) && $eventResultData instanceof ResultError)
200 return (
float)$this->getField(
'QUANTITY');
220 $order = $shipment->getCollection()->getOrder();
223 $shipment->isShipped()
224 &&
$name !==
'XML_ID'
229 Loc::getMessage(
'SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'),
230 'SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'
235 if (
$name ==
"QUANTITY")
246 $deltaQuantity =
$value - $oldValue;
250 $systemShipment = $shipment->getCollection()->getSystemShipment();
252 $systemBasketItemQuantity = $systemShipment->getBasketItemQuantity(
$basketItem);
253 if ($systemBasketItemQuantity < abs($deltaQuantity))
260 if (!($parentBasketItem =
$basketItem->getParentBasketItem()))
262 throw new Main\ObjectNotFoundException(
'Entity "Parent Basket Item" not found');
265 $errorBasketCode = $parentBasketItem->getBasketCode();
268 if (isset(static::$errors[$errorBasketCode][
$basketItem->getField(
'ORDER_DELIVERY_BASKET_ID')][
'STORE_QUANTITY_LARGER_ALLOWED']))
270 static::$errors[$errorBasketCode][
$basketItem->getField(
'ORDER_DELIVERY_BASKET_ID')][
'STORE_QUANTITY_LARGER_ALLOWED'] +=
$basketItem->getQuantity();
277 'SALE_SHIPMENT_ITEM_LESS_AVAILABLE_QUANTITY_2',
281 ),
'SALE_SHIPMENT_ITEM_LESS_AVAILABLE_QUANTITY'
285 static::$errors[$errorBasketCode][
$basketItem->getField(
'ORDER_DELIVERY_BASKET_ID')][
'STORE_QUANTITY_LARGER_ALLOWED'] =
$basketItem->getQuantity();
297 $r = $this->calculateDelivery();
298 if (!$r->isSuccess())
300 $result->addErrors($r->getErrors());
312 throw new Main\ObjectNotFoundException(
'Entity "ShipmentItemStoreCollection" not found');
317 if ((
int)$value === 0)
319 $basketItemName = Loc::getMessage(
"SALE_SHIPMENT_ITEM_BASKET_WRONG_BASKET_ITEM");
320 $basketItemProductId =
'1';
325 $basketItemProductId =
$basketItem->getProductId();
331 $orderHistory = $registry->getOrderHistoryClassName();
332 $orderHistory::addAction(
335 'SHIPMENT_ITEM_BASKET_REMOVED',
339 'NAME' => $basketItemName,
340 'PRODUCT_ID' => $basketItemProductId,
347 $shipmentItemStore->delete();
355 if (!$r->isSuccess())
357 $result->addErrors($r->getErrors());
362 if ($barcodeQuantity > $value)
366 Loc::getMessage(
'SALE_SHIPMENT_ITEM_BARCODE_MORE_ITEM_QUANTITY'),
367 'BARCODE_MORE_ITEM_QUANTITY'
383 return parent::onFieldModify(
$name, $oldValue, $value);
391 public function checkMarkingCodeOnDeducted()
393 $result =
new Result();
406 return $result->addError(
409 'SALE_SHIPMENT_ITEM_MARKING_CODE_LESS_ITEM_QUANTITY_LONG_2',
410 [
'#PRODUCT_NAME#' => $this->
getBasketItem()->getField(
'NAME')])
418 if ($itemStore->getMarkingCode() ===
'')
420 return $result->addError(
423 'SALE_SHIPMENT_ITEM_MARKING_CODE_LESS_ITEM_QUANTITY_LONG_2',
424 [
'#PRODUCT_NAME#' => $this->
getBasketItem()->getField(
'NAME')])
441 return $this->
setField(
'QUANTITY', (
float)$quantity);
446 if (
$name ===
'RESERVED_QUANTITY')
450 $result = parent::setField(
$name, $value);
451 if ($result->isSuccess())
453 $this->setReserveQuantity($value, $oldValue);
459 return parent::setField(
$name, $value);
464 if (
$name ===
'RESERVED_QUANTITY')
468 parent::setFieldNoDemand(
$name, $value);
470 $this->setReserveQuantity($value, $oldValue);
475 parent::setFieldNoDemand(
$name, $value);
478 protected function setReserveQuantity($value, $oldValue)
484 $reserveCollection =
$basketItem->getReserveQuantityCollection();
485 if (!$reserveCollection)
490 if ($value - $oldValue > 0)
493 foreach ($reserveCollection as $reserve)
498 if ($reserve ===
null)
500 $reserve = $reserveCollection->create();
503 $settableReserveQuantity = $reserve->getQuantity() +
$value - $oldValue;
504 $reserve->setFieldNoDemand(
'QUANTITY', $settableReserveQuantity);
508 $delta = abs($value - $oldValue);
511 foreach ($reserveCollection as $reserve)
518 if ($reserve->getQuantity() >
$delta)
520 $settableReserveQuantity = $reserve->getQuantity() -
$delta;
521 $reserve->setFieldNoDemand(
'QUANTITY', $settableReserveQuantity);
526 $delta -= $reserve->getQuantity();
527 $reserve->deleteNoDemand();
539 return $this->getField(
'RESERVED_QUANTITY');
547 return (
int)$this->getField(
'BASKET_ID');
589 public function save()
591 $this->checkCallingContext();
595 $id = $this->getId();
596 $fields = $this->fields->getValues();
601 $order = $shipment->getCollection()->getOrder();
608 'VALUES' => $this->fields->getOriginalValues()
615 $fields = $this->fields->getChangedValues();
619 if (!$shipment->isSystem())
621 if (isset(
$fields[
"QUANTITY"]) && (floatval(
$fields[
"QUANTITY"]) == 0))
628 if (!$r->isSuccess())
633 $orderHistory = $registry->getOrderHistoryClassName();
634 $orderHistory::addAction(
637 'SHIPMENT_ITEM_UPDATE_ERROR',
640 [
"ERROR" => $r->getErrorMessages()]
643 $result->addErrors($r->getErrors());
647 if ($resultData = $r->getData())
648 $result->setData($resultData);
656 $orderHistory = $registry->getOrderHistoryClassName();
657 $orderHistory::collectEntityFields(
'SHIPMENT_ITEM_STORE',
$order->getId(), $id);
662 $fields[
'ORDER_DELIVERY_ID'] = $this->getParentShipmentId();
665 $fields[
'DATE_INSERT'] =
new Main\Type\DateTime();
668 $fields[
"BASKET_ID"] = $this->basketItem->getId();
671 if ($fields[
'BASKET_ID'] <= 0)
676 if (!isset($fields[
"QUANTITY"]) || (floatval($fields[
"QUANTITY"]) == 0))
682 if (!$r->isSuccess())
687 $orderHistory = $registry->getOrderHistoryClassName();
688 $orderHistory::addAction(
691 'SHIPMENT_ITEM_ADD_ERROR',
694 [
"ERROR" => $r->getErrorMessages()]
697 $result->addErrors($r->getErrors());
701 if ($resultData = $r->getData())
702 $result->setData($resultData);
707 if (!$shipment->isSystem())
712 $orderHistory = $registry->getOrderHistoryClassName();
713 $orderHistory::addAction(
716 'SHIPMENT_ITEM_BASKET_ADDED',
720 'QUANTITY' => $this->getQuantity(),
734 $event =
new Main\Event(
'sale',
'OnSaleShipmentItemEntitySaved', [
736 'VALUES' => $this->fields->getOriginalValues(),
745 if (!$r->isSuccess())
747 $result->addErrors($r->getErrors());
751 if ($result->isSuccess())
756 $orderHistory = $registry->getOrderHistoryClassName();
757 $orderHistory::collectEntityFields(
'SHIPMENT_ITEM',
$order->getId(), $id);
768 private function checkCallingContext()
773 throw new Main\ObjectNotFoundException(
'Entity "ShipmentItemCollection" not found');
777 if (!$shipment = $shipmentItemCollection->getShipment())
779 throw new Main\ObjectNotFoundException(
'Entity "Shipment" not found');
783 if (!$shipmentCollection = $shipment->getCollection())
785 throw new Main\ObjectNotFoundException(
'Entity "ShipmentCollection" not found');
789 if (!
$order = $shipmentCollection->getOrder())
791 throw new Main\ObjectNotFoundException(
'Entity "Order" not found');
794 if (!
$order->isSaveRunning())
796 trigger_error(
"Incorrect call to the save process. Use method save() on \Bitrix\Sale\Order entity", E_USER_WARNING);
800 private function getParentShipmentId()
805 return $shipment->getId();
816 if (intval($id) <= 0)
821 $itemDataList = static::getList([
823 '=ORDER_DELIVERY_ID' => $id,
826 'order' => [
'DATE_INSERT' =>
'ASC',
'ID' =>
'ASC']
829 while ($itemData = $itemDataList->fetch())
830 $items[] = static::createShipmentItemObject($itemData);
839 private static function createShipmentItemObject(
array $itemData = [])
842 $shipmentItemClassName = $registry->getShipmentItemClassName();
844 return new $shipmentItemClassName($itemData);
867 protected function loadBasketItem()
879 if (!$shipmentCollection = $shipment->getCollection())
885 if (!
$order = $shipmentCollection->getOrder())
887 throw new Main\ObjectNotFoundException(
'Entity "Order" not found');
891 if (!$basket =
$order->getBasket())
893 throw new Main\ObjectNotFoundException(
'Entity "Basket" not found');
899 return $basket->getItemByBasketCode($this->
getBasketId());
907 if ($this->basketItem ==
null)
909 $this->basketItem = $this->loadBasketItem();
918 public function getShipmentItemStoreCollection()
925 if (empty($this->shipmentItemStoreCollection))
930 $itemStoreCollectionClassName = $registry->getShipmentItemStoreCollectionClassName();
931 $this->shipmentItemStoreCollection = $itemStoreCollectionClassName::load($this);
966 protected function calculateDelivery()
976 $shipmentCollection = $shipment->getCollection();
979 $order = $shipmentCollection->getOrder();
986 $deliveryCalculate = $shipment->calculateDelivery();
987 if (!$deliveryCalculate->isSuccess())
989 $result->addErrors($deliveryCalculate->getErrors());
992 if ($deliveryCalculate->getPrice() > 0)
994 $shipment->setField(
'BASE_PRICE_DELIVERY', $deliveryCalculate->getPrice());
1007 protected function addChangesToHistory(
$name, $oldValue =
null, $value =
null)
1009 if ($this->
getId() > 0)
1014 throw new Main\ObjectNotFoundException(
'Entity "ShipmentItemCollection" not found');
1018 if (!$shipment = $shipmentItemCollection->getShipment())
1020 throw new Main\ObjectNotFoundException(
'Entity "Shipment" not found');
1023 if ($shipment->isSystem())
1027 if (!$shipmentCollection = $shipment->getCollection())
1029 throw new Main\ObjectNotFoundException(
'Entity "ShipmentCollection" not found');
1032 $historyFields = [];
1039 'PRODUCT_ID' =>
$basketItem->getField(
'PRODUCT_ID'),
1044 if ((
$order = $shipmentCollection->getOrder()) &&
$order->getId() > 0)
1049 $orderHistory = $registry->getOrderHistoryClassName();
1050 $orderHistory::addField(
1071 if (parent::isChanged())
1087 return Internals\Catalog\Provider::tryReserveShipmentItem($this);
1097 return Internals\Catalog\Provider::tryUnreserveShipmentItem($this);
1105 public function verify()
1116 if (!$shipment = $shipmentItemCollection->getShipment())
1126 'SALE_SHIPMENT_ITEM_BASKET_ITEM_NOT_FOUND',
1129 '#SHIPMENT_ID#' => $shipment->getId(),
1130 '#SHIPMENT_ITEM_ID#' => $this->getId(),
1132 ),
'SALE_SHIPMENT_ITEM_BASKET_ITEM_NOT_FOUND'
1144 'SALE_SHIPMENT_ITEM_ERR_QUANTITY_EMPTY',
1146 '#BASKET_ITEM_NAME#' => $this->
getBasketItem()->getField(
'NAME'),
1148 ),
'SALE_SHIPMENT_ITEM_ERR_QUANTITY_EMPTY'
1161 $r = $shipmentItemStore->verify();
1162 if (!$r->isSuccess())
1164 $result->addErrors($r->getErrors());
1196 public function createClone(\SplObjectStorage $cloneEntity)
1198 if ($this->
isClone() && $cloneEntity->contains($this))
1200 return $cloneEntity[$this];
1204 $shipmentItemClone = parent::createClone($cloneEntity);
1216 $shipmentItemClone->basketItem = $cloneEntity[
$basketItem];
1234 return $shipmentItemClone;
1245 static $className =
null;
1246 $errorsList = static::getAutoFixErrorsList();
1247 if (is_array($errorsList) && in_array($value, $errorsList))
1249 if ($className ===
null)
1250 $className = static::getClassName();
1273 $errorsList = static::getAutoFixErrorsList();
1274 if (is_array($errorsList) && in_array($value, $errorsList))
1323 parent::clearChanged();
1329 $shipmentItemStore->clearChanged();
1342 $this->fields->isChanged(
'RESERVED_QUANTITY')
1343 || $this->
getCollection()->getShipment()->getField(
'RESERVED') ==
'Y'
1358 $changedFields = $this->fields->getChangedValues();
1359 $originalFields = $this->fields->getOriginalValues();
1361 return $changedFields[
'RESERVED_QUANTITY'] - $originalFields[
'RESERVED_QUANTITY'];
1400 return 'SaleShipmentItem';
1408 $result = parent::toArray();