RefundInvoice.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Model;
  7. use Magento\Framework\App\ResourceConnection;
  8. use Magento\Sales\Api\CreditmemoRepositoryInterface;
  9. use Magento\Sales\Api\InvoiceRepositoryInterface;
  10. use Magento\Sales\Api\OrderRepositoryInterface;
  11. use Magento\Sales\Api\RefundInvoiceInterface;
  12. use Magento\Sales\Model\Order\Config as OrderConfig;
  13. use Magento\Sales\Model\Order\Creditmemo\NotifierInterface;
  14. use Magento\Sales\Model\Order\CreditmemoDocumentFactory;
  15. use Magento\Sales\Model\Order\OrderStateResolverInterface;
  16. use Magento\Sales\Model\Order\RefundAdapterInterface;
  17. use Magento\Sales\Model\Order\Validation\RefundInvoiceInterface as RefundInvoiceValidator;
  18. use Psr\Log\LoggerInterface;
  19. /**
  20. * Class RefundInvoice
  21. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  22. */
  23. class RefundInvoice implements RefundInvoiceInterface
  24. {
  25. /**
  26. * @var ResourceConnection
  27. */
  28. private $resourceConnection;
  29. /**
  30. * @var OrderStateResolverInterface
  31. */
  32. private $orderStateResolver;
  33. /**
  34. * @var OrderRepositoryInterface
  35. */
  36. private $orderRepository;
  37. /**
  38. * @var InvoiceRepositoryInterface
  39. */
  40. private $invoiceRepository;
  41. /**
  42. * @var CreditmemoRepositoryInterface
  43. */
  44. private $creditmemoRepository;
  45. /**
  46. * @var RefundAdapterInterface
  47. */
  48. private $refundAdapter;
  49. /**
  50. * @var CreditmemoDocumentFactory
  51. */
  52. private $creditmemoDocumentFactory;
  53. /**
  54. * @var NotifierInterface
  55. */
  56. private $notifier;
  57. /**
  58. * @var OrderConfig
  59. */
  60. private $config;
  61. /**
  62. * @var LoggerInterface
  63. */
  64. private $logger;
  65. /**
  66. * @var RefundInvoiceValidator
  67. */
  68. private $validator;
  69. /**
  70. * RefundInvoice constructor.
  71. *
  72. * @param ResourceConnection $resourceConnection
  73. * @param OrderStateResolverInterface $orderStateResolver
  74. * @param OrderRepositoryInterface $orderRepository
  75. * @param InvoiceRepositoryInterface $invoiceRepository
  76. * @param RefundInvoiceValidator $validator
  77. * @param CreditmemoRepositoryInterface $creditmemoRepository
  78. * @param RefundAdapterInterface $refundAdapter
  79. * @param CreditmemoDocumentFactory $creditmemoDocumentFactory
  80. * @param NotifierInterface $notifier
  81. * @param OrderConfig $config
  82. * @param LoggerInterface $logger
  83. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  84. */
  85. public function __construct(
  86. ResourceConnection $resourceConnection,
  87. OrderStateResolverInterface $orderStateResolver,
  88. OrderRepositoryInterface $orderRepository,
  89. InvoiceRepositoryInterface $invoiceRepository,
  90. RefundInvoiceValidator $validator,
  91. CreditmemoRepositoryInterface $creditmemoRepository,
  92. RefundAdapterInterface $refundAdapter,
  93. CreditmemoDocumentFactory $creditmemoDocumentFactory,
  94. NotifierInterface $notifier,
  95. OrderConfig $config,
  96. LoggerInterface $logger
  97. ) {
  98. $this->resourceConnection = $resourceConnection;
  99. $this->orderStateResolver = $orderStateResolver;
  100. $this->orderRepository = $orderRepository;
  101. $this->invoiceRepository = $invoiceRepository;
  102. $this->validator = $validator;
  103. $this->creditmemoRepository = $creditmemoRepository;
  104. $this->refundAdapter = $refundAdapter;
  105. $this->creditmemoDocumentFactory = $creditmemoDocumentFactory;
  106. $this->notifier = $notifier;
  107. $this->config = $config;
  108. $this->logger = $logger;
  109. }
  110. /**
  111. * @inheritdoc
  112. */
  113. public function execute(
  114. $invoiceId,
  115. array $items = [],
  116. $isOnline = false,
  117. $notify = false,
  118. $appendComment = false,
  119. \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
  120. \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
  121. ) {
  122. $connection = $this->resourceConnection->getConnection('sales');
  123. $invoice = $this->invoiceRepository->get($invoiceId);
  124. $order = $this->orderRepository->get($invoice->getOrderId());
  125. $creditmemo = $this->creditmemoDocumentFactory->createFromInvoice(
  126. $invoice,
  127. $items,
  128. $comment,
  129. ($appendComment && $notify),
  130. $arguments
  131. );
  132. $validationMessages = $this->validator->validate(
  133. $invoice,
  134. $order,
  135. $creditmemo,
  136. $items,
  137. $isOnline,
  138. $notify,
  139. $appendComment,
  140. $comment,
  141. $arguments
  142. );
  143. if ($validationMessages->hasMessages()) {
  144. throw new \Magento\Sales\Exception\DocumentValidationException(
  145. __("Creditmemo Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages()))
  146. );
  147. }
  148. $connection->beginTransaction();
  149. try {
  150. $creditmemo->setState(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED);
  151. $order->setCustomerNoteNotify($notify);
  152. $order = $this->refundAdapter->refund($creditmemo, $order, $isOnline);
  153. $order->setState(
  154. $this->orderStateResolver->getStateForOrder($order, [])
  155. );
  156. $order->setStatus($this->config->getStateDefaultStatus($order->getState()));
  157. if (!$isOnline) {
  158. $invoice->setIsUsedForRefund(true);
  159. $invoice->setBaseTotalRefunded(
  160. $invoice->getBaseTotalRefunded() + $creditmemo->getBaseGrandTotal()
  161. );
  162. }
  163. $this->invoiceRepository->save($invoice);
  164. $order = $this->orderRepository->save($order);
  165. $creditmemo = $this->creditmemoRepository->save($creditmemo);
  166. $connection->commit();
  167. } catch (\Exception $e) {
  168. $this->logger->critical($e);
  169. $connection->rollBack();
  170. throw new \Magento\Sales\Exception\CouldNotRefundException(
  171. __('Could not save a Creditmemo, see error log for details')
  172. );
  173. }
  174. if ($notify) {
  175. if (!$appendComment) {
  176. $comment = null;
  177. }
  178. $this->notifier->notify($order, $creditmemo, $comment);
  179. }
  180. return $creditmemo->getEntityId();
  181. }
  182. }