diff --git a/app/code/Magento/InventoryApi/Test/_files/products.php b/app/code/Magento/InventoryApi/Test/_files/products.php
index 4c04fdd9c642..08ce6888fd95 100644
--- a/app/code/Magento/InventoryApi/Test/_files/products.php
+++ b/app/code/Magento/InventoryApi/Test/_files/products.php
@@ -16,6 +16,24 @@
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
$productRepository->cleanCache();
+$stockData = [
+ 'SKU-1' => [
+ 'qty' => 8.5,
+ 'is_in_stock' => true,
+ 'manage_stock' => true
+ ],
+ 'SKU-2' => [
+ 'qty' => 5,
+ 'is_in_stock' => true,
+ 'manage_stock' => true
+ ],
+ 'SKU-3' => [
+ 'qty' => 0,
+ 'is_in_stock' => false,
+ 'manage_stock' => true
+ ]
+];
+
for ($i = 1; $i <= 3; $i++) {
$product = $productFactory->create();
$product->setTypeId(Type::TYPE_SIMPLE)
@@ -23,6 +41,7 @@
->setName('Simple Product ' . $i)
->setSku('SKU-' . $i)
->setPrice(10)
+ ->setStockData($stockData['SKU-' . $i])
->setStatus(Status::STATUS_ENABLED);
$productRepository->save($product);
}
diff --git a/app/code/Magento/InventoryApi/Test/_files/products_rollback.php b/app/code/Magento/InventoryApi/Test/_files/products_rollback.php
index 021e40448a00..06de7fe3b82c 100644
--- a/app/code/Magento/InventoryApi/Test/_files/products_rollback.php
+++ b/app/code/Magento/InventoryApi/Test/_files/products_rollback.php
@@ -4,6 +4,8 @@
* See COPYING.txt for license details.
*/
use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory;
+use Magento\CatalogInventory\Api\StockStatusRepositoryInterface;
use Magento\Framework\Registry;
use Magento\TestFramework\Helper\Bootstrap;
@@ -12,12 +14,25 @@
$productRepository = $objectManager->create(ProductRepositoryInterface::class);
/** @var Registry $registry */
$registry = $objectManager->get(Registry::class);
+/** @var StockStatusRepositoryInterface $stockStatusRepository */
+$stockStatusRepository = $objectManager->create(StockStatusRepositoryInterface::class);
+/** @var StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory */
+$stockStatusCriteriaFactory = $objectManager->create(StockStatusCriteriaInterfaceFactory::class);
$currentArea = $registry->registry('isSecureArea');
$registry->unregister('isSecureArea');
$registry->register('isSecureArea', true);
for ($i = 1; $i <= 3; $i++) {
+ $product = $productRepository->get('SKU-' . $i);
+ /** @var \Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory **/
+ $criteria = $stockStatusCriteriaFactory->create();
+ $criteria->setProductsFilter($product->getId());
+
+ $result = $stockStatusRepository->getList($criteria);
+ $stockStatus = current($result->getItems());
+ $stockStatusRepository->delete($stockStatus);
+
$productRepository->deleteById('SKU-' . $i);
}
diff --git a/app/code/Magento/InventoryCatalog/Plugin/Model/UpdateLegacyCatalogInventoryPlugin.php b/app/code/Magento/InventoryCatalog/Plugin/Model/UpdateLegacyCatalogInventoryPlugin.php
new file mode 100644
index 000000000000..ba6de0ccac19
--- /dev/null
+++ b/app/code/Magento/InventoryCatalog/Plugin/Model/UpdateLegacyCatalogInventoryPlugin.php
@@ -0,0 +1,88 @@
+resourceConnection = $resourceConnection;
+ $this->productRepository = $productRepository;
+ $this->stockRegistry = $stockRegistry;
+ }
+
+ /**
+ * Plugin method to fill the legacy tables.
+ *
+ * @param ReservationsAppendInterface $subject
+ * @param void $result
+ * @param ReservationInterface[] $reservations
+ *
+ * @see ReservationsAppendInterface::execute
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @return void
+ */
+ public function afterExecute(ReservationsAppendInterface $subject, $result, array $reservations)
+ {
+ $this->updateStockItemAndStatusTable($reservations);
+ return $result;
+ }
+
+ /**
+ * Updates cataloginventory_stock_item and cataloginventory_stock_status qty with reservation information.
+ *
+ * @param ReservationInterface[] $reservations
+ * @return void
+ */
+ private function updateStockItemAndStatusTable(array $reservations)
+ {
+ foreach ($reservations as $reservation) {
+ $sku = $reservation->getSku();
+ $stockItem = $this->stockRegistry->getStockItemBySku($sku);
+ $stockItem->setQty($stockItem->getQty() + $reservation->getQuantity());
+ $this->stockRegistry->updateStockItemBySku($sku, $stockItem);
+
+ $stockStatus = $this->stockRegistry->getStockStatus($stockItem->getProductId());
+ $stockStatus->setQty($stockStatus->getQty() + $reservation->getQuantity());
+ $stockStatus->save();
+ }
+ }
+}
diff --git a/app/code/Magento/InventoryCatalog/Test/Integration/UpdateLegacyCatalogInventoryPluginTest.php b/app/code/Magento/InventoryCatalog/Test/Integration/UpdateLegacyCatalogInventoryPluginTest.php
new file mode 100644
index 000000000000..d1be1262f809
--- /dev/null
+++ b/app/code/Magento/InventoryCatalog/Test/Integration/UpdateLegacyCatalogInventoryPluginTest.php
@@ -0,0 +1,152 @@
+reservationBuilder = Bootstrap::getObjectManager()->get(ReservationBuilderInterface::class);
+ $this->reservationsAppend = Bootstrap::getObjectManager()->get(ReservationsAppendInterface::class);
+ $this->oldStockItemRepository = Bootstrap::getObjectManager()->get(StockItemRepositoryInterface::class);
+ $this->stockItemCriteriaFactory = Bootstrap::getObjectManager()->get(StockItemCriteriaInterfaceFactory::class);
+
+ $this->indexer = Bootstrap::getObjectManager()->get(Indexer::class);
+ $this->indexer->load(SourceItemIndexer::INDEXER_ID);
+ $this->getProductQtyInStock = Bootstrap::getObjectManager()->get(GetProductQuantityInStockInterface::class);
+ $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+ }
+
+ /**
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stocks.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock_source_link.php
+ */
+ public function testUpdateStockItemTable()
+ {
+ $reservationQuantity = -5;
+
+ /** @var Product $product */
+ $product = $this->productRepository->get('SKU-1');
+
+ /** @var StockItemCriteriaInterface $criteria */
+ $criteria = $this->stockItemCriteriaFactory->create();
+ $criteria->setProductsFilter([$product->getId()]);
+
+ /** @var StockItemCollectionInterface $collectionBeforeChange */
+ $collectionBeforeChange = $this->oldStockItemRepository->getList($criteria);
+ /** @var StockItemInterface $oldStockItem */
+ $oldStockItem = current($collectionBeforeChange->getItems());
+ $initialQuantity = $oldStockItem->getQty();
+
+ $this->reservationsAppend->execute([
+ $this->reservationBuilder->setStockId(1)->setSku('SKU-1')->setQuantity($reservationQuantity)->build()
+ ]);
+
+ /** @var StockItemCollectionInterface $collectionAfterChange */
+ $collectionAfterChange = $this->oldStockItemRepository->getList($criteria);
+ $oldStockItem = current($collectionAfterChange->getItems());
+ $quantityAfterCheck = $oldStockItem->getQty();
+
+ $this->assertEquals($initialQuantity + $reservationQuantity, $quantityAfterCheck);
+ }
+
+ /**
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stocks.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php
+ * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock_source_link.php
+ */
+ public function testThatReservationPlacedUpdatesBothOldAndNewStocks()
+ {
+ $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+ $reservationQuantity = -5;
+
+ $this->indexer->reindexAll();
+ $this->assertEquals(8.5, $this->getProductQtyInStock->execute('SKU-1', 10));
+
+ /** @var Product $product */
+ $product = $this->productRepository->get('SKU-1');
+
+ /** @var StockItemCriteriaInterface $criteria */
+ $criteria = $this->stockItemCriteriaFactory->create();
+ $criteria->setProductsFilter([$product->getId()]);
+
+ /** @var StockItemCollectionInterface $collectionBeforeChange */
+ $collectionBeforeChange = $this->oldStockItemRepository->getList($criteria);
+
+ /** @var StockItemInterface $oldStockItem */
+ $oldStockItem = current($collectionBeforeChange->getItems());
+ $initialQuantity = $oldStockItem->getQty();
+ $this->assertEquals(8.5, $initialQuantity);
+
+ $this->reservationsAppend->execute([
+ $this->reservationBuilder->setStockId(10)->setSku('SKU-1')->setQuantity($reservationQuantity)->build()
+ ]);
+
+ /** @var StockItemCollectionInterface $collectionAfterChange */
+ $collectionAfterChange = $this->oldStockItemRepository->getList($criteria);
+ $oldStockItem = current($collectionAfterChange->getItems());
+ $quantityAfterCheck = $oldStockItem->getQty();
+
+ $this->assertEquals(8.5 - 5, $this->getProductQtyInStock->execute('SKU-1', 10));
+ $this->assertEquals($this->getProductQtyInStock->execute('SKU-1', 10), $quantityAfterCheck);
+ }
+}
diff --git a/app/code/Magento/InventoryCatalog/etc/di.xml b/app/code/Magento/InventoryCatalog/etc/di.xml
index d7e40373206c..d394c22bdea2 100644
--- a/app/code/Magento/InventoryCatalog/etc/di.xml
+++ b/app/code/Magento/InventoryCatalog/etc/di.xml
@@ -14,4 +14,7 @@
+
+
+