Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
shipmentitem.php
1<?php
2namespace Bitrix\Sale;
3
7
8Loc::loadMessages(__FILE__);
9
15 implements \IEntityMarker
16{
18 protected $basketItem;
19
22
24 protected static $errors = [];
25
29 public static function getAvailableFields()
30 {
31 return ['QUANTITY', 'RESERVED_QUANTITY', 'XML_ID'];
32 }
33
37 protected static function getMeaningfulFields()
38 {
39 return ['QUANTITY'];
40 }
41
53 {
54 $fields = [
55 'XML_ID' => static::generateXmlId(),
56 'RESERVED_QUANTITY' => 0
57 ];
58
59 if ($basketItem !== null && $basketItem->getId() > 0)
60 {
61 $fields["BASKET_ID"] = $basketItem->getId();
62 }
63
64 $shipmentItem = static::createShipmentItemObject($fields);
65 $shipmentItem->setCollection($collection);
66
67 if ($basketItem !== null)
68 {
69 $shipmentItem->basketItem = $basketItem;
70 }
71
72 return $shipmentItem;
73 }
74
78 protected static function generateXmlId()
79 {
80 return uniqid('bx_');
81 }
82
89 public function delete()
90 {
91 $result = new Result();
92
93 $shipment = $this->getCollection()->getShipment();
94
95 $oldEntityValues = $this->fields->getOriginalValues();
96
97 $event = new Main\Event('sale', "OnBeforeSaleShipmentItemEntityDeleted", [
98 'ENTITY' => $this,
99 'VALUES' => $oldEntityValues,
100 ]);
101 $event->send();
102
103 foreach($event->getResults() as $eventResult)
104 {
105 if($eventResult->getType() == Main\EventResult::ERROR)
106 {
107 $errorMsg = new ResultError(
108 Loc::getMessage('SALE_EVENT_ON_BEFORE_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'),
109 'SALE_EVENT_ON_BEFORE_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'
110 );
111 if ($eventResultData = $eventResult->getParameters())
112 {
113 if (isset($eventResultData) && $eventResultData instanceof ResultError)
114 {
115 $errorMsg = $eventResultData;
116 }
117 }
118
119 $result->addError($errorMsg);
120 }
121 }
122
123 if (!$result->isSuccess())
124 {
125 return $result;
126 }
127
128
129 if (!$shipment->isSystem())
130 {
131 if ($shipment->isShipped())
132 {
134 if (!$basketItem = $this->getBasketItem())
135 {
136 throw new Main\ObjectNotFoundException('Entity "BasketItem" not found');
137 }
138
139 $result->addError(
140 new ResultError(
141 Loc::getMessage('SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'),
142 'SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'
143 )
144 );
145
146 return $result;
147 }
148
149 $r = $this->setField("QUANTITY", 0);
150
151 if (!$r->isSuccess())
152 {
153 return $result->addErrors($r->getErrors());
154 }
155 }
156 elseif ($shipment->isSystem() && $this->getQuantity() > 1e-10)
157 {
158 throw new \ErrorException('System shipment not empty');
159 }
160
161 $r = parent::delete();
162 if (!$r->isSuccess())
163 {
164 $result->addErrors($r->getErrors());
165 }
166
167
168 $event = new Main\Event('sale', "OnSaleShipmentItemEntityDeleted", [
169 'ENTITY' => $this,
170 'VALUES' => $oldEntityValues,
171 ]);
172 $event->send();
173
174 foreach($event->getResults() as $eventResult)
175 {
176 if($eventResult->getType() == Main\EventResult::ERROR)
177 {
178 $errorMsg = new ResultError(
179 Loc::getMessage('SALE_EVENT_ON_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'),
180 'SALE_EVENT_ON_SALESHIPMENTITEM_ENTITY_DELETED_ERROR'
181 );
182 $eventResultData = $eventResult->getParameters();
183 if (isset($eventResultData) && $eventResultData instanceof ResultError)
184 {
185 $errorMsg = $eventResultData;
186 }
187
188 $result->addError($errorMsg);
189 }
190 }
191
192 return $result;
193 }
194
198 public function getQuantity()
199 {
200 return (float)$this->getField('QUANTITY');
201 }
202
214 protected function onFieldModify($name, $oldValue, $value)
215 {
216 $result = new Result();
217
218 $shipment = $this->getCollection()->getShipment();
219
220 $order = $shipment->getCollection()->getOrder();
221
222 if ($shipment->isShipped())
223 {
224 return $result->addError(
225 new ResultError(
226 Loc::getMessage('SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'),
227 'SALE_SHIPMENT_ITEM_SHIPMENT_ALREADY_SHIPPED_CANNOT_EDIT'
228 )
229 );
230 }
231
232 if ($name == "QUANTITY")
233 {
235 if (!$basketItem = $this->getBasketItem())
236 {
237 if ($value != 0)
238 {
239 throw new Main\ObjectNotFoundException('Entity "BasketItem" not found');
240 }
241 }
242
243 $deltaQuantity = $value - $oldValue;
244
245 if ($basketItem && $deltaQuantity > 0)
246 {
247 $systemShipment = $shipment->getCollection()->getSystemShipment();
248
249 $systemBasketItemQuantity = $systemShipment->getBasketItemQuantity($basketItem);
250 if ($systemBasketItemQuantity < abs($deltaQuantity))
251 {
252 $errorBasketCode = $basketItem->getBasketCode();
253
254 if ($basketItem->isBundleChild())
255 {
257 if (!($parentBasketItem = $basketItem->getParentBasketItem()))
258 {
259 throw new Main\ObjectNotFoundException('Entity "Parent Basket Item" not found');
260 }
261
262 $errorBasketCode = $parentBasketItem->getBasketCode();
263 }
264
265 if (isset(static::$errors[$errorBasketCode][$basketItem->getField('ORDER_DELIVERY_BASKET_ID')]['STORE_QUANTITY_LARGER_ALLOWED']))
266 {
267 static::$errors[$errorBasketCode][$basketItem->getField('ORDER_DELIVERY_BASKET_ID')]['STORE_QUANTITY_LARGER_ALLOWED'] += $basketItem->getQuantity();
268 }
269 else
270 {
271 $result->addError(
272 new ResultError(
274 'SALE_SHIPMENT_ITEM_LESS_AVAILABLE_QUANTITY_2',
275 [
276 '#PRODUCT_NAME#' => $basketItem->getField('NAME'),
277 ]
278 ), 'SALE_SHIPMENT_ITEM_LESS_AVAILABLE_QUANTITY'
279 )
280 );
281
282 static::$errors[$errorBasketCode][$basketItem->getField('ORDER_DELIVERY_BASKET_ID')]['STORE_QUANTITY_LARGER_ALLOWED'] = $basketItem->getQuantity();
283 }
284
285 return $result;
286 }
287 }
288
289
290 if ($basketItem)
291 {
292 if (!$this->isMathActionOnly())
293 {
294 $r = $this->calculateDelivery();
295 if (!$r->isSuccess())
296 {
297 $result->addErrors($r->getErrors());
298 }
299 }
300 }
301
303 $shipmentItemStoreCollection = $this->getShipmentItemStoreCollection();
304 if (
306 && $basketItem->isReservableItem()
307 )
308 {
309 throw new Main\ObjectNotFoundException('Entity "ShipmentItemStoreCollection" not found');
310 }
311
313 {
314 if ((int)$value === 0)
315 {
316 $basketItemName = Loc::getMessage("SALE_SHIPMENT_ITEM_BASKET_WRONG_BASKET_ITEM");
317 $basketItemProductId = '1';
318
319 if ($basketItem)
320 {
321 $basketItemName = $basketItem->getField('NAME');
322 $basketItemProductId = $basketItem->getProductId();
323 }
324
325 $registry = Registry::getInstance(static::getRegistryType());
326
328 $orderHistory = $registry->getOrderHistoryClassName();
329 $orderHistory::addAction(
330 'SHIPMENT',
331 $order->getId(),
332 'SHIPMENT_ITEM_BASKET_REMOVED',
333 $shipment->getId(),
334 null,
335 [
336 'NAME' => $basketItemName,
337 'PRODUCT_ID' => $basketItemProductId,
338 ]
339 );
340
342 foreach ($shipmentItemStoreCollection as $shipmentItemStore)
343 {
344 $shipmentItemStore->delete();
345 }
346
347 }
348 elseif ($basketItem->isReservableItem())
349 {
350 // check barcodes
351 $r = $shipmentItemStoreCollection->onShipmentItemModify(EventActions::UPDATE, $this, $name, $oldValue, $value);
352 if (!$r->isSuccess())
353 {
354 $result->addErrors($r->getErrors());
355 return $result;
356 }
357
358 $barcodeQuantity = $shipmentItemStoreCollection->getQuantityByBasketCode($basketItem->getBasketCode());
359 if ($barcodeQuantity > $value)
360 {
361 $result->addError(
362 new ResultError(
363 Loc::getMessage('SALE_SHIPMENT_ITEM_BARCODE_MORE_ITEM_QUANTITY'),
364 'BARCODE_MORE_ITEM_QUANTITY'
365 )
366 );
367
368 return $result;
369 }
370 }
371 }
372
373 if (!$basketItem)
374 {
375 return $result;
376 }
377 }
378
379
380 return parent::onFieldModify($name, $oldValue, $value);
381 }
382
388 public function checkMarkingCodeOnDeducted()
389 {
390 $result = new Result();
391
392 if (
393 !$this->getBasketItem()->isReservableItem()
394 || !$this->getBasketItem()->isSupportedMarkingCode()
395 )
396 {
397 return $result;
398 }
399
400 $shipmentItemStoreCollection = $this->getShipmentItemStoreCollection();
401 if ($shipmentItemStoreCollection && $shipmentItemStoreCollection->count() < $this->getQuantity())
402 {
403 return $result->addError(
404 new Main\Error(
406 'SALE_SHIPMENT_ITEM_MARKING_CODE_LESS_ITEM_QUANTITY_LONG_2',
407 ['#PRODUCT_NAME#' => $this->getBasketItem()->getField('NAME')])
408 )
409 );
410 }
411
413 foreach ($shipmentItemStoreCollection as $itemStore)
414 {
415 if ($itemStore->getMarkingCode() === '')
416 {
417 return $result->addError(
418 new Main\Error(
420 'SALE_SHIPMENT_ITEM_MARKING_CODE_LESS_ITEM_QUANTITY_LONG_2',
421 ['#PRODUCT_NAME#' => $this->getBasketItem()->getField('NAME')])
422 )
423 );
424 }
425 }
426
427 return $result;
428 }
429
436 public function setQuantity($quantity)
437 {
438 return $this->setField('QUANTITY', (float)$quantity);
439 }
440
441 public function setField($name, $value)
442 {
443 if ($name === 'RESERVED_QUANTITY')
444 {
445 $oldValue = $this->getReservedQuantity();
446
447 $result = parent::setField($name, $value);
448 if ($result->isSuccess())
449 {
450 $this->setReserveQuantity($value, $oldValue);
451 }
452
453 return $result;
454 }
455
456 return parent::setField($name, $value);
457 }
458
459 public function setFieldNoDemand($name, $value)
460 {
461 if ($name === 'RESERVED_QUANTITY')
462 {
463 $oldValue = $this->getReservedQuantity();
464
465 parent::setFieldNoDemand($name, $value);
466
467 $this->setReserveQuantity($value, $oldValue);
468
469 return;
470 }
471
472 parent::setFieldNoDemand($name, $value);
473 }
474
475 protected function setReserveQuantity($value, $oldValue)
476 {
477 $result = new Result();
478
479 $basketItem = $this->getBasketItem();
480
481 $reserveCollection = $basketItem->getReserveQuantityCollection();
482 if (!$reserveCollection)
483 {
484 return $result;
485 }
486
487 if ($value - $oldValue > 0) // plus
488 {
489 $reserve = null;
490 foreach ($reserveCollection as $reserve)
491 {
492 break;
493 }
494
495 if ($reserve === null)
496 {
497 $reserve = $reserveCollection->create();
498 }
499
500 $settableReserveQuantity = $reserve->getQuantity() + $value - $oldValue;
501 $reserve->setFieldNoDemand('QUANTITY', $settableReserveQuantity);
502 }
503 else // minus
504 {
505 $delta = abs($value - $oldValue);
506
508 foreach ($reserveCollection as $reserve)
509 {
510 if ($delta === 0)
511 {
512 break;
513 }
514
515 if ($reserve->getQuantity() > $delta)
516 {
517 $settableReserveQuantity = $reserve->getQuantity() - $delta;
518 $reserve->setFieldNoDemand('QUANTITY', $settableReserveQuantity);
519
520 break;
521 }
522
523 $delta -= $reserve->getQuantity();
524 $reserve->deleteNoDemand();
525 }
526 }
527
528 return $result;
529 }
530
534 public function getReservedQuantity(): float
535 {
536 return $this->getField('RESERVED_QUANTITY');
537 }
538
542 public function getBasketId()
543 {
544 return (int)$this->getField('BASKET_ID');
545 }
546
551 public function getBasketCode()
552 {
553 if ($basketItem = $this->getBasketItem())
554 {
555 return $basketItem->getBasketCode();
556 }
557
558 return null;
559 }
560
565 public function getProductId()
566 {
567 $basketItem = $this->getBasketItem();
568 if ($basketItem)
569 {
570 return $basketItem->getProductId();
571 }
572
573 return null;
574 }
575
586 public function save()
587 {
588 $this->checkCallingContext();
589
590 $result = new Result();
591
592 $id = $this->getId();
593 $fields = $this->fields->getValues();
594
595 $shipment = $this->getCollection()->getShipment();
596
598 $order = $shipment->getCollection()->getOrder();
599
600 if ($this->isChanged())
601 {
603 $event = new Main\Event('sale', 'OnBeforeSaleShipmentItemEntitySaved', [
604 'ENTITY' => $this,
605 'VALUES' => $this->fields->getOriginalValues()
606 ]);
607 $event->send();
608 }
609
610 if ($id > 0)
611 {
612 $fields = $this->fields->getChangedValues();
613
614 if (!empty($fields) && is_array($fields))
615 {
616 if (!$shipment->isSystem())
617 {
618 if (isset($fields["QUANTITY"]) && (floatval($fields["QUANTITY"]) == 0))
619 {
620 return $result;
621 }
622 }
623
624 $r = $this->updateInternal($id, $fields);
625 if (!$r->isSuccess())
626 {
627 $registry = Registry::getInstance(static::getRegistryType());
628
630 $orderHistory = $registry->getOrderHistoryClassName();
631 $orderHistory::addAction(
632 'SHIPMENT',
633 $order->getId(),
634 'SHIPMENT_ITEM_UPDATE_ERROR',
635 $id,
636 $this,
637 ["ERROR" => $r->getErrorMessages()]
638 );
639
640 $result->addErrors($r->getErrors());
641 return $result;
642 }
643
644 if ($resultData = $r->getData())
645 $result->setData($resultData);
646 }
647
648 if ($order && $order->getId() > 0)
649 {
650 $registry = Registry::getInstance(static::getRegistryType());
651
653 $orderHistory = $registry->getOrderHistoryClassName();
654 $orderHistory::collectEntityFields('SHIPMENT_ITEM_STORE', $order->getId(), $id);
655 }
656 }
657 else
658 {
659 $fields['ORDER_DELIVERY_ID'] = $this->getParentShipmentId();
660 $this->setFieldNoDemand('ORDER_DELIVERY_ID', $fields['ORDER_DELIVERY_ID']);
661
662 $fields['DATE_INSERT'] = new Main\Type\DateTime();
663 $this->setFieldNoDemand('DATE_INSERT', $fields['DATE_INSERT']);
664
665 $fields["BASKET_ID"] = $this->basketItem->getId();
666 $this->setFieldNoDemand('BASKET_ID', $fields['BASKET_ID']);
667
668 if ($fields['BASKET_ID'] <= 0)
669 {
670 return $result;
671 }
672
673 if (!isset($fields["QUANTITY"]) || (floatval($fields["QUANTITY"]) == 0))
674 {
675 return $result;
676 }
677
678 $r = $this->addInternal($fields);
679 if (!$r->isSuccess())
680 {
681 $registry = Registry::getInstance(static::getRegistryType());
682
684 $orderHistory = $registry->getOrderHistoryClassName();
685 $orderHistory::addAction(
686 'SHIPMENT',
687 $order->getId(),
688 'SHIPMENT_ITEM_ADD_ERROR',
689 null,
690 $this,
691 ["ERROR" => $r->getErrorMessages()]
692 );
693
694 $result->addErrors($r->getErrors());
695 return $result;
696 }
697
698 if ($resultData = $r->getData())
699 $result->setData($resultData);
700
701 $id = $r->getId();
702 $this->setFieldNoDemand('ID', $id);
703
704 if (!$shipment->isSystem())
705 {
706 $registry = Registry::getInstance(static::getRegistryType());
707
709 $orderHistory = $registry->getOrderHistoryClassName();
710 $orderHistory::addAction(
711 'SHIPMENT',
712 $order->getId(),
713 'SHIPMENT_ITEM_BASKET_ADDED',
714 $shipment->getId(),
715 $this->basketItem,
716 [
717 'QUANTITY' => $this->getQuantity(),
718 ]
719 );
720 }
721 }
722
723 if ($id > 0)
724 {
725 $result->setId($id);
726 }
727
728 if ($this->isChanged())
729 {
731 $event = new Main\Event('sale', 'OnSaleShipmentItemEntitySaved', [
732 'ENTITY' => $this,
733 'VALUES' => $this->fields->getOriginalValues(),
734 ]);
735 $event->send();
736 }
737
738 $shipmentItemStoreCollection = $this->getShipmentItemStoreCollection();
740 {
741 $r = $shipmentItemStoreCollection->save();
742 if (!$r->isSuccess())
743 {
744 $result->addErrors($r->getErrors());
745 }
746 }
747
748 if ($result->isSuccess())
749 {
750 $registry = Registry::getInstance(static::getRegistryType());
751
753 $orderHistory = $registry->getOrderHistoryClassName();
754 $orderHistory::collectEntityFields('SHIPMENT_ITEM', $order->getId(), $id);
755 }
756
757 return $result;
758 }
759
760
761
765 private function checkCallingContext()
766 {
768 if (!$shipmentItemCollection = $this->getCollection())
769 {
770 throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
771 }
772
774 if (!$shipment = $shipmentItemCollection->getShipment())
775 {
776 throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
777 }
778
780 if (!$shipmentCollection = $shipment->getCollection())
781 {
782 throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
783 }
784
786 if (!$order = $shipmentCollection->getOrder())
787 {
788 throw new Main\ObjectNotFoundException('Entity "Order" not found');
789 }
790
791 if (!$order->isSaveRunning())
792 {
793 trigger_error("Incorrect call to the save process. Use method save() on \Bitrix\Sale\Order entity", E_USER_WARNING);
794 }
795 }
796
797 private function getParentShipmentId()
798 {
800 $collection = $this->getCollection();
801 $shipment = $collection->getShipment();
802 return $shipment->getId();
803 }
804
811 public static function loadForShipment($id)
812 {
813 if (intval($id) <= 0)
814 throw new Main\ArgumentNullException("id");
815
816 $items = [];
817
818 $itemDataList = static::getList([
819 'filter' => [
820 '=ORDER_DELIVERY_ID' => $id,
821 '!BASKET.ID' => null
822 ],
823 'order' => ['DATE_INSERT' => 'ASC', 'ID' => 'ASC']
824 ]);
825
826 while ($itemData = $itemDataList->fetch())
827 $items[] = static::createShipmentItemObject($itemData);
828
829 return $items;
830 }
831
836 private static function createShipmentItemObject(array $itemData = [])
837 {
838 $registry = Registry::getInstance(static::getRegistryType());
839 $shipmentItemClassName = $registry->getShipmentItemClassName();
840
841 return new $shipmentItemClassName($itemData);
842 }
843
847 public static function getRegistryType()
848 {
850 }
851
855 public static function getRegistryEntity()
856 {
858 }
859
864 protected function loadBasketItem()
865 {
867 $collection = $this->getCollection();
868
870 if (!$shipment = $collection->getShipment())
871 {
872 throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
873 }
874
876 if (!$shipmentCollection = $shipment->getCollection())
877 {
878 throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
879 }
880
882 if (!$order = $shipmentCollection->getOrder())
883 {
884 throw new Main\ObjectNotFoundException('Entity "Order" not found');
885 }
886
888 if (!$basket = $order->getBasket())
889 {
890 throw new Main\ObjectNotFoundException('Entity "Basket" not found');
891 }
892
893 // [performance]
894 // new ShipmentItem binds BasketItem on initialization
895 // here we find BasketItem for already saved ShipmentItem (his ID is equal to CODE)
896 return $basket->getItemByBasketCode($this->getBasketId());
897 }
898
902 public function getBasketItem()
903 {
904 if ($this->basketItem == null)
905 {
906 $this->basketItem = $this->loadBasketItem();
907 }
908
909 return $this->basketItem;
910 }
911
915 public function getShipmentItemStoreCollection()
916 {
917 if (!$this->getBasketItem()->isReservableItem())
918 {
919 return null;
920 }
921
922 if (empty($this->shipmentItemStoreCollection))
923 {
924 $registry = Registry::getInstance(static::getRegistryType());
925
927 $itemStoreCollectionClassName = $registry->getShipmentItemStoreCollectionClassName();
928 $this->shipmentItemStoreCollection = $itemStoreCollectionClassName::load($this);
929 }
930
932 }
933
947 public function onBasketModify($action, BasketItem $basketItem, $name = null, $oldValue = null, $value = null)
948 {
949 $result = new Result();
950
951 if ($action === EventActions::ADD)
952 {
953 $this->setFieldNoDemand('QUANTITY', $basketItem->getQuantity());
954 }
955
956 return $result;
957 }
958
963 protected function calculateDelivery()
964 {
965 $result = new Result();
966
968 $collection = $this->getCollection();
970 $shipment = $collection->getShipment();
971
973 $shipmentCollection = $shipment->getCollection();
974
976 $order = $shipmentCollection->getOrder();
977
978 if ($order->getId() > 0)
979 {
980 return $result;
981 }
982
983 $deliveryCalculate = $shipment->calculateDelivery();
984 if (!$deliveryCalculate->isSuccess())
985 {
986 $result->addErrors($deliveryCalculate->getErrors());
987 }
988
989 if ($deliveryCalculate->getPrice() > 0)
990 {
991 $shipment->setField('BASE_PRICE_DELIVERY', $deliveryCalculate->getPrice());
992 }
993
994 return $result;
995 }
996
997
1004 protected function addChangesToHistory($name, $oldValue = null, $value = null)
1005 {
1006 if ($this->getId() > 0)
1007 {
1009 if (!$shipmentItemCollection = $this->getCollection())
1010 {
1011 throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
1012 }
1013
1015 if (!$shipment = $shipmentItemCollection->getShipment())
1016 {
1017 throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
1018 }
1019
1020 if ($shipment->isSystem())
1021 return;
1022
1024 if (!$shipmentCollection = $shipment->getCollection())
1025 {
1026 throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
1027 }
1028
1029 $historyFields = [];
1030
1032 if ($basketItem = $this->getBasketItem())
1033 {
1034 $historyFields = [
1035 'NAME' => $basketItem->getField('NAME'),
1036 'PRODUCT_ID' => $basketItem->getField('PRODUCT_ID'),
1037 ];
1038 }
1039
1041 if (($order = $shipmentCollection->getOrder()) && $order->getId() > 0)
1042 {
1043 $registry = Registry::getInstance(static::getRegistryType());
1044
1046 $orderHistory = $registry->getOrderHistoryClassName();
1047 $orderHistory::addField(
1048 'SHIPMENT_ITEM',
1049 $order->getId(),
1050 $name,
1051 $oldValue,
1052 $value,
1053 $this->getId(),
1054 $this,
1055 $historyFields
1056 );
1057 }
1058
1059
1060 }
1061 }
1062
1066 public function isChanged()
1067 {
1068 if (parent::isChanged())
1069 {
1070 return true;
1071 }
1072
1073 $shipmentItemStoreCollection = $this->getShipmentItemStoreCollection();
1075 }
1076
1082 public function tryReserve()
1083 {
1084 return Internals\Catalog\Provider::tryReserveShipmentItem($this);
1085 }
1086
1092 public function tryUnreserve()
1093 {
1094 return Internals\Catalog\Provider::tryUnreserveShipmentItem($this);
1095 }
1096
1097
1102 public function verify()
1103 {
1104 $result = new Result();
1105
1107 if (!$shipmentItemCollection = $this->getCollection())
1108 {
1109 throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
1110 }
1111
1113 if (!$shipment = $shipmentItemCollection->getShipment())
1114 {
1115 throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
1116 }
1117
1118 if (!$this->getBasketItem())
1119 {
1120 $result->addError(
1121 new ResultError(
1123 'SALE_SHIPMENT_ITEM_BASKET_ITEM_NOT_FOUND',
1124 [
1125 '#BASKET_ITEM_ID#' => $this->getBasketId(),
1126 '#SHIPMENT_ID#' => $shipment->getId(),
1127 '#SHIPMENT_ITEM_ID#' => $this->getId(),
1128 ]
1129 ), 'SALE_SHIPMENT_ITEM_BASKET_ITEM_NOT_FOUND'
1130 )
1131 );
1132
1133 return $result;
1134 }
1135
1136 if ($this->getQuantity() <= 0)
1137 {
1138 $result->addError(
1139 new ResultError(
1141 'SALE_SHIPMENT_ITEM_ERR_QUANTITY_EMPTY',
1142 [
1143 '#BASKET_ITEM_NAME#' => $this->getBasketItem()->getField('NAME'),
1144 ]
1145 ), 'SALE_SHIPMENT_ITEM_ERR_QUANTITY_EMPTY'
1146 )
1147 );
1148
1149 return $result;
1150 }
1151
1153 if ($shipmentItemStoreCollection = $this->getShipmentItemStoreCollection())
1154 {
1156 foreach ($shipmentItemStoreCollection as $shipmentItemStore)
1157 {
1158 $r = $shipmentItemStore->verify();
1159 if (!$r->isSuccess())
1160 {
1161 $result->addErrors($r->getErrors());
1162 }
1163 }
1164 }
1165
1166 return $result;
1167 }
1168
1175 public static function getList(array $parameters)
1176 {
1177 return Internals\ShipmentItemTable::getList($parameters);
1178 }
1179
1193 public function createClone(\SplObjectStorage $cloneEntity)
1194 {
1195 if ($this->isClone() && $cloneEntity->contains($this))
1196 {
1197 return $cloneEntity[$this];
1198 }
1199
1201 $shipmentItemClone = parent::createClone($cloneEntity);
1202
1204 if ($basketItem = $this->getBasketItem())
1205 {
1206 if (!$cloneEntity->contains($basketItem))
1207 {
1208 $cloneEntity[$basketItem] = $basketItem->createClone($cloneEntity);
1209 }
1210
1211 if ($cloneEntity->contains($basketItem))
1212 {
1213 $shipmentItemClone->basketItem = $cloneEntity[$basketItem];
1214 }
1215 }
1216
1218 if ($shipmentItemStoreCollection = $this->getShipmentItemStoreCollection())
1219 {
1220 if (!$cloneEntity->contains($shipmentItemStoreCollection))
1221 {
1222 $cloneEntity[$shipmentItemStoreCollection] = $shipmentItemStoreCollection->createClone($cloneEntity);
1223 }
1224
1225 if ($cloneEntity->contains($shipmentItemStoreCollection))
1226 {
1227 $shipmentItemClone->shipmentItemStoreCollection = $cloneEntity[$shipmentItemStoreCollection];
1228 }
1229 }
1230
1231 return $shipmentItemClone;
1232 }
1233
1234
1240 public function getErrorEntity($value)
1241 {
1242 static $className = null;
1243 $errorsList = static::getAutoFixErrorsList();
1244 if (is_array($errorsList) && in_array($value, $errorsList))
1245 {
1246 if ($className === null)
1247 $className = static::getClassName();
1248 }
1249 else
1250 {
1252 if ($shipmentItemStoreCollection = $this->getShipmentItemStoreCollection())
1253 {
1254 $className = $shipmentItemStoreCollection->getErrorEntity($value);
1255 }
1256 }
1257
1258 return $className;
1259 }
1260
1261
1267 public function canAutoFixError($value)
1268 {
1269 $autoFix = false;
1270 $errorsList = static::getAutoFixErrorsList();
1271 if (is_array($errorsList) && in_array($value, $errorsList))
1272 {
1273 $autoFix = true;
1274 }
1275 else
1276 {
1278 if ($shipmentItemStoreCollection = $this->getShipmentItemStoreCollection())
1279 {
1280 $autoFix = $shipmentItemStoreCollection->canAutoFixError($value);
1281 }
1282 }
1283
1284 return $autoFix;
1285 }
1286
1290 public function getAutoFixErrorsList()
1291 {
1292 return [];
1293 }
1294
1300 public function tryFixError($code)
1301 {
1302 return new Result();
1303 }
1304
1305 public function canMarked()
1306 {
1307 return false;
1308 }
1309
1310 public function getMarkField()
1311 {
1312 return null;
1313 }
1314
1318 public function clearChanged()
1319 {
1320 parent::clearChanged();
1321
1322 if ($shipmentItemStoreCollection = $this->getShipmentItemStoreCollection())
1323 {
1324 foreach ($shipmentItemStoreCollection as $shipmentItemStore)
1325 {
1326 $shipmentItemStore->clearChanged();
1327 }
1328 }
1329 }
1330
1336 public function needReserve()
1337 {
1338 return
1339 $this->fields->isChanged('RESERVED_QUANTITY')
1340 || $this->getCollection()->getShipment()->getField('RESERVED') == 'Y'
1341 ;
1342 }
1343
1348 public function getNeedReserveQuantity()
1349 {
1350 if (!$this->needReserve())
1351 {
1352 return 0;
1353 }
1354
1355 $changedFields = $this->fields->getChangedValues();
1356 $originalFields = $this->fields->getOriginalValues();
1357
1358 return $changedFields['RESERVED_QUANTITY'] - $originalFields['RESERVED_QUANTITY'];
1359 }
1360
1366 protected function addInternal(array $data)
1367 {
1368 return Internals\ShipmentItemTable::add($data);
1369 }
1370
1377 protected function updateInternal($primary, array $data)
1378 {
1379 return Internals\ShipmentItemTable::update($primary, $data);
1380 }
1381
1385 protected static function getFieldsMap()
1386 {
1387 return Internals\ShipmentItemTable::getMap();
1388 }
1389
1395 public static function getEntityEventName()
1396 {
1397 return 'SaleShipmentItem';
1398 }
1399
1403 public function toArray(): array
1404 {
1405 $result = parent::toArray();
1406
1407 $shipmentItemStoreCollection = $this->getShipmentItemStoreCollection();
1408 $result['STORES'] = $shipmentItemStoreCollection ? $shipmentItemStoreCollection->toArray() : [];
1409
1410 return $result;
1411 }
1412
1418 public function isShippable(): bool
1419 {
1420 $basketItem = $this->getBasketItem();
1421 if ($basketItem)
1422 {
1423 return !$basketItem->isBundleParent() && !$basketItem->isService();
1424 }
1425
1426 return true;
1427 }
1428}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getInstance($type)
Definition registry.php:183
updateInternal($primary, array $data)
static getList(array $parameters)
setFieldNoDemand($name, $value)
onBasketModify($action, BasketItem $basketItem, $name=null, $oldValue=null, $value=null)
static create(ShipmentItemCollection $collection, BasketItem $basketItem=null)
canAutoFixError($value)
getErrorEntity($value)