diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php index 64a7c4be4e03c..5ea2b636933a3 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php @@ -85,10 +85,16 @@ public function execute($id = null) $ids = [$id]; $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $storeIds = $this->getAssignedStoreIdsOfProduct($id); + $stores = $this->_storeManager->getStores(); foreach ($stores as $store) { $tableExists = $this->_isFlatTableExists($store->getId()); if ($tableExists) { + if (!in_array($store->getId(), $storeIds)) { + $this->flatItemEraser->deleteProductsFromStore($id, $store->getId()); + continue; + } $this->flatItemEraser->removeDeletedProducts($ids, $store->getId()); $this->flatItemEraser->removeDisabledProducts($ids, $store->getId()); } @@ -129,4 +135,23 @@ public function execute($id = null) return $this; } + + /** + * Get list store id where the product is enable + * + * @param int $productId + * @return array + */ + private function getAssignedStoreIdsOfProduct($productId) + { + $select = $this->_connection->select(); + $select->from(['e' => $this->_productIndexerHelper->getTable('store')], ['e.store_id']) + ->where('c.product_id = ' . $productId) + ->joinLeft( + ['c' => $this->_productIndexerHelper->getTable('catalog_product_website')], + 'e.website_id = c.website_id', + [] + ); + return $this->_connection->fetchCol($select); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php index 11d07872fef91..61fad897c6418 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php @@ -160,8 +160,24 @@ public function testExecuteWithExistingFlatTablesCreatesTables() ->willReturn('store_flat_table'); $this->connection->expects($this->any())->method('isTableExists')->with('store_flat_table') ->willReturn(true); + $this->connection->expects($this->any())->method('fetchCol') + ->willReturn(['store_id_1']); $this->flatItemEraser->expects($this->once())->method('removeDeletedProducts'); $this->flatTableBuilder->expects($this->never())->method('build')->with('store_id_1', ['product_id_1']); $this->model->execute('product_id_1'); } + + public function testExecuteWithExistingFlatTablesRemoveProductFromStore() + { + $this->productIndexerHelper->expects($this->any())->method('getFlatTableName') + ->willReturn('store_flat_table'); + $this->connection->expects($this->any())->method('isTableExists')->with('store_flat_table') + ->willReturn(true); + $this->connection->expects($this->any())->method('fetchCol') + ->willReturn([1]); + $this->flatItemEraser->expects($this->once())->method('deleteProductsFromStore'); + $this->flatItemEraser->expects($this->never())->method('removeDeletedProducts'); + $this->flatTableBuilder->expects($this->never())->method('build')->with('store_id_1', ['product_id_1']); + $this->model->execute('product_id_1'); + } }