Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
shipmentimport.php
1<?php
3
14
15IncludeModuleLangFile(__FILE__);
16
23{
24 protected static $currentSettingsStores = null;
25
26 public function __construct($parentEntityContext = null)
27 {
28 parent::__construct($parentEntityContext);
29 }
30
34 public function getOwnerTypeId()
35 {
36 return Exchange\EntityType::SHIPMENT;
37 }
38
43 public function setEntity(Internals\Entity $entity)
44 {
45 if(!($entity instanceof Shipment))
46 throw new Main\ArgumentException("Entity must be instanceof Shipment");
47
48 $this->entity = $entity;
49 }
50
55 protected function checkFields(array $fields)
56 {
57 $result = new Sale\Result();
58
59 if(intval($fields['ORDER_ID'])<=0 &&
60 !$this->isLoadedParentEntity()
61 )
62 {
63 $result->addError(new Error('ORDER_ID is not defined',''));
64 }
65
66 return $result;
67 }
68
72 public function save()
73 {
76 return $parentEntity->save();
77 }
78
83 public function add(array $params)
84 {
85 $result = new Sale\Result();
86
87 if(!$this->isLoadedParentEntity())
88 {
89 $result->addError(new Error(GetMessage('SALE_EXCHANGE_ENTITY_SHIPMENT_ORDER_IS_NOT_LOADED_ERROR'),'ENTITY_SHIPMENT_ORDER_IS_NOT_LOADED_ERROR'));
90 return $result;
91 }
92
93 $fields = $params['TRAITS'];
95
96 if(($shipmentService = Manager::getObjectById($fields['DELIVERY_ID'])) == null)
97 {
98 $result->addError(new Error(GetMessage('SALE_EXCHANGE_ENTITY_SHIPMENT_DELIVERY_SERVICE_IS_NOT_AVAILABLE_ERROR'),'DELIVERY_SERVICE_IS_NOT_AVAILABLE_ERROR'));
99 }
100 else
101 {
102 $shipmentCollection = $parentEntity->getShipmentCollection();
103 $shipment = $shipmentCollection->createItem($shipmentService);
104
105 $shipment->setField('DELIVERY_NAME', $shipmentService->getName());
106
107 $basket = $parentEntity->getBasket();
108 $result = $this->fillShipmentItems($shipment, $basket, $params);
109 if(!$result->isSuccess())
110 {
111 return $result;
112 }
113
114 $result = $shipment->setFields($fields);
115
116 if($result->isSuccess())
117 {
118 $this->setEntity($shipment);
119 }
120 }
121
122 return $result;
123 }
124
129 public function update(array $params)
130 {
131 $result = new Sale\Result();
132
133 if(!$this->isLoadedParentEntity())
134 {
135 $result->addError(new Error(GetMessage('SALE_EXCHANGE_ENTITY_SHIPMENT_ORDER_IS_NOT_LOADED_ERROR'),'ORDER_IS_NOT_LOADED_ERROR'));
136 return $result;
137 }
138
140 $shipment = $this->getEntity();
141
143
144 $criterion = $this->getCurrentCriterion($this->getEntity());
145
146 $fields = $params['TRAITS'];
147 if($criterion->equals($fields))
148 {
149 $basket = $parentEntity->getBasket();
150 $result = $this->fillShipmentItems($shipment, $basket, $params);
151 if(!$result->isSuccess())
152 {
153 return $result;
154 }
155 }
156
157 $result = $shipment->setFields($fields);
158
159 return $result;
160 }
161
167 public function delete(array $params = null)
168 {
170 $entity = $this->getEntity();
171 $result = $entity->delete();
172 if($result->isSuccess())
173 {
174 //$this->setCollisions(EntityCollisionType::OrderShipmentDeleted, $this->getParentEntity());
175 }
176 else
177 {
178 $this->setCollisions(EntityCollisionType::OrderShipmentDeletedError, $this->getParentEntity(), implode(',', $result->getErrorMessages()));
179 }
180
181 return $result;
182 }
183
187 protected function getExternalFieldName()
188 {
189 return 'EXTERNAL_DELIVERY';
190 }
191
198 public function load(array $fields)
199 {
200 $r = $this->checkFields($fields);
201 if(!$r->isSuccess())
202 {
203 throw new Main\ArgumentException('ORDER_ID is not defined');
204 }
205
206 if(!$this->isLoadedParentEntity() && !empty($fields['ORDER_ID']))
207 {
208 $this->setParentEntity(
209 $this->loadParentEntity(['ID'=>$fields['ORDER_ID']])
210 );
211 }
212
213 if($this->isLoadedParentEntity())
214 {
216
217 if(!empty($fields['ID']))
218 {
219 $shipment = $parentEntity->getShipmentCollection()->getItemById($fields['ID']);
220 }
221
223 if(!empty($shipment) && !$shipment->isSystem())
224 {
225 $this->setEntity($shipment);
226 }
227 else
228 {
229 $this->setExternal();
230 }
231 }
232 return new Sale\Result();
233 }
234
241 private function getBasketItemQuantity(Order $order, Sale\BasketItem $basketItem)
242 {
243 $allQuantity = 0;
245 foreach ($order->getShipmentCollection() as $shipment)
246 {
247 if($shipment->isShipped())
248 continue;
249
250 $allQuantity += $shipment->getBasketItemQuantity($basketItem);
251 }
252
253 return $allQuantity;
254 }
255
261 protected function getBasketItemByItem(Sale\BasketBase $basket, array $item)
262 {
263 return OrderImport::getBasketItemByItem($basket, $item);
264 }
265
273 private function fillShipmentItems(Shipment $shipment, Sale\BasketBase $basket, array $params)
274 {
275 $result = new Sale\Result();
276
278 $order = $basket->getOrder();
279
280 $fieldsBasketItems = $params['ITEMS'];
281
282 if(is_array($fieldsBasketItems))
283 {
284 foreach($fieldsBasketItems as $items)
285 {
286 foreach($items as $productXML_ID => $item)
287 {
289 continue;
290
291 if($item['TYPE'] == Exchange\ImportBase::ITEM_ITEM)
292 {
293 if($basketItem = $this->getBasketItemByItem($basket, $item))
294 {
295 $basketItemQuantity = $this->getBasketItemQuantity($order, $basketItem);
296
297 $shipmentItem = static::getShipmentItem($shipment, $basketItem);
298
299 $deltaQuantity = $item['QUANTITY'] - $shipmentItem->getQuantity();
300
301 if($deltaQuantity < 0)
302 {
303 $result = $this->fillShipmentItem($shipmentItem, 0, abs($deltaQuantity));
304 }
305 elseif($deltaQuantity > 0)
306 {
307 if($basketItemQuantity >= $item['QUANTITY'])
308 {
309 $systemShipment = $order->getShipmentCollection()->getSystemShipment();
310 $systemBasketQuantity = $systemShipment->getBasketItemQuantity($basketItem);
311
312 if($systemBasketQuantity >= $deltaQuantity)
313 {
314 $this->fillShipmentItem($shipmentItem, $item['QUANTITY'], $shipmentItem->getQuantity());
315 }
316 else
317 {
318 $needQuantity = $deltaQuantity - $systemBasketQuantity;
319
320 $r = $this->synchronizeQuantityShipmentItems($basketItem, $needQuantity);
321 if($r->isSuccess())
322 {
323 $this->fillShipmentItem($shipmentItem, $item['QUANTITY'], $shipmentItem->getQuantity());
324 }
325 else
326 {
328 }
329 }
330 }
331 else
332 {
334 }
335 }
336
337 if (
338 isset($item['MARKINGS'])
339 && is_array($item['MARKINGS'])
340 && count($item['MARKINGS']) > 0
341 )
342 {
343 $result = $this->fillMarkingsShipmentItem($shipmentItem, $item['MARKINGS']);
344 }
345 }
346 else
347 {
349 }
350 }
351 else
352 {
353 $this->setCollisions(EntityCollisionType::OrderBasketItemTypeError, $shipment, $item['NAME']);
354 }
355 }
356 }
357 }
358 return $result;
359 }
360
367 private static function getShipmentItem(Sale\Shipment $shipment, Sale\BasketItem $basketItem)
368 {
370 if (!$shipmentItemCollection = $shipment->getShipmentItemCollection())
371 {
372 throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
373 }
374
375 $shipmentItem = $shipmentItemCollection->getItemByBasketCode($basketItem->getBasketCode());
376 if (empty($shipmentItem))
377 {
378 $shipmentItem = $shipmentItemCollection->createItem($basketItem);
379 }
380 return $shipmentItem;
381 }
382
383 protected function fillMarkingsShipmentItem(Sale\ShipmentItem $item, $markings)
384 {
385 $result = new Sale\Result();
386
387 $itemStoreCollection = $item->getShipmentItemStoreCollection();
388 if (!$itemStoreCollection)
389 {
390 return $result;
391 }
392
393 $this->resetMarkingsShipmentItem($item);
394
395 $delta = min(count($markings), $item->getQuantity());
396
397 if ($itemStoreCollection->count() < $delta)
398 {
399 for ($i = (count($markings) - $itemStoreCollection->count()); $i > 0; $i--)
400 {
401 $itemStore = $itemStoreCollection->createItem($itemStoreCollection->getShipmentItem()->getBasketItem());
402 $r = $itemStore->setFields([
403 'QUANTITY'=>1
404 ]);
405
406 if($r->isSuccess() === false)
407 {
408 $result->addErrors($r->getErrors());
409 break 1;
410 }
411 }
412 }
413
414 if ($result->isSuccess())
415 {
416 $k = 0;
418 foreach ($itemStoreCollection as $storeItem)
419 {
420 $r = $storeItem->setField('MARKING_CODE', $markings[$k++]);
421 if ($r->isSuccess() === false)
422 {
423 $result->addErrors($r->getErrors());
424 break 1;
425 }
426 }
427 }
428
429 return $result;
430 }
431
432 protected function resetMarkingsShipmentItem(Sale\ShipmentItem $item)
433 {
434 $itemStoreCollection = $item->getShipmentItemStoreCollection();
435 if ($itemStoreCollection)
436 {
438 foreach ($itemStoreCollection as $barcode)
439 {
440 $barcode->setField('MARKING_CODE', null);
441 }
442 }
443 }
444
445 private function syncRelationBarcodeMarkingsCode(Sale\ShipmentItem $shipmentItem, $value)
446 {
447 if ($shipmentItem->getBasketItem()->isSupportedMarkingCode())
448 {
449 $after = $shipmentItem->getQuantity() + $value;
450 if ($after < $shipmentItem->getQuantity()) // minus
451 {
452 $deltaQuantity = $shipmentItem->getQuantity() - $after;
453
454 $storeCollection = $shipmentItem->getShipmentItemStoreCollection();
455 if ($storeCollection)
456 {
458 foreach ($storeCollection as $store)
459 {
460 if ($deltaQuantity > 0)
461 {
462 $store->delete();
463 $deltaQuantity--;
464 }
465 }
466 }
467
468 }
469 }
470 }
471
478 private function fillShipmentItem(Sale\ShipmentItem $shipmentItem, $value, $oldValue)
479 {
480 $result = new Sale\Result();
481
482 $deltaQuantity = $value - $oldValue;
483
484 if($shipmentItem->getQuantity() + $deltaQuantity == 0)
485 {
486 $r = $shipmentItem->delete();
487 }
488 else
489 {
490 $this->syncRelationBarcodeMarkingsCode($shipmentItem, $deltaQuantity);
491
492 $r = $shipmentItem->setField(
493 "QUANTITY",
494 $shipmentItem->getQuantity() + $deltaQuantity
495 );
496 }
497
499 $shipmentItemCollection = $shipmentItem->getCollection();
500
502 if ($shipment = $shipmentItemCollection->getShipment())
503 {
504 if(!$r->isSuccess())
505 {
506 $result->addErrors($r->getErrors());
507 $this->setCollisions(EntityCollisionType::OrderShipmentItemsModifyError, $shipment, implode(',', $r->getErrorMessages()));
508 }
509 else
510 {
511 //$this->setCollisions(EntityCollisionType::OrderShipmentItemsModify, $shipment);
512 }
513 }
514
515 return $result;
516 }
517
532 public function synchronizeQuantityShipmentItems(Sale\BasketItem $basketItem, $needQuantity)
533 {
534 $result = new Sale\Result();
535
536 if(intval($needQuantity) <= 0)
537 {
538 return $result;
539 }
540
541 $entity = $this->getEntity();
542
544 $order = $this->getParentEntity();
545 $shipmentCollection = $order->getShipmentCollection();
546
548 foreach ($shipmentCollection as $shipment)
549 {
551 if(!empty($entity) && $entity->getId() == $shipment->getId())
552 continue;
553
554 if($shipment->isShipped() || $shipment->isSystem())
555 continue;
556
557 $basketQuantity = $shipment->getBasketItemQuantity($basketItem);
558 if(empty($basketQuantity))
559 continue;
560
561 $shipmentItem = static::getShipmentItem($shipment, $basketItem);
562
563 if($basketQuantity >= $needQuantity)
564 {
565 $this->fillShipmentItem($shipmentItem, 0, $needQuantity);
566 $needQuantity = 0;
567 }
568 else
569 {
570 $this->fillShipmentItem($shipmentItem, 0, $basketQuantity);
571 $needQuantity -= $basketQuantity;
572 }
573
575
576 if($needQuantity == 0)
577 break;
578 }
579
580 if($needQuantity != 0)
581 $result->addError(new Error(GetMessage('SALE_EXCHANGE_ENTITY_SHIPMENT_SYNCHRONIZE_QUANTITY_ERROR'), 'SYNCHRONIZE_QUANTITY_ERROR'));
582
583 return $result;
584 }
585
590 static public function getFieldsDeliveryService($fields)
591 {
592 $result = array();
593 foreach($fields["ITEMS"] as $items)
594 {
595 foreach($items as $item)
596 {
597 if($item['TYPE'] == Exchange\ImportBase::ITEM_SERVICE)
598 {
599 $result = $item;
600 break 2;
601 }
602 }
603 }
604 return $result;
605 }
606
612 {
613 $result = array();
614
615 $item = static::getFieldsDeliveryService($fields);
616 if(count($item)>0)
617 {
618 $result = array(
619 "CUSTOM_PRICE_DELIVERY" => "Y",
620 "BASE_PRICE_DELIVERY" => $item["PRICE"],
621 "CURRENCY" => $this->settings->getCurrency()
622 );
623 }
624
625 return $result;
626 }
627
631 public function refreshData(array $fields)
632 {
634 $entity = $this->getEntity();
635 if(!empty($entity) && $entity->isShipped())
636 {
637 if($fields['DEDUCTED'] == 'N')
638 $entity->setField('DEDUCTED', 'N');
639 }
640 }
641
647 public static function resolveEntityTypeId(Internals\Entity $shipment)
648 {
649 if(!($shipment instanceof Shipment))
650 throw new Main\ArgumentException("Entity must be instanceof Shipment");
651
652 return Exchange\EntityType::SHIPMENT;
653 }
654
655 public function initFields()
656 {
657 $this->setFields(
658 array(
659 'TRAITS' => $this->getFieldsTraits(),
660 'ITEMS' => $this->getFieldsItems(),
661 'STORIES' => $this->getFieldsStories()
662 )
663 );
664 }
665
670 protected function getAttributesItem(Sale\BasketItem $basket)
671 {
672 return OrderImport::getAttributesItem($basket);
673 }
674
678 protected function getFieldsItems()
679 {
680 $result = array();
681 $shipment = $this->getEntity();
682 if($shipment instanceof Shipment)
683 {
684 $order = $shipment->getParentOrder();
686 foreach ($order->getBasket() as $basket)
687 {
689 $shipmentItem = $shipment->getShipmentItemCollection()
690 ->getItemByBasketCode($basket->getBasketCode());
691
692 if($shipmentItem !== null)
693 {
694 $itemFields = $basket->getFieldValues();
695 $itemFields['QUANTITY'] = $shipmentItem->getQuantity();
696
697 $attributes = array();
698 $attributeFields = $this->getAttributesItem($basket);
699 if(count($attributeFields)>0)
700 $attributes['ATTRIBUTES'] = $attributeFields;
701
702 $result[] = array_merge($itemFields, $attributes);
703 }
704 }
705 }
706 return $result;
707 }
708
713 protected function getFieldsStories()
714 {
715 $result = array();
716 $entity = $this->getEntity();
717 if($entity instanceof Shipment)
718 {
719 $shipmentItemCollection = $entity->getShipmentItemCollection();
720 if($shipmentItemCollection->count()>0)
721 {
723 foreach ($shipmentItemCollection as $shipmentItem)
724 {
725 $shipmentItemStoreCollection = $shipmentItem->getShipmentItemStoreCollection();
726 if ($shipmentItemStoreCollection && $shipmentItemStoreCollection->count() > 0)
727 {
729 foreach ($shipmentItemStoreCollection as $shipmentItemStore)
730 {
731 $result[] = array('ID'=>$shipmentItemStore->getStoreId());
732 }
733 }
734 }
735 }
736 }
737 return $result;
738 }
739
744 static protected function getBusinessValueOrderProvider(\Bitrix\Sale\IBusinessValueProvider $entity)
745 {
746 if(!($entity instanceof Shipment))
747 throw new Main\ArgumentException("entity must be instanceof Shipment");
748
750 $collection = $entity->getCollection();
751
752 return $collection->getOrder();
753 }
754}
setParentEntity(Sale\Order $parentEntity)
setCollisions($tipeId, Sale\Internals\Entity $entity, $message=null)
getBasketItemByItem(Sale\BasketBase $basket, array $item)
static resolveEntityTypeId(Internals\Entity $shipment)
static getBusinessValueOrderProvider(\Bitrix\Sale\IBusinessValueProvider $entity)