SourceItemsProcessor.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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\InventoryCatalogAdminUi\Observer;
  8. use Magento\Catalog\Api\Data\ProductInterface;
  9. use Magento\Framework\Api\DataObjectHelper;
  10. use Magento\Framework\Api\SearchCriteriaBuilder;
  11. use Magento\Framework\Api\SearchCriteriaBuilderFactory;
  12. use Magento\Framework\Exception\InputException;
  13. use Magento\InventoryApi\Api\Data\SourceItemInterface;
  14. use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory;
  15. use Magento\InventoryApi\Api\SourceItemRepositoryInterface;
  16. use Magento\InventoryApi\Api\SourceItemsDeleteInterface;
  17. use Magento\InventoryApi\Api\SourceItemsSaveInterface;
  18. /**
  19. * At the time of processing Product save form this class used to save source items correctly
  20. * Perform replace strategy of sources for the product
  21. */
  22. class SourceItemsProcessor
  23. {
  24. /**
  25. * @var SearchCriteriaBuilderFactory
  26. */
  27. private $searchCriteriaBuilderFactory;
  28. /**
  29. * @var SourceItemRepositoryInterface
  30. */
  31. private $sourceItemRepository;
  32. /**
  33. * @var SourceItemInterfaceFactory
  34. */
  35. private $sourceItemFactory;
  36. /**
  37. * @var DataObjectHelper
  38. */
  39. private $dataObjectHelper;
  40. /**
  41. * @var SourceItemsSaveInterface
  42. */
  43. private $sourceItemsSave;
  44. /**
  45. * @var SourceItemsDeleteInterface
  46. */
  47. private $sourceItemsDelete;
  48. /**
  49. * @param SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory
  50. * @param SourceItemRepositoryInterface $sourceItemRepository
  51. * @param SourceItemInterfaceFactory $sourceItemFactory
  52. * @param DataObjectHelper $dataObjectHelper
  53. * @param SourceItemsSaveInterface $sourceItemsSave
  54. * @param SourceItemsDeleteInterface $sourceItemsDelete
  55. */
  56. public function __construct(
  57. SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory,
  58. SourceItemRepositoryInterface $sourceItemRepository,
  59. SourceItemInterfaceFactory $sourceItemFactory,
  60. DataObjectHelper $dataObjectHelper,
  61. SourceItemsSaveInterface $sourceItemsSave,
  62. SourceItemsDeleteInterface $sourceItemsDelete
  63. ) {
  64. $this->searchCriteriaBuilderFactory = $searchCriteriaBuilderFactory;
  65. $this->sourceItemRepository = $sourceItemRepository;
  66. $this->sourceItemFactory = $sourceItemFactory;
  67. $this->dataObjectHelper = $dataObjectHelper;
  68. $this->sourceItemsSave = $sourceItemsSave;
  69. $this->sourceItemsDelete = $sourceItemsDelete;
  70. }
  71. /**
  72. * @param string $sku
  73. * @param array $sourceItemsData
  74. * @return void
  75. * @throws InputException
  76. */
  77. public function process($sku, array $sourceItemsData)
  78. {
  79. $sourceItemsForDelete = $this->getCurrentSourceItemsMap($sku);
  80. $sourceItemsForSave = [];
  81. foreach ($sourceItemsData as $sourceItemData) {
  82. $this->validateSourceItemData($sourceItemData);
  83. $sourceCode = $sourceItemData[SourceItemInterface::SOURCE_CODE];
  84. if (isset($sourceItemsForDelete[$sourceCode])) {
  85. $sourceItem = $sourceItemsForDelete[$sourceCode];
  86. } else {
  87. /** @var SourceItemInterface $sourceItem */
  88. $sourceItem = $this->sourceItemFactory->create();
  89. }
  90. $sourceItemData[SourceItemInterface::SKU] = $sku;
  91. $this->dataObjectHelper->populateWithArray($sourceItem, $sourceItemData, SourceItemInterface::class);
  92. $sourceItemsForSave[] = $sourceItem;
  93. unset($sourceItemsForDelete[$sourceCode]);
  94. }
  95. if ($sourceItemsForSave) {
  96. $this->sourceItemsSave->execute($sourceItemsForSave);
  97. }
  98. if ($sourceItemsForDelete) {
  99. $this->sourceItemsDelete->execute($sourceItemsForDelete);
  100. }
  101. }
  102. /**
  103. * Get Source Items Hash Table by SKU
  104. *
  105. * @param string $sku
  106. * @return SourceItemInterface[]
  107. */
  108. private function getCurrentSourceItemsMap(string $sku): array
  109. {
  110. /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
  111. $searchCriteriaBuilder = $this->searchCriteriaBuilderFactory->create();
  112. $searchCriteria = $searchCriteriaBuilder->addFilter(ProductInterface::SKU, $sku)->create();
  113. $sourceItems = $this->sourceItemRepository->getList($searchCriteria)->getItems();
  114. $sourceItemMap = [];
  115. if ($sourceItems) {
  116. foreach ($sourceItems as $sourceItem) {
  117. $sourceItemMap[$sourceItem->getSourceCode()] = $sourceItem;
  118. }
  119. }
  120. return $sourceItemMap;
  121. }
  122. /**
  123. * @param array $sourceItemData
  124. * @return void
  125. * @throws InputException
  126. */
  127. private function validateSourceItemData(array $sourceItemData)
  128. {
  129. if (!isset($sourceItemData[SourceItemInterface::SOURCE_CODE])) {
  130. throw new InputException(__('Wrong Product to Source relation parameters given.'));
  131. }
  132. }
  133. }