Save.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /**
  3. *
  4. * Copyright © Magento, Inc. All rights reserved.
  5. * See COPYING.txt for license details.
  6. */
  7. namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
  8. use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
  9. use Magento\Backend\App\Action;
  10. use Magento\Framework\Exception\LocalizedException;
  11. use Magento\Framework\Registry;
  12. use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
  13. use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
  14. use Magento\Sales\Model\Order\ShipmentFactory;
  15. use Magento\Sales\Model\Order\Invoice;
  16. use Magento\Sales\Model\Service\InvoiceService;
  17. /**
  18. * Save invoice controller.
  19. *
  20. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  21. */
  22. class Save extends \Magento\Backend\App\Action implements HttpPostActionInterface
  23. {
  24. /**
  25. * Authorization level of a basic admin session
  26. *
  27. * @see _isAllowed()
  28. */
  29. const ADMIN_RESOURCE = 'Magento_Sales::sales_invoice';
  30. /**
  31. * @var InvoiceSender
  32. */
  33. protected $invoiceSender;
  34. /**
  35. * @var ShipmentSender
  36. */
  37. protected $shipmentSender;
  38. /**
  39. * @var ShipmentFactory
  40. */
  41. protected $shipmentFactory;
  42. /**
  43. * @var Registry
  44. */
  45. protected $registry;
  46. /**
  47. * @var InvoiceService
  48. */
  49. private $invoiceService;
  50. /**
  51. * @param Action\Context $context
  52. * @param Registry $registry
  53. * @param InvoiceSender $invoiceSender
  54. * @param ShipmentSender $shipmentSender
  55. * @param ShipmentFactory $shipmentFactory
  56. * @param InvoiceService $invoiceService
  57. */
  58. public function __construct(
  59. Action\Context $context,
  60. Registry $registry,
  61. InvoiceSender $invoiceSender,
  62. ShipmentSender $shipmentSender,
  63. ShipmentFactory $shipmentFactory,
  64. InvoiceService $invoiceService
  65. ) {
  66. $this->registry = $registry;
  67. $this->invoiceSender = $invoiceSender;
  68. $this->shipmentSender = $shipmentSender;
  69. $this->shipmentFactory = $shipmentFactory;
  70. $this->invoiceService = $invoiceService;
  71. parent::__construct($context);
  72. }
  73. /**
  74. * Prepare shipment
  75. *
  76. * @param \Magento\Sales\Model\Order\Invoice $invoice
  77. * @return \Magento\Sales\Model\Order\Shipment|false
  78. */
  79. protected function _prepareShipment($invoice)
  80. {
  81. $invoiceData = $this->getRequest()->getParam('invoice');
  82. $shipment = $this->shipmentFactory->create(
  83. $invoice->getOrder(),
  84. isset($invoiceData['items']) ? $invoiceData['items'] : [],
  85. $this->getRequest()->getPost('tracking')
  86. );
  87. if (!$shipment->getTotalQty()) {
  88. return false;
  89. }
  90. return $shipment->register();
  91. }
  92. /**
  93. * Save invoice
  94. *
  95. * We can save only new invoice. Existing invoices are not editable
  96. *
  97. * @return \Magento\Framework\Controller\ResultInterface
  98. *
  99. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  100. * @SuppressWarnings(PHPMD.NPathComplexity)
  101. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  102. */
  103. public function execute()
  104. {
  105. /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
  106. $resultRedirect = $this->resultRedirectFactory->create();
  107. $formKeyIsValid = $this->_formKeyValidator->validate($this->getRequest());
  108. $isPost = $this->getRequest()->isPost();
  109. if (!$formKeyIsValid || !$isPost) {
  110. $this->messageManager
  111. ->addErrorMessage(__("The invoice can't be saved at this time. Please try again later."));
  112. return $resultRedirect->setPath('sales/order/index');
  113. }
  114. $data = $this->getRequest()->getPost('invoice');
  115. $orderId = $this->getRequest()->getParam('order_id');
  116. if (!empty($data['comment_text'])) {
  117. $this->_objectManager->get(\Magento\Backend\Model\Session::class)->setCommentText($data['comment_text']);
  118. }
  119. try {
  120. $invoiceData = $this->getRequest()->getParam('invoice', []);
  121. $invoiceItems = isset($invoiceData['items']) ? $invoiceData['items'] : [];
  122. /** @var \Magento\Sales\Model\Order $order */
  123. $order = $this->_objectManager->create(\Magento\Sales\Model\Order::class)->load($orderId);
  124. if (!$order->getId()) {
  125. throw new \Magento\Framework\Exception\LocalizedException(__('The order no longer exists.'));
  126. }
  127. if (!$order->canInvoice()) {
  128. throw new \Magento\Framework\Exception\LocalizedException(
  129. __('The order does not allow an invoice to be created.')
  130. );
  131. }
  132. $invoice = $this->invoiceService->prepareInvoice($order, $invoiceItems);
  133. if (!$invoice) {
  134. throw new LocalizedException(__("The invoice can't be saved at this time. Please try again later."));
  135. }
  136. if (!$invoice->getTotalQty()) {
  137. throw new \Magento\Framework\Exception\LocalizedException(
  138. __("The invoice can't be created without products. Add products and try again.")
  139. );
  140. }
  141. $this->registry->register('current_invoice', $invoice);
  142. if (!empty($data['capture_case'])) {
  143. $invoice->setRequestedCaptureCase($data['capture_case']);
  144. }
  145. if (!empty($data['comment_text'])) {
  146. $invoice->addComment(
  147. $data['comment_text'],
  148. isset($data['comment_customer_notify']),
  149. isset($data['is_visible_on_front'])
  150. );
  151. $invoice->setCustomerNote($data['comment_text']);
  152. $invoice->setCustomerNoteNotify(isset($data['comment_customer_notify']));
  153. }
  154. $invoice->register();
  155. $invoice->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
  156. $invoice->getOrder()->setIsInProcess(true);
  157. $transactionSave = $this->_objectManager->create(
  158. \Magento\Framework\DB\Transaction::class
  159. )->addObject(
  160. $invoice
  161. )->addObject(
  162. $invoice->getOrder()
  163. );
  164. $shipment = false;
  165. if (!empty($data['do_shipment']) || (int)$invoice->getOrder()->getForcedShipmentWithInvoice()) {
  166. $shipment = $this->_prepareShipment($invoice);
  167. if ($shipment) {
  168. $transactionSave->addObject($shipment);
  169. }
  170. }
  171. $transactionSave->save();
  172. // send invoice/shipment emails
  173. try {
  174. if (!empty($data['send_email'])) {
  175. $this->invoiceSender->send($invoice);
  176. }
  177. } catch (\Exception $e) {
  178. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  179. $this->messageManager->addErrorMessage(__('We can\'t send the invoice email right now.'));
  180. }
  181. if ($shipment) {
  182. try {
  183. if (!empty($data['send_email'])) {
  184. $this->shipmentSender->send($shipment);
  185. }
  186. } catch (\Exception $e) {
  187. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  188. $this->messageManager->addErrorMessage(__('We can\'t send the shipment right now.'));
  189. }
  190. }
  191. if (!empty($data['do_shipment'])) {
  192. $this->messageManager->addSuccessMessage(__('You created the invoice and shipment.'));
  193. } else {
  194. $this->messageManager->addSuccessMessage(__('The invoice has been created.'));
  195. }
  196. $this->_objectManager->get(\Magento\Backend\Model\Session::class)->getCommentText(true);
  197. return $resultRedirect->setPath('sales/order/view', ['order_id' => $orderId]);
  198. } catch (LocalizedException $e) {
  199. $this->messageManager->addErrorMessage($e->getMessage());
  200. } catch (\Exception $e) {
  201. $this->messageManager->addErrorMessage(
  202. __("The invoice can't be saved at this time. Please try again later.")
  203. );
  204. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  205. }
  206. return $resultRedirect->setPath('sales/*/new', ['order_id' => $orderId]);
  207. }
  208. }