ShipmentLoader.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Shipping\Controller\Adminhtml\Order;
  7. use Magento\Framework\DataObject;
  8. use Magento\Framework\Exception\LocalizedException;
  9. use Magento\Framework\Message\ManagerInterface;
  10. use Magento\Framework\Registry;
  11. use Magento\Sales\Api\Data\ShipmentTrackCreationInterface;
  12. use Magento\Sales\Api\Data\ShipmentTrackCreationInterfaceFactory;
  13. use Magento\Sales\Api\Data\ShipmentItemCreationInterfaceFactory;
  14. use Magento\Sales\Api\ShipmentRepositoryInterface;
  15. use Magento\Sales\Api\OrderRepositoryInterface;
  16. use Magento\Sales\Model\Order\ShipmentDocumentFactory;
  17. use Magento\Sales\Api\Data\ShipmentItemCreationInterface;
  18. /**
  19. * Class ShipmentLoader
  20. *
  21. * @package Magento\Shipping\Controller\Adminhtml\Order
  22. * @method ShipmentLoader setOrderId($id)
  23. * @method ShipmentLoader setShipmentId($id)
  24. * @method ShipmentLoader setShipment($shipment)
  25. * @method ShipmentLoader setTracking($tracking)
  26. * @method int getOrderId()
  27. * @method int getShipmentId()
  28. * @method array getTracking()
  29. */
  30. class ShipmentLoader extends DataObject
  31. {
  32. const SHIPMENT = 'shipment';
  33. /**
  34. * @var ManagerInterface
  35. */
  36. private $messageManager;
  37. /**
  38. * @var Registry
  39. */
  40. private $registry;
  41. /**
  42. * @var ShipmentRepositoryInterface
  43. */
  44. private $shipmentRepository;
  45. /**
  46. * @var OrderRepositoryInterface
  47. */
  48. private $orderRepository;
  49. /**
  50. * @var ShipmentDocumentFactory
  51. */
  52. private $documentFactory;
  53. /**
  54. * @var ShipmentTrackCreationInterfaceFactory
  55. */
  56. private $trackFactory;
  57. /**
  58. * @var ShipmentItemCreationInterfaceFactory
  59. */
  60. private $itemFactory;
  61. /**
  62. * @param ManagerInterface $messageManager
  63. * @param Registry $registry
  64. * @param ShipmentRepositoryInterface $shipmentRepository
  65. * @param OrderRepositoryInterface $orderRepository
  66. * @param ShipmentDocumentFactory $documentFactory
  67. * @param ShipmentTrackCreationInterfaceFactory $trackFactory
  68. * @param ShipmentItemCreationInterfaceFactory $itemFactory
  69. * @param array $data
  70. */
  71. public function __construct(
  72. ManagerInterface $messageManager,
  73. Registry $registry,
  74. ShipmentRepositoryInterface $shipmentRepository,
  75. OrderRepositoryInterface $orderRepository,
  76. ShipmentDocumentFactory $documentFactory,
  77. ShipmentTrackCreationInterfaceFactory $trackFactory,
  78. ShipmentItemCreationInterfaceFactory $itemFactory,
  79. array $data = []
  80. ) {
  81. $this->messageManager = $messageManager;
  82. $this->registry = $registry;
  83. $this->shipmentRepository = $shipmentRepository;
  84. $this->orderRepository = $orderRepository;
  85. $this->documentFactory = $documentFactory;
  86. $this->trackFactory = $trackFactory;
  87. $this->itemFactory = $itemFactory;
  88. parent::__construct($data);
  89. }
  90. /**
  91. * Initialize shipment model instance
  92. *
  93. * @return bool|\Magento\Sales\Model\Order\Shipment
  94. * @throws \Magento\Framework\Exception\LocalizedException
  95. */
  96. public function load()
  97. {
  98. $shipment = false;
  99. $orderId = $this->getOrderId();
  100. $shipmentId = $this->getShipmentId();
  101. if ($shipmentId) {
  102. $shipment = $this->shipmentRepository->get($shipmentId);
  103. } elseif ($orderId) {
  104. $order = $this->orderRepository->get($orderId);
  105. /**
  106. * Check order existing
  107. */
  108. if (!$order->getId()) {
  109. $this->messageManager->addError(__('The order no longer exists.'));
  110. return false;
  111. }
  112. /**
  113. * Check shipment is available to create separate from invoice
  114. */
  115. if ($order->getForcedShipmentWithInvoice()) {
  116. $this->messageManager->addError(__('Cannot do shipment for the order separately from invoice.'));
  117. return false;
  118. }
  119. /**
  120. * Check shipment create availability
  121. */
  122. if (!$order->canShip()) {
  123. $this->messageManager->addError(__('Cannot do shipment for the order.'));
  124. return false;
  125. }
  126. $shipmentItems = $this->getShipmentItems($this->getShipment());
  127. $shipment = $this->documentFactory->create(
  128. $order,
  129. $shipmentItems,
  130. $this->getTrackingArray()
  131. );
  132. }
  133. $this->registry->register('current_shipment', $shipment);
  134. return $shipment;
  135. }
  136. /**
  137. * Convert UI-generated tracking array to Data Object array
  138. *
  139. * @return ShipmentTrackCreationInterface[]
  140. * @throws LocalizedException
  141. */
  142. private function getTrackingArray()
  143. {
  144. $tracks = $this->getTracking() ?: [];
  145. $trackingCreation = [];
  146. foreach ($tracks as $track) {
  147. if (!isset($track['number']) || !isset($track['title']) || !isset($track['carrier_code'])) {
  148. throw new LocalizedException(
  149. __('Tracking information must contain title, carrier code, and tracking number')
  150. );
  151. }
  152. /** @var ShipmentTrackCreationInterface $trackCreation */
  153. $trackCreation = $this->trackFactory->create();
  154. $trackCreation->setTrackNumber($track['number']);
  155. $trackCreation->setTitle($track['title']);
  156. $trackCreation->setCarrierCode($track['carrier_code']);
  157. $trackingCreation[] = $trackCreation;
  158. }
  159. return $trackingCreation;
  160. }
  161. /**
  162. * Extract product id => product quantity array from shipment data.
  163. *
  164. * @param array $shipmentData
  165. * @return int[]
  166. */
  167. private function getShipmentItems(array $shipmentData)
  168. {
  169. $shipmentItems = [];
  170. $itemQty = isset($shipmentData['items']) ? $shipmentData['items'] : [];
  171. foreach ($itemQty as $itemId => $quantity) {
  172. /** @var ShipmentItemCreationInterface $item */
  173. $item = $this->itemFactory->create();
  174. $item->setOrderItemId($itemId);
  175. $item->setQty($quantity);
  176. $shipmentItems[] = $item;
  177. }
  178. return $shipmentItems;
  179. }
  180. /**
  181. * Retrieve shipment
  182. *
  183. * @return array
  184. */
  185. public function getShipment()
  186. {
  187. return $this->getData(self::SHIPMENT) ?: [];
  188. }
  189. }