CancelOrder.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. /**
  3. * This file is part of the Klarna Order Management module
  4. *
  5. * (c) Klarna Bank AB (publ)
  6. *
  7. * For the full copyright and license information, please view the NOTICE
  8. * and LICENSE files that were distributed with this source code.
  9. */
  10. namespace Klarna\Ordermanagement\Observer;
  11. use Klarna\Core\Api\OrderRepositoryInterface;
  12. use Klarna\Core\Helper\KlarnaConfig;
  13. use Klarna\Ordermanagement\Api\ApiInterface;
  14. use Klarna\Ordermanagement\Model\Api\Factory;
  15. use Klarna\Ordermanagement\Model\Api\Ordermanagement;
  16. use Magento\Framework\Event\Observer;
  17. use Magento\Framework\Event\ObserverInterface;
  18. use Magento\Quote\Model\Quote;
  19. use Magento\Sales\Api\Data\OrderInterface;
  20. use Magento\Store\Api\Data\StoreInterface;
  21. use Psr\Log\LoggerInterface;
  22. use Magento\Store\Model\StoreManagerInterface;
  23. /**
  24. * Class CancelOrder
  25. *
  26. * @package Klarna\Ordermanagement\Observer
  27. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  28. */
  29. class CancelOrder implements ObserverInterface
  30. {
  31. /**
  32. * @var LoggerInterface
  33. */
  34. private $log;
  35. /**
  36. * @var Ordermanagement
  37. */
  38. private $orderManagement;
  39. /**
  40. * @var KlarnaConfig
  41. */
  42. private $helper;
  43. /**
  44. * @var Factory
  45. */
  46. private $omFactory;
  47. /**
  48. * @var OrderRepositoryInterface
  49. */
  50. private $orderRepository;
  51. /**
  52. * @var \Magento\Quote\Model\ResourceModel\Quote
  53. */
  54. private $quoteResourceModel;
  55. /**
  56. * @var \Magento\Sales\Api\OrderRepositoryInterface
  57. */
  58. private $mageOrderRepository;
  59. /**
  60. * @var \Magento\Store\Model\StoreManagerInterface
  61. */
  62. private $storeManager;
  63. /**
  64. * CancelOrder constructor.
  65. *
  66. * @param LoggerInterface $log
  67. * @param Ordermanagement $om
  68. * @param KlarnaConfig $helper
  69. * @param Factory $omFactory
  70. * @param OrderRepositoryInterface $orderRepository
  71. */
  72. public function __construct(
  73. LoggerInterface $log,
  74. Ordermanagement $orderManagement,
  75. KlarnaConfig $helper,
  76. Factory $omFactory,
  77. OrderRepositoryInterface $orderRepository,
  78. \Magento\Quote\Model\ResourceModel\Quote $quoteResourceModel,
  79. \Magento\Sales\Api\OrderRepositoryInterface $mageOrderRepository,
  80. StoreManagerInterface $storeManager
  81. ) {
  82. $this->log = $log;
  83. $this->orderManagement = $orderManagement;
  84. $this->helper = $helper;
  85. $this->omFactory = $omFactory;
  86. $this->orderRepository = $orderRepository;
  87. $this->quoteResourceModel = $quoteResourceModel;
  88. $this->mageOrderRepository = $mageOrderRepository;
  89. $this->storeManager = $storeManager;
  90. }
  91. /**
  92. * @param Observer $observer
  93. * @return void
  94. * @throws \Magento\Framework\Exception\NoSuchEntityException
  95. */
  96. public function execute(Observer $observer)
  97. {
  98. $checkout_id = $observer->getKlarnaOrderId();
  99. $store = $this->getStore($observer);
  100. if ($checkout_id === null) {
  101. return;
  102. }
  103. $korder = $this->orderRepository->getByKlarnaOrderId($checkout_id);
  104. if (!$korder->getId() && !$this->helper->isDelayedPushNotification($store)) {
  105. // If no order exists and API does not have a delay before the push notices,
  106. // don't cancel. It's likely the push happened too quickly. See
  107. // LogOrderPushNotification observer
  108. $this->log->debug('Delaying canceling order as delayed push is enabled');
  109. return;
  110. }
  111. $this->cancelOrderWithKlarna($observer->getMethodCode(), $observer->getReason(), $checkout_id, $store);
  112. $this->cancelOrderWithMagento($observer->getOrder(), $observer->getQuote());
  113. }
  114. /**
  115. * @param Observer $observer
  116. * @return StoreInterface
  117. */
  118. private function getStore(Observer $observer)
  119. {
  120. $order = $observer->getOrder();
  121. if ($order) {
  122. return $order->getStore();
  123. }
  124. $quote = $observer->getQuote();
  125. if ($quote) {
  126. return $quote->getStore();
  127. }
  128. return $this->storeManager->getStore();
  129. }
  130. /**
  131. * @param string $methodCode
  132. * @param string $reason
  133. * @param string $checkoutId
  134. * @param StoreInterface $store
  135. * @return void
  136. */
  137. private function cancelOrderWithKlarna($methodCode, $reason, $checkoutId, StoreInterface $store = null)
  138. {
  139. try {
  140. $this->getOmApi($methodCode, $store);
  141. $order = $this->orderManagement->getPlacedKlarnaOrder($checkoutId);
  142. $klarnaId = $order->getReservation();
  143. if (!$klarnaId) {
  144. $klarnaId = $checkoutId;
  145. }
  146. if ($order->getStatus() !== 'CANCELED') {
  147. $this->orderManagement->cancel($klarnaId);
  148. $this->log->debug('Canceled order with Klarna - ' . $reason);
  149. }
  150. } catch (\Exception $e) {
  151. $this->log->error($e);
  152. }
  153. }
  154. /**
  155. * Get api class
  156. *
  157. * @param string $methodCode
  158. * @param StoreInterface $store
  159. * @return ApiInterface
  160. * @throws \Magento\Framework\Exception\LocalizedException
  161. */
  162. private function getOmApi($methodCode, StoreInterface $store = null)
  163. {
  164. $om_class = $this->helper->getOrderMangagementClass($store);
  165. /** @var ApiInterface $om */
  166. $this->orderManagement = $this->omFactory->create($om_class);
  167. $this->orderManagement->resetForStore($store, $methodCode);
  168. return $this->orderManagement;
  169. }
  170. /**
  171. * @param OrderInterface $mageOrder
  172. * @param Quote $quote
  173. */
  174. private function cancelOrderWithMagento(OrderInterface $mageOrder = null, Quote $quote = null)
  175. {
  176. try {
  177. $debug_message = 'Magento order object not available to cancel';
  178. if ($mageOrder) {
  179. $mageOrder->cancel();
  180. $debug_message = 'Canceled order in Magento';
  181. }
  182. $this->log->debug($debug_message);
  183. if ($quote) {
  184. $quote->setReservedOrderId(null);
  185. $quote->setIsActive(1);
  186. // STFU and just save the quote
  187. $this->quoteResourceModel->save($quote->collectTotals());
  188. }
  189. } catch (\Exception $e) {
  190. $this->log->error($e);
  191. }
  192. }
  193. }