diff --git a/app/code/Magento/CatalogInventory/Model/StockStateProvider.php b/app/code/Magento/CatalogInventory/Model/StockStateProvider.php index 4cffc678314b..7209f5f23b3a 100644 --- a/app/code/Magento/CatalogInventory/Model/StockStateProvider.php +++ b/app/code/Magento/CatalogInventory/Model/StockStateProvider.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); // @codingStandardsIgnoreFile @@ -14,6 +15,7 @@ use Magento\Framework\Locale\FormatInterface; use Magento\Framework\Math\Division as MathDivision; use Magento\Framework\DataObject\Factory as ObjectFactory; +use Magento\InventorySales\Model\GetProductQuantityInterface; /** * Interface StockStateProvider @@ -45,11 +47,17 @@ class StockStateProvider implements StockStateProviderInterface */ protected $qtyCheckApplicable; + /** + * @var GetProductQuantityInterface + */ + private $getProductQuantity; + /** * @param MathDivision $mathDivision * @param FormatInterface $localeFormat * @param ObjectFactory $objectFactory * @param ProductFactory $productFactory + * @param GetProductQuantityInterface $getProductQuantity * @param bool $qtyCheckApplicable */ public function __construct( @@ -57,6 +65,7 @@ public function __construct( FormatInterface $localeFormat, ObjectFactory $objectFactory, ProductFactory $productFactory, + GetProductQuantityInterface $getProductQuantity, $qtyCheckApplicable = true ) { $this->mathDivision = $mathDivision; @@ -64,6 +73,7 @@ public function __construct( $this->objectFactory = $objectFactory; $this->productFactory = $productFactory; $this->qtyCheckApplicable = $qtyCheckApplicable; + $this->getProductQuantity = $getProductQuantity; } /** @@ -72,11 +82,14 @@ public function __construct( */ public function verifyStock(StockItemInterface $stockItem) { - if ($stockItem->getQty() === null && $stockItem->getManageStock()) { +// prototype code +// $productQty = $this->getProductQuantity->execute($stockItem); + $productQty = $stockItem->getQty(); + if ($productQty === null && $stockItem->getManageStock()) { return false; } if ($stockItem->getBackorders() == StockItemInterface::BACKORDERS_NO - && $stockItem->getQty() <= $stockItem->getMinQty() + && $productQty <= $stockItem->getMinQty() ) { return false; } @@ -89,7 +102,7 @@ public function verifyStock(StockItemInterface $stockItem) */ public function verifyNotification(StockItemInterface $stockItem) { - return (float)$stockItem->getQty() < $stockItem->getNotifyStockQty(); + return $this->getProductQuantity->execute($stockItem) < $stockItem->getNotifyStockQty(); } /** @@ -166,10 +179,11 @@ public function checkQuoteItemQty(StockItemInterface $stockItem, $qty, $summaryQ $result->setHasError(true)->setMessage($message)->setQuoteMessage($message)->setQuoteMessageIndex('qty'); return $result; } else { - if ($stockItem->getQty() - $summaryQty < 0) { + $productQty = $this->getProductQuantity->execute($stockItem); + if ($productQty - $summaryQty < 0) { if ($stockItem->getProductName()) { if ($stockItem->getIsChildItem()) { - $backOrderQty = $stockItem->getQty() > 0 ? ($summaryQty - $stockItem->getQty()) * 1 : $qty * 1; + $backOrderQty = $productQty > 0 ? ($summaryQty - $productQty) * 1 : $qty * 1; if ($backOrderQty > $qty) { $backOrderQty = $qty; } @@ -179,7 +193,7 @@ public function checkQuoteItemQty(StockItemInterface $stockItem, $qty, $summaryQ $orderedItems = (int)$stockItem->getOrderedItems(); // Available item qty in stock excluding item qty in other quotes - $qtyAvailable = ($stockItem->getQty() - ($summaryQty - $qty)) * 1; + $qtyAvailable = ($productQty - ($summaryQty - $qty)) * 1; if ($qtyAvailable > 0) { $backOrderQty = $qty * 1 - $qtyAvailable; } else { @@ -241,7 +255,7 @@ public function checkQty(StockItemInterface $stockItem, $qty) if (!$stockItem->getManageStock()) { return true; } - if ($stockItem->getQty() - $stockItem->getMinQty() - $qty < 0) { + if ($this->getProductQuantity->execute($stockItem) - $stockItem->getMinQty() - $qty < 0) { switch ($stockItem->getBackorders()) { case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NONOTIFY: case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NOTIFY: @@ -277,7 +291,10 @@ public function suggestQty(StockItemInterface $stockItem, $qty) $minQty = max($stockItem->getMinSaleQty(), $qtyIncrements); $divisibleMin = ceil($minQty / $qtyIncrements) * $qtyIncrements; - $maxQty = min($stockItem->getQty() - $stockItem->getMinQty(), $stockItem->getMaxSaleQty()); + $maxQty = min( + $this->getProductQuantity->execute($stockItem) - $stockItem->getMinQty(), + $stockItem->getMaxSaleQty() + ); $divisibleMax = floor($maxQty / $qtyIncrements) * $qtyIncrements; if ($qty < $minQty || $qty > $maxQty || $divisibleMin > $divisibleMax) { @@ -343,7 +360,7 @@ public function getStockQty(StockItemInterface $stockItem) $product->load($stockItem->getProductId()); // prevent possible recursive loop if (!$product->isComposite()) { - $stockQty = $stockItem->getQty(); + $stockQty = $this->getProductQuantity->execute($stockItem); } else { $stockQty = null; $productsByGroups = $product->getTypeInstance()->getProductsToPurchaseByReqGroups($product); diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Spi/StockStateProviderTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Spi/StockStateProviderTest.php index 5c75249b7cbf..c2d69986af50 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Spi/StockStateProviderTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Spi/StockStateProviderTest.php @@ -7,6 +7,7 @@ use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\InventorySales\Model\GetProductQuantityInterface; /** * Class StockStateProviderTest @@ -48,6 +49,11 @@ class StockStateProviderTest extends \PHPUnit\Framework\TestCase */ protected $objectFactory; + /** + * @var \Magento\InventorySales\Model\GetProductQuantityInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $getProductQuantity; + /** * @var \Magento\Framework\DataObject|\PHPUnit_Framework_MockObject_MockObject */ @@ -130,6 +136,8 @@ protected function setUp() $this->productFactory = $this->createPartialMock(\Magento\Catalog\Model\ProductFactory::class, ['create']); $this->productFactory->expects($this->any())->method('create')->willReturn($this->product); + $this->getProductQuantity = $this->createPartialMock(GetProductQuantityInterface::class, ['execute']); + $this->stockStateProvider = $this->objectManagerHelper->getObject( \Magento\CatalogInventory\Model\StockStateProvider::class, [ @@ -137,6 +145,7 @@ protected function setUp() 'localeFormat' => $this->localeFormat, 'objectFactory' => $this->objectFactory, 'productFactory' => $this->productFactory, + 'getProductQuantity' => $this->getProductQuantity, 'qtyCheckApplicable' => $this->qtyCheckApplicable ] ); @@ -154,6 +163,7 @@ protected function tearDown() */ public function testVerifyStock(StockItemInterface $stockItem, $expectedResult) { + $this->getProductQuantity->expects($this->any())->method('execute')->willReturn($stockItem->getQty()); $this->assertEquals( $expectedResult, $this->stockStateProvider->verifyStock($stockItem) @@ -167,6 +177,7 @@ public function testVerifyStock(StockItemInterface $stockItem, $expectedResult) */ public function testVerifyNotification(StockItemInterface $stockItem, $expectedResult) { + $this->getProductQuantity->expects($this->any())->method('execute')->willReturn($stockItem->getQty()); $this->assertEquals( $expectedResult, $this->stockStateProvider->verifyNotification($stockItem) @@ -193,6 +204,7 @@ public function testCheckQty(StockItemInterface $stockItem, $expectedResult) */ public function testSuggestQty(StockItemInterface $stockItem, $expectedResult) { + $this->getProductQuantity->expects($this->any())->method('execute')->willReturn($stockItem->getQty()); $this->assertEquals( $expectedResult, $this->stockStateProvider->suggestQty($stockItem, $this->qty) diff --git a/app/code/Magento/InventoryCatalog/etc/di.xml b/app/code/Magento/InventoryCatalog/etc/di.xml index 34e0b6acc5c3..b5e9cb5137b4 100644 --- a/app/code/Magento/InventoryCatalog/etc/di.xml +++ b/app/code/Magento/InventoryCatalog/etc/di.xml @@ -11,30 +11,24 @@ - + - + - + - + - + - + diff --git a/app/code/Magento/InventorySales/Model/GetProductQuantityInterface.php b/app/code/Magento/InventorySales/Model/GetProductQuantityInterface.php new file mode 100644 index 000000000000..4eaa8c16d234 --- /dev/null +++ b/app/code/Magento/InventorySales/Model/GetProductQuantityInterface.php @@ -0,0 +1,24 @@ +storeManager = $storeManager; + $this->getSkusByProductIds = $getSkusByProductIds; + $this->stockResolver = $stockResolver; + $this->getProductQuantityInStock = $getProductQuantityInStock; + } + + /** + * {@inheritdoc} + */ + public function execute(StockItemInterface $legacyStockItem) + { + try { + $websiteCode = $this->storeManager->getWebsite()->getCode(); + + $productIds = $this->getSkusByProductIds->execute([$legacyStockItem->getProductId()]); + $productSku = $productIds[$legacyStockItem->getProductId()]; + + $stock = $this->stockResolver->get(SalesChannelInterface::TYPE_WEBSITE, $websiteCode); + + return $this->getProductQuantityInStock->execute($productSku, (int)$stock->getStockId()); + } catch (NoSuchEntityException $e) { + return $legacyStockItem->getQty(); + } catch (LocalizedException $e) { + return $legacyStockItem->getQty(); + } + } +} diff --git a/app/code/Magento/InventorySales/etc/di.xml b/app/code/Magento/InventorySales/etc/di.xml index d55b91612995..0f46b825e2cc 100644 --- a/app/code/Magento/InventorySales/etc/di.xml +++ b/app/code/Magento/InventorySales/etc/di.xml @@ -13,13 +13,13 @@ + - +