From 13e4f1a798d6e02a6fac9b1002c46b7e55d91ee6 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Thu, 19 Aug 2021 16:11:13 -0500 Subject: [PATCH 01/12] Fixed issue for default stock --- .../SetDataToLegacyCatalogInventory.php | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) 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; } From 7b1f54c3adaa15644f42a9461cfc69153842ba43 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Fri, 20 Aug 2021 15:29:38 -0500 Subject: [PATCH 02/12] Fixed issue for custom stock --- InventoryIndexer/Indexer/SelectBuilder.php | 2 +- .../IsStockItemSalableConditionChain.php | 33 ++++++++- .../MinQtyStockCondition.php | 2 +- .../ReservationsCondition.php | 68 +++++++++++++++++++ InventorySales/etc/di.xml | 3 + 5 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php diff --git a/InventoryIndexer/Indexer/SelectBuilder.php b/InventoryIndexer/Indexer/SelectBuilder.php index dc63c6d54719..78d5439d64af 100644 --- a/InventoryIndexer/Indexer/SelectBuilder.php +++ b/InventoryIndexer/Indexer/SelectBuilder.php @@ -66,7 +66,7 @@ public function execute(int $stockId): Select $quantityExpression = (string)$this->resourceConnection->getConnection()->getCheckSql( 'source_item.' . SourceItemInterface::STATUS . ' = ' . SourceItemInterface::STATUS_OUT_OF_STOCK, 0, - SourceItemInterface::QUANTITY + 'source_item.' . SourceItemInterface::QUANTITY ); $sourceCodes = $this->getSourceCodes($stockId); 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..aa984f810220 --- /dev/null +++ b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php @@ -0,0 +1,68 @@ +configuration = $configuration; + $this->resourceConnection = $resourceConnection; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function execute(Select $select): string + { + $stockSourceLinkTable = $this->resourceConnection->getTableName(StockSourceLink::TABLE_NAME_STOCK_SOURCE_LINK); + $reservationTable = $this->resourceConnection->getTableName('inventory_reservation'); + $globalMinQty = (float)$this->configuration->getMinQty(); + $itemQty = 'source_item.quantity'; + + $select->joinLeft( + ['stock_source_link' => $stockSourceLinkTable], + 'source_item.' . SourceInterface::SOURCE_CODE . '=' . 'stock_source_link.' . SourceInterface::SOURCE_CODE, + null + )->joinLeft( + ['inventory_reservation' => $reservationTable], + 'product.sku = inventory_reservation.' . ReservationInterface::SKU + . ' AND stock_source_link.' . StockSourceLinkInterface::STOCK_ID . ' = inventory_reservation.' . ReservationInterface::STOCK_ID, + [] + ); + + $qtyWithReservation = '(' . $itemQty . ' + SUM(inventory_reservation.' . ReservationInterface::QUANTITY . '))'; + return 'SUM(inventory_reservation.' . ReservationInterface::QUANTITY . ') IS NULL ' + . 'OR ' . $qtyWithReservation . ' > ' . $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 + From c7a6ac8dbe9b0ee5373999d6d8778ab75c112f93 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Mon, 23 Aug 2021 12:50:12 -0500 Subject: [PATCH 03/12] Fixed issue for custom stock --- InventoryIndexer/Indexer/SelectBuilder.php | 22 ++++++++- .../Indexer/SourceItem/Strategy/Sync.php | 45 ++++++++++++++++++- .../ReservationsCondition.php | 35 ++------------- 3 files changed, 69 insertions(+), 33 deletions(-) diff --git a/InventoryIndexer/Indexer/SelectBuilder.php b/InventoryIndexer/Indexer/SelectBuilder.php index 78d5439d64af..abcbf5d49926 100644 --- a/InventoryIndexer/Indexer/SelectBuilder.php +++ b/InventoryIndexer/Indexer/SelectBuilder.php @@ -8,6 +8,8 @@ namespace Magento\InventoryIndexer\Indexer; use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Ddl\Table; use Magento\Framework\DB\Select; use Magento\Inventory\Model\ResourceModel\Source as SourceResourceModel; use Magento\Inventory\Model\ResourceModel\SourceItem as SourceItemResourceModel; @@ -70,6 +72,20 @@ public function execute(int $stockId): Select ); $sourceCodes = $this->getSourceCodes($stockId); + $reservationsTableName = 'reservations_temp_for_stock_' . $stockId; + $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 +95,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 +110,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..48c83320e7f4 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; } /** @@ -120,12 +129,46 @@ public function executeList(array $sourceItemIds) : void ResourceConnection::DEFAULT_CONNECTION ); + $reservationsTableName = 'reservations_temp_for_stock_' . $stockId; + $connection = $this->resourceConnection->getConnection(); + $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); + $indexData = $this->indexDataBySkuListProvider->execute($stockId, $skuList); $this->indexHandler->saveIndex( $mainIndexName, $indexData, ResourceConnection::DEFAULT_CONNECTION ); + $connection->dropTemporaryTable($reservationsTableName); } } diff --git a/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php index aa984f810220..c76482e3020a 100644 --- a/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php +++ b/InventorySales/Model/ResourceModel/IsStockItemSalableCondition/ReservationsCondition.php @@ -7,10 +7,7 @@ namespace Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition; use Magento\Framework\DB\Select; -use Magento\InventoryApi\Api\Data\SourceInterface; -use Magento\InventoryApi\Api\Data\StockSourceLinkInterface; -use Magento\InventoryReservationsApi\Model\ReservationInterface; -use Magento\Inventory\Model\ResourceModel\StockSourceLink; +use Magento\InventoryApi\Api\Data\SourceItemInterface; use Magento\CatalogInventory\Api\StockConfigurationInterface; use Magento\Framework\App\ResourceConnection; @@ -21,21 +18,14 @@ class ReservationsCondition implements GetIsStockItemSalableConditionInterface */ private $configuration; - /** - * @var ResourceConnection - */ - private $resourceConnection; - /** * @param StockConfigurationInterface $configuration * @param ResourceConnection $resourceConnection */ public function __construct( - StockConfigurationInterface $configuration, - ResourceConnection $resourceConnection + StockConfigurationInterface $configuration ) { $this->configuration = $configuration; - $this->resourceConnection = $resourceConnection; } /** @@ -44,25 +34,8 @@ public function __construct( */ public function execute(Select $select): string { - $stockSourceLinkTable = $this->resourceConnection->getTableName(StockSourceLink::TABLE_NAME_STOCK_SOURCE_LINK); - $reservationTable = $this->resourceConnection->getTableName('inventory_reservation'); - $globalMinQty = (float)$this->configuration->getMinQty(); - $itemQty = 'source_item.quantity'; - - $select->joinLeft( - ['stock_source_link' => $stockSourceLinkTable], - 'source_item.' . SourceInterface::SOURCE_CODE . '=' . 'stock_source_link.' . SourceInterface::SOURCE_CODE, - null - )->joinLeft( - ['inventory_reservation' => $reservationTable], - 'product.sku = inventory_reservation.' . ReservationInterface::SKU - . ' AND stock_source_link.' . StockSourceLinkInterface::STOCK_ID . ' = inventory_reservation.' . ReservationInterface::STOCK_ID, - [] - ); - - $qtyWithReservation = '(' . $itemQty . ' + SUM(inventory_reservation.' . ReservationInterface::QUANTITY . '))'; - return 'SUM(inventory_reservation.' . ReservationInterface::QUANTITY . ') IS NULL ' - . 'OR ' . $qtyWithReservation . ' > ' . $globalMinQty; + $globalMinQty = $this->configuration->getMinQty(); + return 'reservation_qty IS NULL OR (source_item.' . SourceItemInterface::QUANTITY . ' + reservation_qty) > ' . $globalMinQty; } } From d986ca5508e745315e68e23af359032ec73b6abb Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Mon, 23 Aug 2021 16:04:16 -0500 Subject: [PATCH 04/12] Fixed issue for custom stock --- InventoryIndexer/Indexer/SelectBuilder.php | 32 ++++++++++++++ .../Indexer/SourceItem/Strategy/Sync.php | 43 +------------------ 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/InventoryIndexer/Indexer/SelectBuilder.php b/InventoryIndexer/Indexer/SelectBuilder.php index abcbf5d49926..dd466ae417f2 100644 --- a/InventoryIndexer/Indexer/SelectBuilder.php +++ b/InventoryIndexer/Indexer/SelectBuilder.php @@ -73,6 +73,38 @@ public function execute(int $stockId): Select $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); + $connection->truncateTable($reservationsTableName); + $reservationsData = $connection->select(); $reservationsData->from( ['reservations' => $this->resourceConnection->getTableName('inventory_reservation')], diff --git a/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php b/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php index 48c83320e7f4..73ec6386d5df 100644 --- a/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php +++ b/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php @@ -60,11 +60,6 @@ class Sync */ private $defaultStockProvider; - /** - * @var ResourceConnection - */ - private $resourceConnection; - /** * $indexStructure is reserved name for construct variable (in index internal mechanism) * @@ -83,8 +78,7 @@ public function __construct( IndexDataBySkuListProvider $indexDataBySkuListProvider, IndexNameBuilder $indexNameBuilder, StockIndexer $stockIndexer, - DefaultStockProviderInterface $defaultStockProvider, - ResourceConnection $resourceConnection + DefaultStockProviderInterface $defaultStockProvider ) { $this->getSkuListInStock = $getSkuListInStockToUpdate; $this->indexStructure = $indexStructureHandler; @@ -93,7 +87,6 @@ public function __construct( $this->indexNameBuilder = $indexNameBuilder; $this->stockIndexer = $stockIndexer; $this->defaultStockProvider = $defaultStockProvider; - $this->resourceConnection = $resourceConnection; } /** @@ -129,46 +122,12 @@ public function executeList(array $sourceItemIds) : void ResourceConnection::DEFAULT_CONNECTION ); - $reservationsTableName = 'reservations_temp_for_stock_' . $stockId; - $connection = $this->resourceConnection->getConnection(); - $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); - $indexData = $this->indexDataBySkuListProvider->execute($stockId, $skuList); $this->indexHandler->saveIndex( $mainIndexName, $indexData, ResourceConnection::DEFAULT_CONNECTION ); - $connection->dropTemporaryTable($reservationsTableName); } } From 9ba1d8f3be56383ac29018c55650865dcac09d3a Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Mon, 23 Aug 2021 18:19:09 -0500 Subject: [PATCH 05/12] Fixed issue for custom stock --- InventoryIndexer/Indexer/SelectBuilder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/InventoryIndexer/Indexer/SelectBuilder.php b/InventoryIndexer/Indexer/SelectBuilder.php index dd466ae417f2..017dec5da374 100644 --- a/InventoryIndexer/Indexer/SelectBuilder.php +++ b/InventoryIndexer/Indexer/SelectBuilder.php @@ -103,7 +103,6 @@ public function execute(int $stockId): Select ['type' => AdapterInterface::INDEX_TYPE_INDEX] ); $connection->createTemporaryTable($table); - $connection->truncateTable($reservationsTableName); $reservationsData = $connection->select(); $reservationsData->from( From c4365b82af699976ff527c5006ec843b431151c9 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Tue, 24 Aug 2021 10:58:51 -0500 Subject: [PATCH 06/12] Fixed issue for custom stock --- .../Indexer/SourceItem/Strategy/Sync.php | 13 ++++++++++++- InventoryIndexer/Indexer/Stock/Strategy/Sync.php | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php b/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php index 73ec6386d5df..b4d5bbc6539d 100644 --- a/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php +++ b/InventoryIndexer/Indexer/SourceItem/Strategy/Sync.php @@ -60,6 +60,11 @@ class Sync */ private $defaultStockProvider; + /** + * @var ResourceConnection + */ + private $resourceConnection; + /** * $indexStructure is reserved name for construct variable (in index internal mechanism) * @@ -78,7 +83,8 @@ public function __construct( IndexDataBySkuListProvider $indexDataBySkuListProvider, IndexNameBuilder $indexNameBuilder, StockIndexer $stockIndexer, - DefaultStockProviderInterface $defaultStockProvider + DefaultStockProviderInterface $defaultStockProvider, + ResourceConnection $resourceConnection ) { $this->getSkuListInStock = $getSkuListInStockToUpdate; $this->indexStructure = $indexStructureHandler; @@ -87,6 +93,7 @@ public function __construct( $this->indexNameBuilder = $indexNameBuilder; $this->stockIndexer = $stockIndexer; $this->defaultStockProvider = $defaultStockProvider; + $this->resourceConnection = $resourceConnection; } /** @@ -128,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); } } } From 7030e458e4bc9f842662f6260eb530a93464f29a Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Wed, 25 Aug 2021 14:30:05 -0500 Subject: [PATCH 07/12] Fixed issue for default stock --- .../source_items_for_bundle_children.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) 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 + ); +} From e0ac8b65e552f821a9ad8c30fd7421e39d32fe8a Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Thu, 26 Aug 2021 09:57:54 -0500 Subject: [PATCH 08/12] Fixed issue for default stock --- ...ce_items_for_virtual_on_default_source.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) 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 + ); +} From 94ed063deef236820b2195519eb9a0850577ad93 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Thu, 26 Aug 2021 11:37:02 -0500 Subject: [PATCH 09/12] Fixed issue for custom stock --- .../Model/BulkInventoryTransfer.php | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) 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). * From 5fbc37274253a3c0b49b0b48a97e98b8eb54cd05 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Thu, 26 Aug 2021 16:22:05 -0500 Subject: [PATCH 10/12] Fixed issue for default stock --- .../AdaptUpdateStockStatusBySkuPlugin.php | 49 +++++++++++++++++++ InventoryCatalog/etc/di.xml | 1 + 2 files changed, 50 insertions(+) create mode 100644 InventoryCatalog/Plugin/CatalogInventory/Api/StockRegistry/AdaptUpdateStockStatusBySkuPlugin.php 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/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 @@ + Date: Fri, 27 Aug 2021 11:17:38 -0500 Subject: [PATCH 11/12] Fixed issue for default stock --- .../_files/source_items_on_default_source.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) 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 + ); +} From 10270a3f9cf88eb502c36f232e98fe0228c9032d Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Fri, 27 Aug 2021 14:25:51 -0500 Subject: [PATCH 12/12] Fixed issue for default stock --- .../Test/Integration/Order/PlaceOrderOnDefaultStockTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/InventoryGroupedProduct/Test/Integration/Order/PlaceOrderOnDefaultStockTest.php b/InventoryGroupedProduct/Test/Integration/Order/PlaceOrderOnDefaultStockTest.php index 50cd1b06300a..35b453ab4dec 100644 --- a/InventoryGroupedProduct/Test/Integration/Order/PlaceOrderOnDefaultStockTest.php +++ b/InventoryGroupedProduct/Test/Integration/Order/PlaceOrderOnDefaultStockTest.php @@ -104,7 +104,6 @@ public function testPlaceOrderWithOutOffStockProductAndBackOrdersTurnedOn(): voi /** * @magentoDataFixture Magento_InventoryGroupedProduct::Test/_files/default_stock_grouped_products.php - * @magentoDataFixture Magento_InventoryCatalog::Test/_files/source_items_on_default_source.php * @magentoDataFixture Magento_InventorySalesApi::Test/_files/quote.php * @magentoDataFixture Magento_InventoryIndexer::Test/_files/reindex_inventory.php * @magentoConfigFixture current_store cataloginventory/item_options/manage_stock 0