Save.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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\Shipment;
  7. use Magento\Framework\App\Action\HttpPostActionInterface;
  8. use Magento\Framework\Controller\ResultFactory;
  9. use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator;
  10. /**
  11. * Class Save
  12. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  13. */
  14. class Save extends \Magento\Backend\App\Action implements HttpPostActionInterface
  15. {
  16. /**
  17. * Authorization level of a basic admin session
  18. *
  19. * @see _isAllowed()
  20. */
  21. const ADMIN_RESOURCE = 'Magento_Sales::shipment';
  22. /**
  23. * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
  24. */
  25. protected $shipmentLoader;
  26. /**
  27. * @var \Magento\Shipping\Model\Shipping\LabelGenerator
  28. */
  29. protected $labelGenerator;
  30. /**
  31. * @var \Magento\Sales\Model\Order\Email\Sender\ShipmentSender
  32. */
  33. protected $shipmentSender;
  34. /**
  35. * @var \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface
  36. */
  37. private $shipmentValidator;
  38. /**
  39. * @param \Magento\Backend\App\Action\Context $context
  40. * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
  41. * @param \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator
  42. * @param \Magento\Sales\Model\Order\Email\Sender\ShipmentSender $shipmentSender
  43. * @param \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface|null $shipmentValidator
  44. */
  45. public function __construct(
  46. \Magento\Backend\App\Action\Context $context,
  47. \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader,
  48. \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator,
  49. \Magento\Sales\Model\Order\Email\Sender\ShipmentSender $shipmentSender,
  50. \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface $shipmentValidator = null
  51. ) {
  52. parent::__construct($context);
  53. $this->shipmentLoader = $shipmentLoader;
  54. $this->labelGenerator = $labelGenerator;
  55. $this->shipmentSender = $shipmentSender;
  56. $this->shipmentValidator = $shipmentValidator ?: \Magento\Framework\App\ObjectManager::getInstance()
  57. ->get(\Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface::class);
  58. }
  59. /**
  60. * Save shipment and order in one transaction
  61. *
  62. * @param \Magento\Sales\Model\Order\Shipment $shipment
  63. * @return $this
  64. */
  65. protected function _saveShipment($shipment)
  66. {
  67. $shipment->getOrder()->setIsInProcess(true);
  68. $transaction = $this->_objectManager->create(
  69. \Magento\Framework\DB\Transaction::class
  70. );
  71. $transaction->addObject(
  72. $shipment
  73. )->addObject(
  74. $shipment->getOrder()
  75. )->save();
  76. return $this;
  77. }
  78. /**
  79. * Save shipment
  80. *
  81. * We can save only new shipment. Existing shipments are not editable
  82. *
  83. * @return \Magento\Framework\Controller\ResultInterface
  84. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  85. * @SuppressWarnings(PHPMD.NPathComplexity)
  86. */
  87. public function execute()
  88. {
  89. /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
  90. $resultRedirect = $this->resultRedirectFactory->create();
  91. $formKeyIsValid = $this->_formKeyValidator->validate($this->getRequest());
  92. $isPost = $this->getRequest()->isPost();
  93. if (!$formKeyIsValid || !$isPost) {
  94. $this->messageManager->addErrorMessage(__('We can\'t save the shipment right now.'));
  95. return $resultRedirect->setPath('sales/order/index');
  96. }
  97. $data = $this->getRequest()->getParam('shipment');
  98. if (!empty($data['comment_text'])) {
  99. $this->_objectManager->get(\Magento\Backend\Model\Session::class)->setCommentText($data['comment_text']);
  100. }
  101. $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label'];
  102. $responseAjax = new \Magento\Framework\DataObject();
  103. try {
  104. $this->shipmentLoader->setOrderId($this->getRequest()->getParam('order_id'));
  105. $this->shipmentLoader->setShipmentId($this->getRequest()->getParam('shipment_id'));
  106. $this->shipmentLoader->setShipment($data);
  107. $this->shipmentLoader->setTracking($this->getRequest()->getParam('tracking'));
  108. $shipment = $this->shipmentLoader->load();
  109. if (!$shipment) {
  110. return $this->resultFactory->create(ResultFactory::TYPE_FORWARD)->forward('noroute');
  111. }
  112. if (!empty($data['comment_text'])) {
  113. $shipment->addComment(
  114. $data['comment_text'],
  115. isset($data['comment_customer_notify']),
  116. isset($data['is_visible_on_front'])
  117. );
  118. $shipment->setCustomerNote($data['comment_text']);
  119. $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify']));
  120. }
  121. $validationResult = $this->shipmentValidator->validate($shipment, [QuantityValidator::class]);
  122. if ($validationResult->hasMessages()) {
  123. $this->messageManager->addErrorMessage(
  124. __("Shipment Document Validation Error(s):\n" . implode("\n", $validationResult->getMessages()))
  125. );
  126. return $resultRedirect->setPath('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]);
  127. }
  128. $shipment->register();
  129. $shipment->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
  130. if ($isNeedCreateLabel) {
  131. $this->labelGenerator->create($shipment, $this->_request);
  132. $responseAjax->setOk(true);
  133. }
  134. $this->_saveShipment($shipment);
  135. if (!empty($data['send_email'])) {
  136. $this->shipmentSender->send($shipment);
  137. }
  138. $shipmentCreatedMessage = __('The shipment has been created.');
  139. $labelCreatedMessage = __('You created the shipping label.');
  140. $this->messageManager->addSuccessMessage(
  141. $isNeedCreateLabel ? $shipmentCreatedMessage . ' ' . $labelCreatedMessage : $shipmentCreatedMessage
  142. );
  143. $this->_objectManager->get(\Magento\Backend\Model\Session::class)->getCommentText(true);
  144. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  145. if ($isNeedCreateLabel) {
  146. $responseAjax->setError(true);
  147. $responseAjax->setMessage($e->getMessage());
  148. } else {
  149. $this->messageManager->addErrorMessage($e->getMessage());
  150. return $resultRedirect->setPath('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]);
  151. }
  152. } catch (\Exception $e) {
  153. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  154. if ($isNeedCreateLabel) {
  155. $responseAjax->setError(true);
  156. $responseAjax->setMessage(__('An error occurred while creating shipping label.'));
  157. } else {
  158. $this->messageManager->addErrorMessage(__('Cannot save shipment.'));
  159. return $resultRedirect->setPath('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]);
  160. }
  161. }
  162. if ($isNeedCreateLabel) {
  163. return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setJsonData($responseAjax->toJson());
  164. }
  165. return $resultRedirect->setPath('sales/order/view', ['order_id' => $shipment->getOrderId()]);
  166. }
  167. }