diff --git a/InventoryCatalog/Model/BulkInventoryTransfer.php b/InventoryCatalog/Model/BulkInventoryTransfer.php index 9aebf77319a0..207bbe1749a0 100644 --- a/InventoryCatalog/Model/BulkInventoryTransfer.php +++ b/InventoryCatalog/Model/BulkInventoryTransfer.php @@ -10,6 +10,8 @@ use Magento\CatalogInventory\Model\Indexer\Stock as LegacyIndexer; use Magento\Framework\Validation\ValidationException; use Magento\InventoryCatalog\Model\ResourceModel\BulkInventoryTransfer as BulkInventoryTransferResource; +use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockItem; +use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus; use Magento\InventoryCatalogApi\Api\BulkInventoryTransferInterface; use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface; use Magento\InventoryCatalogApi\Model\BulkInventoryTransferValidatorInterface; @@ -51,6 +53,21 @@ class BulkInventoryTransfer implements BulkInventoryTransferInterface */ private $sourceIndexer; + /** + * @var GetSourceItemsBySkuAndSourceCodes + */ + private $getSourceItemsBySkuAndSourceCodes; + + /** + * @var SetDataToLegacyStockStatus + */ + private $setDataToLegacyStockStatus; + + /** + * @var SetDataToLegacyStockItem + */ + private $setDataToLegacyStockItem; + /** * @param BulkInventoryTransferValidatorInterface $inventoryTransferValidator * @param BulkInventoryTransferResource $bulkInventoryTransfer @@ -58,6 +75,9 @@ class BulkInventoryTransfer implements BulkInventoryTransferInterface * @param DefaultSourceProviderInterface $defaultSourceProvider * @param GetProductIdsBySkusInterface $getProductIdsBySkus * @param LegacyIndexer $legacyIndexer + * @param GetSourceItemsBySkuAndSourceCodes $getSourceItemsBySkuAndSourceCodes + * @param SetDataToLegacyStockStatus $setDataToLegacyStockStatus + * @param SetDataToLegacyStockItem $setDataToLegacyStockItem * @SuppressWarnings(PHPMD.LongVariable) */ public function __construct( @@ -66,7 +86,10 @@ public function __construct( SourceIndexer $sourceIndexer, DefaultSourceProviderInterface $defaultSourceProvider, GetProductIdsBySkusInterface $getProductIdsBySkus, - LegacyIndexer $legacyIndexer + LegacyIndexer $legacyIndexer, + GetSourceItemsBySkuAndSourceCodes $getSourceItemsBySkuAndSourceCodes, + SetDataToLegacyStockStatus $setDataToLegacyStockStatus, + SetDataToLegacyStockItem $setDataToLegacyStockItem ) { $this->bulkInventoryTransferValidator = $inventoryTransferValidator; $this->bulkInventoryTransfer = $bulkInventoryTransfer; @@ -74,6 +97,9 @@ public function __construct( $this->legacyIndexer = $legacyIndexer; $this->defaultSourceProvider = $defaultSourceProvider; $this->sourceIndexer = $sourceIndexer; + $this->getSourceItemsBySkuAndSourceCodes = $getSourceItemsBySkuAndSourceCodes; + $this->setDataToLegacyStockStatus = $setDataToLegacyStockStatus; + $this->setDataToLegacyStockItem = $setDataToLegacyStockItem; } /** @@ -111,6 +137,7 @@ public function execute( if (($this->defaultSourceProvider->getCode() === $originSource) || ($this->defaultSourceProvider->getCode() === $destinationSource)) { + $this->updateStockStatusForLegacyStock($skus); $productIds = array_values($this->getProductIdsBySkus->execute($skus)); $this->reindexLegacy($productIds); } @@ -118,6 +145,32 @@ public function execute( return true; } + /** + * @param array $skus + * @return void + */ + private function updateStockStatusForLegacyStock(array $skus): void + { + foreach ($skus as $sku) { + $sourceItems = $this->getSourceItemsBySkuAndSourceCodes->execute( + $sku, + [$this->defaultSourceProvider->getCode()] + ); + foreach ($sourceItems as $sourceItem) { + $this->setDataToLegacyStockItem->execute( + (string)$sourceItem->getSku(), + (float)$sourceItem->getQuantity(), + (int)$sourceItem->getStatus() + ); + $this->setDataToLegacyStockStatus->execute( + (string)$sourceItem->getSku(), + (float)$sourceItem->getQuantity(), + (int)$sourceItem->getStatus() + ); + } + } + } + /** * Reindex legacy stock (for default source). * diff --git a/InventoryCatalog/Model/SourceItemsSaveSynchronization/SetDataToLegacyCatalogInventory.php b/InventoryCatalog/Model/SourceItemsSaveSynchronization/SetDataToLegacyCatalogInventory.php index a2d267bc0be0..0b6e7d78c9a7 100644 --- a/InventoryCatalog/Model/SourceItemsSaveSynchronization/SetDataToLegacyCatalogInventory.php +++ b/InventoryCatalog/Model/SourceItemsSaveSynchronization/SetDataToLegacyCatalogInventory.php @@ -18,6 +18,7 @@ use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockItem; use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus; use Magento\InventoryCatalogApi\Model\SourceItemsSaveSynchronizationInterface; +use Magento\InventorySalesApi\Api\AreProductsSalableInterface; /** * Set Qty and status for legacy CatalogInventory Stock Information tables. @@ -59,6 +60,11 @@ class SetDataToLegacyCatalogInventory */ private $indexerProcessor; + /** + * @var AreProductsSalableInterface + */ + private $areProductsSalable; + /** * @param SetDataToLegacyStockItem $setDataToLegacyStockItem * @param StockItemCriteriaInterfaceFactory $legacyStockItemCriteriaFactory @@ -67,6 +73,7 @@ class SetDataToLegacyCatalogInventory * @param StockStateProviderInterface $stockStateProvider * @param Processor $indexerProcessor * @param SetDataToLegacyStockStatus $setDataToLegacyStockStatus + * @param AreProductsSalableInterface $areProductsSalable */ public function __construct( SetDataToLegacyStockItem $setDataToLegacyStockItem, @@ -75,7 +82,8 @@ public function __construct( GetProductIdsBySkusInterface $getProductIdsBySkus, StockStateProviderInterface $stockStateProvider, Processor $indexerProcessor, - SetDataToLegacyStockStatus $setDataToLegacyStockStatus + SetDataToLegacyStockStatus $setDataToLegacyStockStatus, + AreProductsSalableInterface $areProductsSalable ) { $this->setDataToLegacyStockItem = $setDataToLegacyStockItem; $this->setDataToLegacyStockStatus = $setDataToLegacyStockStatus; @@ -84,6 +92,7 @@ public function __construct( $this->getProductIdsBySkus = $getProductIdsBySkus; $this->stockStateProvider = $stockStateProvider; $this->indexerProcessor = $indexerProcessor; + $this->areProductsSalable = $areProductsSalable; } /** @@ -94,6 +103,16 @@ public function __construct( */ public function execute(array $sourceItems): void { + $skus = []; + foreach ($sourceItems as $sourceItem) { + $skus[] = $sourceItem->getSku(); + } + + $stockStatuses = []; + foreach ($this->areProductsSalable->execute($skus, Stock::DEFAULT_STOCK_ID) as $productSalable) { + $stockStatuses[$productSalable->getSku()] = $productSalable->isSalable(); + } + $productIds = []; foreach ($sourceItems as $sourceItem) { $sku = $sourceItem->getSku(); @@ -129,7 +148,7 @@ public function execute(array $sourceItems): void $this->setDataToLegacyStockStatus->execute( (string)$sourceItem->getSku(), (float)$sourceItem->getQuantity(), - $isInStock + $stockStatuses[(string)$sourceItem->getSku()] === true ? 1 : 0 ); $productIds[] = $productId; } diff --git a/InventoryCatalog/Plugin/CatalogInventory/Api/StockRegistry/AdaptUpdateStockStatusBySkuPlugin.php b/InventoryCatalog/Plugin/CatalogInventory/Api/StockRegistry/AdaptUpdateStockStatusBySkuPlugin.php new file mode 100644 index 000000000000..45bb70835af5 --- /dev/null +++ b/InventoryCatalog/Plugin/CatalogInventory/Api/StockRegistry/AdaptUpdateStockStatusBySkuPlugin.php @@ -0,0 +1,49 @@ +setDataToLegacyStockStatus = $setDataToLegacyStockStatus; + } + + /** + * @param StockRegistryInterface $subject + * @param int $itemId + * @param string $productSku + * @param StockItemInterface $stockItem + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterUpdateStockItemBySku( + StockRegistryInterface $subject, + int $itemId, + string $productSku, + StockItemInterface $stockItem + ): void { + $this->setDataToLegacyStockStatus->execute( + $productSku, + (float)$stockItem->getQty(), + $stockItem->getIsInStock() + ); + } +} diff --git a/InventoryCatalog/Test/_files/source_items_on_default_source.php b/InventoryCatalog/Test/_files/source_items_on_default_source.php index 38a64cf003ce..0343660400d0 100644 --- a/InventoryCatalog/Test/_files/source_items_on_default_source.php +++ b/InventoryCatalog/Test/_files/source_items_on_default_source.php @@ -5,11 +5,14 @@ */ declare(strict_types=1); +use Magento\CatalogInventory\Model\Stock; use Magento\Framework\Api\DataObjectHelper; use Magento\InventoryApi\Api\Data\SourceItemInterface; use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory; use Magento\InventoryApi\Api\SourceItemsSaveInterface; +use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus; use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface; +use Magento\InventorySalesApi\Api\AreProductsSalableInterface; use Magento\TestFramework\Helper\Bootstrap; /** @var DataObjectHelper $dataObjectHelper */ @@ -20,6 +23,10 @@ $sourceItemsSave = Bootstrap::getObjectManager()->get(SourceItemsSaveInterface::class); /** @var DefaultSourceProviderInterface $defaultSourceProvider */ $defaultSourceProvider = Bootstrap::getObjectManager()->get(DefaultSourceProviderInterface::class); +/** @var AreProductsSalableInterface $areProductsSalable */ +$areProductsSalable = Bootstrap::getObjectManager()->get(AreProductsSalableInterface::class); +/** @var SetDataToLegacyStockStatus $setDataToLegacyStockStatus */ +$setDataToLegacyStockStatus = Bootstrap::getObjectManager()->get(SetDataToLegacyStockStatus::class); /** * SKU-1 - Default-source-1(id:10) - 5.5qty @@ -60,10 +67,25 @@ ]; $sourceItems = []; +$skus = []; foreach ($sourcesItemsData as $sourceItemData) { /** @var SourceItemInterface $source */ $sourceItem = $sourceItemFactory->create(); $dataObjectHelper->populateWithArray($sourceItem, $sourceItemData, SourceItemInterface::class); $sourceItems[] = $sourceItem; + $skus[] = $sourceItemData[SourceItemInterface::SKU]; } $sourceItemsSave->execute($sourceItems); + +$stockStatuses = []; +foreach ($areProductsSalable->execute($skus, Stock::DEFAULT_STOCK_ID) as $productSalable) { + $stockStatuses[$productSalable->getSku()] = $productSalable->isSalable(); +} + +foreach ($sourceItems as $sourceItem) { + $setDataToLegacyStockStatus->execute( + (string)$sourceItem->getSku(), + (float)$sourceItem->getQuantity(), + $stockStatuses[(string)$sourceItem->getSku()] === true ? 1 : 0 + ); +} diff --git a/InventoryCatalog/etc/di.xml b/InventoryCatalog/etc/di.xml index 2910bc2ca1b0..5b99168b52c3 100644 --- a/InventoryCatalog/etc/di.xml +++ b/InventoryCatalog/etc/di.xml @@ -100,6 +100,7 @@ + resourceConnection->getConnection()->getCheckSql( 'source_item.' . SourceItemInterface::STATUS . ' = ' . SourceItemInterface::STATUS_OUT_OF_STOCK, 0, - SourceItemInterface::QUANTITY + 'source_item.' . SourceItemInterface::QUANTITY ); $sourceCodes = $this->getSourceCodes($stockId); + $reservationsTableName = 'reservations_temp_for_stock_' . $stockId; + $table = $connection->newTable($reservationsTableName); + $table->addColumn( + 'sku', + Table::TYPE_TEXT, + 64, + [ + Table::OPTION_PRIMARY => true, + Table::OPTION_NULLABLE => false, + ], + 'Sku' + ); + $table->addColumn( + 'reservation_qty', + Table::TYPE_DECIMAL, + null, + [ + Table::OPTION_UNSIGNED => false, + Table::OPTION_NULLABLE => false, + Table::OPTION_DEFAULT => 0, + Table::OPTION_PRECISION => 10, + Table::OPTION_SCALE => 4, + ], + 'Reservation Qty' + ); + $table->addIndex( + 'index_sku_qty', + ['sku'], + ['type' => AdapterInterface::INDEX_TYPE_INDEX] + ); + $connection->createTemporaryTable($table); + + $reservationsData = $connection->select(); + $reservationsData->from( + ['reservations' => $this->resourceConnection->getTableName('inventory_reservation')], + [ + 'sku', + 'reservation_qty' => 'SUM(reservations.quantity)' + ] + ); + $reservationsData->group(['sku', 'stock_id']); + + $insRes = $connection->insertFromSelect($reservationsData, $reservationsTableName); + $connection->query($insRes); + $select = $connection->select(); $select->joinLeft( ['product' => $this->resourceConnection->getTableName($this->productTableName)], @@ -79,6 +126,10 @@ public function execute(int $stockId): Select ['legacy_stock_item' => $this->resourceConnection->getTableName('cataloginventory_stock_item')], 'product.entity_id = legacy_stock_item.product_id', [] + )->joinLeft( + ['reservations_qty' => $this->resourceConnection->getTableName($reservationsTableName)], + ' source_item.' . SourceItemInterface::SKU . ' = reservations_qty.sku', + [] ); $select->from( @@ -90,7 +141,7 @@ public function execute(int $stockId): Select ] ) ->where('source_item.' . SourceItemInterface::SOURCE_CODE . ' IN (?)', $sourceCodes) - ->group([SourceItemInterface::SKU]); + ->group(['source_item.' .SourceItemInterface::SKU]); return $select; } diff --git a/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php b/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php index 85851a5942e7..b4d5bbc6539d 100644 --- a/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php +++ b/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php @@ -8,6 +8,8 @@ namespace Magento\InventoryIndexer\Indexer\SourceItem\Strategy; use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Ddl\Table; use Magento\InventoryCatalogApi\Api\DefaultStockProviderInterface; use Magento\InventoryIndexer\Indexer\InventoryIndexer; use Magento\InventoryIndexer\Indexer\SourceItem\GetSkuListInStock; @@ -58,6 +60,11 @@ class Sync */ private $defaultStockProvider; + /** + * @var ResourceConnection + */ + private $resourceConnection; + /** * $indexStructure is reserved name for construct variable (in index internal mechanism) * @@ -76,7 +83,8 @@ public function __construct( IndexDataBySkuListProvider $indexDataBySkuListProvider, IndexNameBuilder $indexNameBuilder, StockIndexer $stockIndexer, - DefaultStockProviderInterface $defaultStockProvider + DefaultStockProviderInterface $defaultStockProvider, + ResourceConnection $resourceConnection ) { $this->getSkuListInStock = $getSkuListInStockToUpdate; $this->indexStructure = $indexStructureHandler; @@ -85,6 +93,7 @@ public function __construct( $this->indexNameBuilder = $indexNameBuilder; $this->stockIndexer = $stockIndexer; $this->defaultStockProvider = $defaultStockProvider; + $this->resourceConnection = $resourceConnection; } /** @@ -126,6 +135,10 @@ public function executeList(array $sourceItemIds) : void $indexData, ResourceConnection::DEFAULT_CONNECTION ); + + $reservationsTableName = 'reservations_temp_for_stock_' . $stockId; + $connection = $this->resourceConnection->getConnection(); + $connection->dropTemporaryTable($reservationsTableName); } } diff --git a/InventoryIndexer/Indexer/Stock/Strategy/Sync.php b/InventoryIndexer/Indexer/Stock/Strategy/Sync.php index fb5d6506a320..e81c7ceca8a3 100644 --- a/InventoryIndexer/Indexer/Stock/Strategy/Sync.php +++ b/InventoryIndexer/Indexer/Stock/Strategy/Sync.php @@ -57,6 +57,11 @@ class Sync */ private $defaultStockProvider; + /** + * @var ResourceConnection + */ + private $resourceConnection; + /** * $indexStructure is reserved name for construct variable in index internal mechanism * @@ -75,7 +80,8 @@ public function __construct( IndexNameBuilder $indexNameBuilder, IndexDataProviderByStockId $indexDataProviderByStockId, IndexTableSwitcherInterface $indexTableSwitcher, - DefaultStockProviderInterface $defaultStockProvider + DefaultStockProviderInterface $defaultStockProvider, + ResourceConnection $resourceConnection ) { $this->getAllStockIds = $getAllStockIds; $this->indexStructure = $indexStructureHandler; @@ -84,6 +90,7 @@ public function __construct( $this->indexDataProviderByStockId = $indexDataProviderByStockId; $this->indexTableSwitcher = $indexTableSwitcher; $this->defaultStockProvider = $defaultStockProvider; + $this->resourceConnection = $resourceConnection; } /** @@ -147,6 +154,10 @@ public function executeList(array $stockIds): void ); $this->indexTableSwitcher->switch($mainIndexName, ResourceConnection::DEFAULT_CONNECTION); $this->indexStructure->delete($replicaIndexName, ResourceConnection::DEFAULT_CONNECTION); + + $reservationsTableName = 'reservations_temp_for_stock_' . $stockId; + $connection = $this->resourceConnection->getConnection(); + $connection->dropTemporaryTable($reservationsTableName); } } } diff --git a/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/IsStockItemSalableConditionChain.php b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/IsStockItemSalableConditionChain.php index fb93eb8a3b5c..8ab63e35ba8c 100644 --- a/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/IsStockItemSalableConditionChain.php +++ b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/IsStockItemSalableConditionChain.php @@ -21,6 +21,11 @@ class IsStockItemSalableConditionChain implements GetIsStockItemSalableCondition */ private $conditions = []; + /** + * @var GetIsStockItemSalableConditionInterface[] + */ + private $requiredConditions = []; + /** * @var ResourceConnection */ @@ -29,12 +34,13 @@ class IsStockItemSalableConditionChain implements GetIsStockItemSalableCondition /** * @param ResourceConnection $resourceConnection * @param array $conditions - * + * @param array $requiredConditions * @throws LocalizedException */ public function __construct( ResourceConnection $resourceConnection, - array $conditions = [] + array $conditions = [], + array $requiredConditions = [] ) { foreach ($conditions as $getIsSalableCondition) { if (!$getIsSalableCondition instanceof GetIsStockItemSalableConditionInterface) { @@ -43,8 +49,16 @@ public function __construct( ); } } + foreach ($requiredConditions as $getIsSalableCondition) { + if (!$getIsSalableCondition instanceof GetIsStockItemSalableConditionInterface) { + throw new LocalizedException( + __('Condition must implement %1', GetIsStockItemSalableConditionInterface::class) + ); + } + } $this->resourceConnection = $resourceConnection; $this->conditions = $conditions; + $this->requiredConditions = $requiredConditions; } /** @@ -65,7 +79,20 @@ public function execute(Select $select): string } } - $isSalableString = '(' . implode(') OR (', $conditionStrings) . ')'; + if (empty($this->requiredConditions)) { + $isSalableString = '(' . implode(') OR (', $conditionStrings) . ')'; + } else { + $requiredConditionsStrings = []; + foreach ($this->requiredConditions as $requiredCondition) { + $requiredConditionString = $requiredCondition->execute($select); + if ('' !== trim($requiredConditionString)) { + $requiredConditionsStrings[] = $requiredConditionString; + } + } + $isSalableString = '(' . implode(') AND (', $requiredConditionsStrings) . ')' + . ' AND ((' . implode(') OR (', $conditionStrings) . '))'; + } + return (string)$this->resourceConnection->getConnection()->getCheckSql($isSalableString, 1, 0); } } diff --git a/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/MinQtyStockCondition.php b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/MinQtyStockCondition.php index 6f74e532fbfa..05369ceec41d 100644 --- a/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/MinQtyStockCondition.php +++ b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/MinQtyStockCondition.php @@ -50,7 +50,7 @@ public function execute(Select $select): string $quantityExpression = (string)$this->resourceConnection->getConnection()->getCheckSql( 'source_item.' . SourceItemInterface::STATUS . ' = ' . SourceItemInterface::STATUS_OUT_OF_STOCK, 0, - SourceItemInterface::QUANTITY + 'source_item.' . SourceItemInterface::QUANTITY ); $quantityExpression = 'SUM(' . $quantityExpression . ')'; diff --git a/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php new file mode 100644 index 000000000000..c76482e3020a --- /dev/null +++ b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php @@ -0,0 +1,41 @@ +configuration = $configuration; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function execute(Select $select): string + { + $globalMinQty = $this->configuration->getMinQty(); + return 'reservation_qty IS NULL OR (source_item.' . SourceItemInterface::QUANTITY . ' + reservation_qty) > ' . $globalMinQty; + + } +} diff --git a/InventorySales/etc/di.xml b/InventorySales/etc/di.xml index 19faa0c3719d..12b95a877435 100644 --- a/InventorySales/etc/di.xml +++ b/InventorySales/etc/di.xml @@ -48,6 +48,9 @@ Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\MinQtyStockCondition Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\SkuIsAbsentInCatalogCondition + + Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\ReservationsCondition + diff --git a/InventoryShipping/Test/_files/source_items_for_bundle_children.php b/InventoryShipping/Test/_files/source_items_for_bundle_children.php index 6fe9569e74cd..05382528924c 100644 --- a/InventoryShipping/Test/_files/source_items_for_bundle_children.php +++ b/InventoryShipping/Test/_files/source_items_for_bundle_children.php @@ -5,11 +5,15 @@ */ declare(strict_types=1); +use Magento\CatalogInventory\Model\Stock; use Magento\Framework\Api\DataObjectHelper; use Magento\InventoryApi\Api\Data\SourceItemInterface; use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory; use Magento\InventoryApi\Api\SourceItemsSaveInterface; +use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockItem; +use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus; use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface; +use Magento\InventorySalesApi\Api\AreProductsSalableInterface; use Magento\TestFramework\Helper\Bootstrap; /** @var DataObjectHelper $dataObjectHelper */ @@ -43,10 +47,36 @@ ]; $sourceItems = []; +$skus = []; foreach ($sourcesItemsData as $sourceItemData) { /** @var SourceItemInterface $source */ $sourceItem = $sourceItemFactory->create(); $dataObjectHelper->populateWithArray($sourceItem, $sourceItemData, SourceItemInterface::class); $sourceItems[] = $sourceItem; + $skus[] = $sourceItemData[SourceItemInterface::SKU]; } $sourceItemsSave->execute($sourceItems); + +/** @var AreProductsSalableInterface $areProductsSalable */ +$areProductsSalable = Bootstrap::getObjectManager()->get(AreProductsSalableInterface::class); +/** @var SetDataToLegacyStockStatus $setDataToLegacyStockStatus */ +$setDataToLegacyStockStatus = Bootstrap::getObjectManager()->get(SetDataToLegacyStockStatus::class); +/** @var SetDataToLegacyStockItem $setDataToLegacyStockItem */ +$setDataToLegacyStockItem = Bootstrap::getObjectManager()->get(SetDataToLegacyStockItem::class); + +$stockStatuses = []; +foreach ($areProductsSalable->execute($skus, Stock::DEFAULT_STOCK_ID) as $productSalable) { + $stockStatuses[$productSalable->getSku()] = $productSalable->isSalable(); +} +foreach ($sourceItems as $sourceItem) { + $setDataToLegacyStockItem->execute( + (string)$sourceItem->getSku(), + (float)$sourceItem->getQuantity(), + (int)$sourceItem->getStatus() + ); + $setDataToLegacyStockStatus->execute( + (string)$sourceItem->getSku(), + (float)$sourceItem->getQuantity(), + $stockStatuses[(string)$sourceItem->getSku()] === true ? 1 : 0 + ); +} diff --git a/InventoryShipping/Test/_files/source_items_for_virtual_on_default_source.php b/InventoryShipping/Test/_files/source_items_for_virtual_on_default_source.php index 1c8cb1ec7ef2..3132b2550c44 100644 --- a/InventoryShipping/Test/_files/source_items_for_virtual_on_default_source.php +++ b/InventoryShipping/Test/_files/source_items_for_virtual_on_default_source.php @@ -5,11 +5,15 @@ */ declare(strict_types=1); +use Magento\CatalogInventory\Model\Stock; use Magento\Framework\Api\DataObjectHelper; use Magento\InventoryApi\Api\Data\SourceItemInterface; use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory; use Magento\InventoryApi\Api\SourceItemsSaveInterface; +use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockItem; +use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus; use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface; +use Magento\InventorySalesApi\Api\AreProductsSalableInterface; use Magento\TestFramework\Helper\Bootstrap; /** @var DataObjectHelper $dataObjectHelper */ @@ -57,10 +61,36 @@ ]; $sourceItems = []; +$skus = []; foreach ($sourcesItemsData as $sourceItemData) { /** @var SourceItemInterface $source */ $sourceItem = $sourceItemFactory->create(); $dataObjectHelper->populateWithArray($sourceItem, $sourceItemData, SourceItemInterface::class); $sourceItems[] = $sourceItem; + $skus[] = $sourceItemData[SourceItemInterface::SKU]; } $sourceItemsSave->execute($sourceItems); + +/** @var AreProductsSalableInterface $areProductsSalable */ +$areProductsSalable = Bootstrap::getObjectManager()->get(AreProductsSalableInterface::class); +/** @var SetDataToLegacyStockStatus $setDataToLegacyStockStatus */ +$setDataToLegacyStockStatus = Bootstrap::getObjectManager()->get(SetDataToLegacyStockStatus::class); +/** @var SetDataToLegacyStockItem $setDataToLegacyStockItem */ +$setDataToLegacyStockItem = Bootstrap::getObjectManager()->get(SetDataToLegacyStockItem::class); + +$stockStatuses = []; +foreach ($areProductsSalable->execute($skus, Stock::DEFAULT_STOCK_ID) as $productSalable) { + $stockStatuses[$productSalable->getSku()] = $productSalable->isSalable(); +} +foreach ($sourceItems as $sourceItem) { + $setDataToLegacyStockItem->execute( + (string)$sourceItem->getSku(), + (float)$sourceItem->getQuantity(), + (int)$sourceItem->getStatus() + ); + $setDataToLegacyStockStatus->execute( + (string)$sourceItem->getSku(), + (float)$sourceItem->getQuantity(), + $stockStatuses[(string)$sourceItem->getSku()] === true ? 1 : 0 + ); +}