OrderRepositoryPlugin.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Plugin\Sales;
  6. use Magento\Framework\Exception\LocalizedException;
  7. use Magento\Framework\Exception\NoSuchEntityException;
  8. use Magento\Sales\Api\Data\OrderInterface;
  9. use Magento\Sales\Api\OrderRepositoryInterface as SalesOrderRepositoryInterface;
  10. use Psr\Log\LoggerInterface;
  11. use Temando\Shipping\Api\Data\Order\OrderReferenceInterface;
  12. use Temando\Shipping\Api\Data\Order\OrderReferenceInterfaceFactory;
  13. use Temando\Shipping\Model\Checkout\Submit\OrderDataInitializer;
  14. use Temando\Shipping\Model\ResourceModel\Repository\OrderRepositoryInterface;
  15. use Temando\Shipping\Model\Shipping\Carrier;
  16. use Temando\Shipping\Webservice\Processor\OrderOperationProcessorPool;
  17. /**
  18. * OrderRepositoryPlugin
  19. *
  20. * @package Temando\Shipping\Plugin
  21. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  22. * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  23. * @link https://www.temando.com/
  24. */
  25. class OrderRepositoryPlugin
  26. {
  27. /**
  28. * @var OrderReferenceInterfaceFactory
  29. */
  30. private $orderReferenceFactory;
  31. /**
  32. * @var OrderDataInitializer
  33. */
  34. private $orderDataInitializer;
  35. /**
  36. * @var OrderRepositoryInterface
  37. */
  38. private $orderRepository;
  39. /**
  40. * @var OrderOperationProcessorPool
  41. */
  42. private $processorPool;
  43. /**
  44. * @var LoggerInterface
  45. */
  46. private $logger;
  47. /**
  48. * OrderRepositoryPlugin constructor.
  49. * @param OrderReferenceInterfaceFactory $orderReferenceFactory
  50. * @param OrderDataInitializer $orderDataInitializer
  51. * @param OrderRepositoryInterface $orderRepository
  52. * @param OrderOperationProcessorPool $processorPool
  53. * @param LoggerInterface $logger
  54. */
  55. public function __construct(
  56. OrderReferenceInterfaceFactory $orderReferenceFactory,
  57. OrderDataInitializer $orderDataInitializer,
  58. OrderRepositoryInterface $orderRepository,
  59. OrderOperationProcessorPool $processorPool,
  60. LoggerInterface $logger
  61. ) {
  62. $this->orderReferenceFactory = $orderReferenceFactory;
  63. $this->orderDataInitializer = $orderDataInitializer;
  64. $this->orderRepository = $orderRepository;
  65. $this->processorPool = $processorPool;
  66. $this->logger = $logger;
  67. }
  68. /**
  69. * Manifest order at Temando platform.
  70. *
  71. * Observers don't work:
  72. * - `sales_order_save_commit_after` is no longer triggered in guest checkout
  73. * - `sales_order_save_after` does not have related entities (addresses) persisted yet
  74. *
  75. * Other promising events like `sales_order_place_after`, `checkout_submit_all_after`,
  76. * `sales_model_service_quote_submit_success` are
  77. * - triggered before the order was saved or
  78. * - not triggered at all in multi address checkout or some payment providers'
  79. * custom checkout implementations (paypal express, sagepay, …).
  80. *
  81. * @param SalesOrderRepositoryInterface $subject
  82. * @param OrderInterface|\Magento\Sales\Model\Order $salesOrder
  83. * @return OrderInterface
  84. */
  85. public function afterSave(SalesOrderRepositoryInterface $subject, OrderInterface $salesOrder)
  86. {
  87. if (!$salesOrder->getData('shipping_method')) {
  88. // virtual or corrupt order
  89. return $salesOrder;
  90. }
  91. $shippingMethod = $salesOrder->getShippingMethod(true);
  92. $carrierCode = $shippingMethod->getData('carrier_code');
  93. if ($carrierCode !== Carrier::CODE) {
  94. // not interested in other carriers
  95. return $salesOrder;
  96. }
  97. try {
  98. $orderReference = $this->orderRepository->getReferenceByOrderId($salesOrder->getId());
  99. } catch (NoSuchEntityException $exception) {
  100. $orderReference = $this->orderReferenceFactory->create(['data' => [
  101. OrderReferenceInterface::ORDER_ID => $salesOrder->getId(),
  102. ]]);
  103. }
  104. if ($orderReference->getExtOrderId()) {
  105. // Do not send orders to Temando platform that were saved already.
  106. return $salesOrder;
  107. }
  108. try {
  109. // create request data from local (sales) order entity
  110. $order = $this->orderDataInitializer->getOrder($salesOrder);
  111. // save order at Temando platform as well as local reference to it.
  112. $saveResult = $this->orderRepository->save($order);
  113. $this->processorPool->processSaveResponse($salesOrder, $order, $saveResult);
  114. } catch (LocalizedException $exception) {
  115. // nothing we can do here, just don't interrupt order process
  116. $this->logger->critical($exception->getLogMessage(), ['exception' => $exception]);
  117. }
  118. return $salesOrder;
  119. }
  120. }