Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/code/Magento/InventoryApi/Test/_files/products.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,32 @@
$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)
->setAttributeSetId(4)
->setName('Simple Product ' . $i)
->setSku('SKU-' . $i)
->setPrice(10)
->setStockData($stockData['SKU-' . $i])
->setStatus(Status::STATUS_ENABLED);
$productRepository->save($product);
}
15 changes: 15 additions & 0 deletions app/code/Magento/InventoryApi/Test/_files/products_rollback.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\InventoryCatalog\Plugin\Model;

use Magento\Framework\App\ResourceConnection;
use Magento\InventoryApi\Api\Data\ReservationInterface;
use Magento\InventoryApi\Api\ReservationsAppendInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;

/**
* Plugin help to fill the legacy catalog inventory tables cataloginventory_stock_status and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helpS

* cataloginventory_stock_item to don't break the backward compatible.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to don't break the backward compatible. ->
to prevent breaking the backward compatibility

*/
class UpdateLegacyCatalogInventoryPlugin
{

/**
* @var ResourceConnection
*/
private $resourceConnection;

/**
* @var ProductRepositoryInterface
*/
private $productRepository;

/**
* @var \Magento\CatalogInventory\Api\StockRegistryInterface
*/
private $stockRegistry;

/**
* @param ResourceConnection $resourceConnection
* @param ProductRepositoryInterface $productRepository
* @param StockRegistryInterface $stockRegistry
*/
public function __construct(
ResourceConnection $resourceConnection,
ProductRepositoryInterface $productRepository,
StockRegistryInterface $stockRegistry
) {
$this->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();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\InventoryCatalog\Test\Integration;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\InventoryApi\Api\ReservationBuilderInterface;
use Magento\InventoryApi\Api\ReservationsAppendInterface;
use PHPUnit\Framework\TestCase;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
use Magento\CatalogInventory\Api\StockItemCriteriaInterface;
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
use Magento\CatalogInventory\Api\Data\StockItemCollectionInterface;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\InventoryApi\Api\GetProductQuantityInStockInterface;
use Magento\Indexer\Model\Indexer;
use Magento\Inventory\Indexer\SourceItem\SourceItemIndexer;

class UpdateLegacyCatalogInventoryPluginTest extends TestCase
{
/**
* @var ReservationBuilderInterface
*/
private $reservationBuilder;

/**
* @var ReservationsAppendInterface
*/
private $reservationsAppend;

/**
* @var StockItemRepositoryInterface
*/
private $oldStockItemRepository;

/**
* @var StockItemCriteriaInterfaceFactory
*/
private $stockItemCriteriaFactory;

/**
* @var GetProductQuantityInStockInterface
*/
private $getProductQtyInStock;

/**
* @var IndexerInterface
*/
private $indexer;

/**
* @var ProductRepositoryInterface
*/
private $productRepository;

protected function setUp()
{
$this->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);
}
}
3 changes: 3 additions & 0 deletions app/code/Magento/InventoryCatalog/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@
<plugin name="prevent_assigned_to_sales_channels_stock_deleting"
type="Magento\InventoryCatalog\Plugin\InventoryApi\StockRepository\PreventDeleting\AssignedToSalesChannelsStockPlugin"/>
</type>
<type name="Magento\InventoryApi\Api\ReservationsAppendInterface">
<plugin name="update_legacy_catalog_inventory_plugin" type="Magento\InventoryCatalog\Plugin\Model\UpdateLegacyCatalogInventoryPlugin"/>
</type>
</config>