SourceDeductionProcessor.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\InventoryShipping\Observer;
  8. use Magento\Framework\Event\ObserverInterface;
  9. use Magento\Framework\Event\Observer as EventObserver;
  10. use Magento\InventorySourceDeductionApi\Model\SourceDeductionServiceInterface;
  11. use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface;
  12. use Magento\InventoryCatalogApi\Model\IsSingleSourceModeInterface;
  13. use Magento\InventoryShipping\Model\GetItemsToDeductFromShipment;
  14. use Magento\InventorySalesApi\Api\PlaceReservationsForSalesEventInterface;
  15. use Magento\InventoryShipping\Model\SourceDeductionRequestFromShipmentFactory;
  16. use Magento\InventorySourceDeductionApi\Model\SourceDeductionRequestInterface;
  17. use Magento\InventorySalesApi\Api\Data\ItemToSellInterfaceFactory;
  18. /**
  19. * Class SourceDeductionProcessor
  20. */
  21. class SourceDeductionProcessor implements ObserverInterface
  22. {
  23. /**
  24. * @var IsSingleSourceModeInterface
  25. */
  26. private $isSingleSourceMode;
  27. /**
  28. * @var DefaultSourceProviderInterface
  29. */
  30. private $defaultSourceProvider;
  31. /**
  32. * @var GetItemsToDeductFromShipment
  33. */
  34. private $getItemsToDeductFromShipment;
  35. /**
  36. * @var SourceDeductionRequestFromShipmentFactory
  37. */
  38. private $sourceDeductionRequestFromShipmentFactory;
  39. /**
  40. * @var SourceDeductionServiceInterface
  41. */
  42. private $sourceDeductionService;
  43. /**
  44. * @var ItemToSellInterfaceFactory
  45. */
  46. private $itemsToSellFactory;
  47. /**
  48. * @var PlaceReservationsForSalesEventInterface
  49. */
  50. private $placeReservationsForSalesEvent;
  51. /**
  52. * @param IsSingleSourceModeInterface $isSingleSourceMode
  53. * @param DefaultSourceProviderInterface $defaultSourceProvider
  54. * @param GetItemsToDeductFromShipment $getItemsToDeductFromShipment
  55. * @param SourceDeductionRequestFromShipmentFactory $sourceDeductionRequestFromShipmentFactory
  56. * @param SourceDeductionServiceInterface $sourceDeductionService
  57. * @param ItemToSellInterfaceFactory $itemsToSellFactory
  58. * @param PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent
  59. */
  60. public function __construct(
  61. IsSingleSourceModeInterface $isSingleSourceMode,
  62. DefaultSourceProviderInterface $defaultSourceProvider,
  63. GetItemsToDeductFromShipment $getItemsToDeductFromShipment,
  64. SourceDeductionRequestFromShipmentFactory $sourceDeductionRequestFromShipmentFactory,
  65. SourceDeductionServiceInterface $sourceDeductionService,
  66. ItemToSellInterfaceFactory $itemsToSellFactory,
  67. PlaceReservationsForSalesEventInterface $placeReservationsForSalesEvent
  68. ) {
  69. $this->isSingleSourceMode = $isSingleSourceMode;
  70. $this->defaultSourceProvider = $defaultSourceProvider;
  71. $this->getItemsToDeductFromShipment = $getItemsToDeductFromShipment;
  72. $this->sourceDeductionRequestFromShipmentFactory = $sourceDeductionRequestFromShipmentFactory;
  73. $this->sourceDeductionService = $sourceDeductionService;
  74. $this->itemsToSellFactory = $itemsToSellFactory;
  75. $this->placeReservationsForSalesEvent = $placeReservationsForSalesEvent;
  76. }
  77. /**
  78. * @param EventObserver $observer
  79. * @return void
  80. */
  81. public function execute(EventObserver $observer)
  82. {
  83. /** @var \Magento\Sales\Model\Order\Shipment $shipment */
  84. $shipment = $observer->getEvent()->getShipment();
  85. if ($shipment->getOrigData('entity_id')) {
  86. return;
  87. }
  88. if (!empty($shipment->getExtensionAttributes())
  89. && !empty($shipment->getExtensionAttributes()->getSourceCode())) {
  90. $sourceCode = $shipment->getExtensionAttributes()->getSourceCode();
  91. } elseif ($this->isSingleSourceMode->execute()) {
  92. $sourceCode = $this->defaultSourceProvider->getCode();
  93. }
  94. $shipmentItems = $this->getItemsToDeductFromShipment->execute($shipment);
  95. if (!empty($shipmentItems)) {
  96. $sourceDeductionRequest = $this->sourceDeductionRequestFromShipmentFactory->execute(
  97. $shipment,
  98. $sourceCode,
  99. $shipmentItems
  100. );
  101. $this->sourceDeductionService->execute($sourceDeductionRequest);
  102. $this->placeCompensatingReservation($sourceDeductionRequest);
  103. }
  104. }
  105. /**
  106. * Place compensating reservation after source deduction
  107. *
  108. * @param SourceDeductionRequestInterface $sourceDeductionRequest
  109. */
  110. private function placeCompensatingReservation(SourceDeductionRequestInterface $sourceDeductionRequest): void
  111. {
  112. $items = [];
  113. foreach ($sourceDeductionRequest->getItems() as $item) {
  114. $items[] = $this->itemsToSellFactory->create([
  115. 'sku' => $item->getSku(),
  116. 'qty' => $item->getQty()
  117. ]);
  118. }
  119. $this->placeReservationsForSalesEvent->execute(
  120. $items,
  121. $sourceDeductionRequest->getSalesChannel(),
  122. $sourceDeductionRequest->getSalesEvent()
  123. );
  124. }
  125. }