Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ShipmentFactory.php
Go to the documentation of this file.
1 <?php
7 
10 
17 {
23  protected $converter;
24 
30  protected $trackFactory;
31 
37  protected $instanceName;
38 
44  private $serializer;
45 
53  public function __construct(
54  \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory,
55  \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory,
56  Json $serializer = null
57  ) {
58  $this->converter = $convertOrderFactory->create();
59  $this->trackFactory = $trackFactory;
60  $this->instanceName = \Magento\Sales\Api\Data\ShipmentInterface::class;
61  $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
62  ->get(Json::class);
63  }
64 
73  public function create(\Magento\Sales\Model\Order $order, array $items = [], $tracks = null)
74  {
75  $shipment = $this->prepareItems($this->converter->toShipment($order), $order, $items);
76 
77  if ($tracks) {
79  }
80 
81  return $shipment;
82  }
83 
94  protected function prepareItems(
96  \Magento\Sales\Model\Order $order,
97  array $items = []
98  ) {
99  $shipmentItems = [];
100  foreach ($order->getAllItems() as $orderItem) {
101  if ($this->validateItem($orderItem, $items) === false) {
102  continue;
103  }
104 
106  $item = $this->converter->itemToShipmentItem($orderItem);
107  if ($orderItem->getIsVirtual() || ($orderItem->getParentItemId() && !$orderItem->isShipSeparately())) {
108  $item->isDeleted(true);
109  }
110 
111  if ($orderItem->isDummy(true)) {
112  $qty = 0;
113 
114  if (isset($items[$orderItem->getParentItemId()])) {
115  $productOptions = $orderItem->getProductOptions();
116 
117  if (isset($productOptions['bundle_selection_attributes'])) {
118  $bundleSelectionAttributes = $this->serializer->unserialize(
119  $productOptions['bundle_selection_attributes']
120  );
121 
122  if ($bundleSelectionAttributes) {
123  $qty = $bundleSelectionAttributes['qty'] * $items[$orderItem->getParentItemId()];
124  $qty = min($qty, $orderItem->getSimpleQtyToShip());
125 
126  $item->setQty($this->castQty($orderItem, $qty));
127  $shipmentItems[] = $item;
128  continue;
129  } else {
130  $qty = 1;
131  }
132  }
133  } else {
134  $qty = 1;
135  }
136  } else {
137  if (isset($items[$orderItem->getId()])) {
138  $qty = min($items[$orderItem->getId()], $orderItem->getQtyToShip());
139  } elseif (!count($items)) {
140  $qty = $orderItem->getQtyToShip();
141  } else {
142  continue;
143  }
144  }
145 
146  $item->setQty($this->castQty($orderItem, $qty));
147  $shipmentItems[] = $item;
148  }
149  return $this->setItemsToShipment($shipment, $shipmentItems);
150  }
151 
159  private function validateItem(\Magento\Sales\Model\Order\Item $orderItem, array $items)
160  {
161  if (!$this->canShipItem($orderItem, $items)) {
162  return false;
163  }
164 
165  // Remove from shipment items without qty or with qty=0
166  if (!$orderItem->isDummy(true)
167  && (!isset($items[$orderItem->getId()]) || $items[$orderItem->getId()] <= 0)
168  ) {
169  return false;
170  }
171  return true;
172  }
173 
181  private function setItemsToShipment(\Magento\Sales\Api\Data\ShipmentInterface $shipment, $shipmentItems)
182  {
183  $totalQty = 0;
184 
189  foreach ($shipmentItems as $key => $shipmentItem) {
190  if ($shipmentItem->getOrderItem()->getHasChildren()
191  && $shipmentItem->getOrderItem()->isShipSeparately()
192  ) {
193  $containerId = $shipmentItem->getOrderItem()->getId();
194  $childItems = array_filter($shipmentItems, function ($item) use ($containerId) {
195  return $containerId == $item->getOrderItem()->getParentItemId();
196  });
197 
198  if (count($childItems) <= 0) {
199  unset($shipmentItems[$key]);
200  continue;
201  }
202  }
203  $totalQty += $shipmentItem->getQty();
204  $shipment->addItem($shipmentItem);
205  }
206  return $shipment->setTotalQty($totalQty);
207  }
208 
217  protected function prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks)
218  {
219  foreach ($tracks as $data) {
220  if (empty($data['number'])) {
221  throw new \Magento\Framework\Exception\LocalizedException(
222  __('Please enter a tracking number.')
223  );
224  }
225 
226  $shipment->addTrack(
227  $this->trackFactory->create()->addData($data)
228  );
229  }
230 
231  return $shipment;
232  }
233 
245  protected function canShipItem($item, array $items = [])
246  {
247  if ($item->getIsVirtual() || $item->getLockedDoShip()) {
248  return false;
249  }
250 
251  if ($item->isDummy(true)) {
252  if ($item->getHasChildren()) {
253  if ($item->isShipSeparately()) {
254  return true;
255  }
256 
257  foreach ($item->getChildrenItems() as $child) {
258  if ($child->getIsVirtual()) {
259  continue;
260  }
261 
262  if (empty($items)) {
263  if ($child->getQtyToShip() > 0) {
264  return true;
265  }
266  } else {
267  if (isset($items[$child->getId()]) && $items[$child->getId()] > 0) {
268  return true;
269  }
270  }
271  }
272 
273  return false;
274  } elseif ($item->getParentItem()) {
275  $parent = $item->getParentItem();
276 
277  if (empty($items)) {
278  return $parent->getQtyToShip() > 0;
279  } else {
280  return isset($items[$parent->getId()]) && $items[$parent->getId()] > 0;
281  }
282  }
283  } else {
284  return $item->getQtyToShip() > 0;
285  }
286  }
287 
293  private function castQty(\Magento\Sales\Model\Order\Item $item, $qty)
294  {
295  if ($item->getIsQtyDecimal()) {
296  $qty = (double)$qty;
297  } else {
298  $qty = (int)$qty;
299  }
300 
301  return $qty > 0 ? $qty : 0;
302  }
303 }
create(\Magento\Sales\Model\Order $order, array $items=[], $tracks=null)
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$orderItem
Definition: order.php:30
$containerId
Definition: fieldset.phtml:13
$order
Definition: order.php:55
__()
Definition: __.php:13
$shipmentItem
prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks)
__construct(\Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory, \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory, Json $serializer=null)
foreach($order->getItems() as $orderItem) $shipment
$items