diff --git a/InventoryCatalogFrontendUi/Model/GetProductQtyLeft.php b/InventoryCatalogFrontendUi/Model/GetProductQtyLeft.php index 65c2c67ae20..0d436f43fda 100644 --- a/InventoryCatalogFrontendUi/Model/GetProductQtyLeft.php +++ b/InventoryCatalogFrontendUi/Model/GetProductQtyLeft.php @@ -7,6 +7,9 @@ namespace Magento\InventoryCatalogFrontendUi\Model; +use Magento\Framework\App\ObjectManager; +use Magento\InventoryConfigurationApi\Api\GetStockItemConfigurationInterface; +use Magento\InventoryConfigurationApi\Exception\SkuIsNotAssignedToStockException; use Magento\InventorySalesApi\Api\GetProductSalableQtyInterface; /** @@ -14,26 +17,28 @@ */ class GetProductQtyLeft { - /** - * @var IsSalableQtyAvailableForDisplaying - */ - private $qtyLeftChecker; + private GetProductSalableQtyInterface $getProductSalableQty; - /** - * @var GetProductSalableQtyInterface - */ - private $getProductSalableQty; + private IsSalableQtyThresholdReached $isSalableQtyThresholdReached; + + private GetStockItemConfigurationInterface $getStockItemConfig; /** - * @param IsSalableQtyAvailableForDisplaying $qtyLeftChecker + * @param IsSalableQtyAvailableForDisplaying $qtyLeftChecker [Deprecated] * @param GetProductSalableQtyInterface $getProductSalableQty + * @param IsSalableQtyThresholdReached|null $isSalableQtyThresholdReached + * @param GetStockItemConfigurationInterface|null $getStockItemConfig */ public function __construct( IsSalableQtyAvailableForDisplaying $qtyLeftChecker, - GetProductSalableQtyInterface $getProductSalableQty + GetProductSalableQtyInterface $getProductSalableQty, + ?IsSalableQtyThresholdReached $isSalableQtyThresholdReached = null, + ?GetStockItemConfigurationInterface $getStockItemConfig = null ) { - $this->qtyLeftChecker = $qtyLeftChecker; $this->getProductSalableQty = $getProductSalableQty; + $this->isSalableQtyThresholdReached = $isSalableQtyThresholdReached + ?? ObjectManager::getInstance()->get(IsSalableQtyThresholdReached::class); + $this->getStockItemConfig = $getStockItemConfig ?? ObjectManager::getInstance()->get(GetStockItemConfigurationInterface::class); } /** @@ -42,14 +47,15 @@ public function __construct( * @param string $productSku * @param int $stockId * @return float + * @throws SkuIsNotAssignedToStockException */ public function execute(string $productSku, int $stockId): float { $productSalableQty = $this->getProductSalableQty->execute($productSku, $stockId); - if ($this->qtyLeftChecker->execute((float)$productSalableQty)) { - return $productSalableQty; - } + $stockItemConfig = $this->getStockItemConfig->execute($productSku, $stockId); - return 0.0; + return $this->isSalableQtyThresholdReached->execute($productSalableQty, $stockItemConfig) + ? $productSalableQty + : 0; } } diff --git a/InventoryCatalogFrontendUi/Model/IsSalableQtyAvailableForDisplaying.php b/InventoryCatalogFrontendUi/Model/IsSalableQtyAvailableForDisplaying.php index d7fb2696a89..17f9f99a81f 100644 --- a/InventoryCatalogFrontendUi/Model/IsSalableQtyAvailableForDisplaying.php +++ b/InventoryCatalogFrontendUi/Model/IsSalableQtyAvailableForDisplaying.php @@ -11,6 +11,8 @@ /** * Check if it is necessary to show qty left. + * + * @deprecated */ class IsSalableQtyAvailableForDisplaying { @@ -37,9 +39,9 @@ public function __construct( public function execute(float $productSalableQty): bool { return ($this->stockItemConfig->getBackorders() === StockItemConfigurationInterface::BACKORDERS_NO - || $this->stockItemConfig->getBackorders() !== StockItemConfigurationInterface::BACKORDERS_NO - && $this->stockItemConfig->getMinQty() < 0) - && $productSalableQty <= (float) $this->stockItemConfig->getStockThresholdQty() + || ($this->stockItemConfig->getBackorders() !== StockItemConfigurationInterface::BACKORDERS_NO + && $this->stockItemConfig->getMinQty() < 0)) + && $productSalableQty <= $this->stockItemConfig->getStockThresholdQty() && $productSalableQty > 0; } } diff --git a/InventoryCatalogFrontendUi/Model/IsSalableQtyThresholdReached.php b/InventoryCatalogFrontendUi/Model/IsSalableQtyThresholdReached.php new file mode 100644 index 00000000000..84559217722 --- /dev/null +++ b/InventoryCatalogFrontendUi/Model/IsSalableQtyThresholdReached.php @@ -0,0 +1,24 @@ +getBackorders() === StockItemConfigurationInterface::BACKORDERS_NO + || ( + $stockItemConfig->getBackorders() !== StockItemConfigurationInterface::BACKORDERS_NO + && $stockItemConfig->getMinQty() < 0 + ) + ) && $productSalableQty > 0 && $productSalableQty <= $stockItemConfig->getStockThresholdQty(); + } +} diff --git a/InventorySalesFrontendUi/Plugin/Block/Stockqty/AbstractStockqtyPlugin.php b/InventorySalesFrontendUi/Plugin/Block/Stockqty/AbstractStockqtyPlugin.php index d2246d97fa4..650d023c1a5 100644 --- a/InventorySalesFrontendUi/Plugin/Block/Stockqty/AbstractStockqtyPlugin.php +++ b/InventorySalesFrontendUi/Plugin/Block/Stockqty/AbstractStockqtyPlugin.php @@ -8,8 +8,11 @@ namespace Magento\InventorySalesFrontendUi\Plugin\Block\Stockqty; use Magento\CatalogInventory\Block\Stockqty\AbstractStockqty; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; +use Magento\InventoryCatalogFrontendUi\Model\IsSalableQtyThresholdReached; use Magento\InventoryConfigurationApi\Api\GetStockItemConfigurationInterface; +use Magento\InventoryConfigurationApi\Exception\SkuIsNotAssignedToStockException; use Magento\InventoryConfigurationApi\Model\IsSourceItemManagementAllowedForProductTypeInterface; use Magento\InventorySalesApi\Api\GetProductSalableQtyInterface; use Magento\InventorySalesApi\Model\StockByWebsiteIdResolverInterface; @@ -20,30 +23,15 @@ */ class AbstractStockqtyPlugin { - /** - * @var GetStockItemConfigurationInterface - */ - private $getStockItemConfiguration; + private GetStockItemConfigurationInterface $getStockItemConfiguration; - /** - * @var StockByWebsiteIdResolverInterface - */ - private $stockByWebsiteId; + private StockByWebsiteIdResolverInterface $stockByWebsiteId; - /** - * @var GetProductSalableQtyInterface - */ - private $getProductSalableQty; + private GetProductSalableQtyInterface $getProductSalableQty; - /** - * @var IsSourceItemManagementAllowedForProductTypeInterface - */ - private $isSourceItemManagementAllowedForProductType; + private IsSourceItemManagementAllowedForProductTypeInterface $isSourceItemManagementAllowedForProductType; - /** - * @var IsSalableQtyAvailableForDisplaying - */ - private $qtyLeftChecker; + private IsSalableQtyThresholdReached $qtyLeftChecker; /** * @param StockByWebsiteIdResolverInterface $stockByWebsiteId @@ -51,19 +39,22 @@ class AbstractStockqtyPlugin * @param GetProductSalableQtyInterface $getProductSalableQty * @param IsSourceItemManagementAllowedForProductTypeInterface $isSourceItemManagementAllowedForProductType * @param IsSalableQtyAvailableForDisplaying $qtyLeftChecker + * @param IsSalableQtyThresholdReached|null $isSalableQtyThresholdReached */ public function __construct( StockByWebsiteIdResolverInterface $stockByWebsiteId, GetStockItemConfigurationInterface $getStockItemConfig, GetProductSalableQtyInterface $getProductSalableQty, IsSourceItemManagementAllowedForProductTypeInterface $isSourceItemManagementAllowedForProductType, - IsSalableQtyAvailableForDisplaying $qtyLeftChecker + IsSalableQtyAvailableForDisplaying $qtyLeftChecker, + ?IsSalableQtyThresholdReached $isSalableQtyThresholdReached = null ) { $this->getStockItemConfiguration = $getStockItemConfig; $this->stockByWebsiteId = $stockByWebsiteId; $this->getProductSalableQty = $getProductSalableQty; $this->isSourceItemManagementAllowedForProductType = $isSourceItemManagementAllowedForProductType; - $this->qtyLeftChecker = $qtyLeftChecker; + $this->qtyLeftChecker = $isSalableQtyThresholdReached + ?? ObjectManager::getInstance()->get(IsSalableQtyThresholdReached::class); } /** @@ -72,24 +63,25 @@ public function __construct( * @param AbstractStockqty $subject * @param callable $proceed * @return bool + * @throws SkuIsNotAssignedToStockException * @throws LocalizedException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundIsMsgVisible(AbstractStockqty $subject, callable $proceed): bool { - $productType = $subject->getProduct()->getTypeId(); - $sku = $subject->getProduct()->getSku(); - $websiteId = (int)$subject->getProduct()->getStore()->getWebsiteId(); - $stockId = (int)$this->stockByWebsiteId->execute($websiteId)->getStockId(); - $stockItemConfig = $this->getStockItemConfiguration->execute($sku, $stockId); - if (!$this->isSourceItemManagementAllowedForProductType->execute($productType) - || !$stockItemConfig->isManageStock() - ) { - return false; + $product = $subject->getProduct(); + if ($this->isSourceItemManagementAllowedForProductType->execute($product->getTypeId())) { + $sku = $product->getSku(); + $stockId = (int)$this->stockByWebsiteId->execute( + (int)$subject->getProduct()->getStore()->getWebsiteId() + )->getStockId(); + $stockItemConfig = $this->getStockItemConfiguration->execute($sku, $stockId); + + return $stockItemConfig->isManageStock() + && $this->qtyLeftChecker->execute($this->getProductSalableQty->execute($sku, $stockId), $stockItemConfig); } - $productSalableQty = $this->getProductSalableQty->execute($sku, $stockId); - return $this->qtyLeftChecker->execute($productSalableQty); + return false; } /** @@ -103,9 +95,11 @@ public function aroundIsMsgVisible(AbstractStockqty $subject, callable $proceed) */ public function aroundGetStockQtyLeft(AbstractStockqty $subject, callable $proceed): float { - $sku = $subject->getProduct()->getSku(); - $websiteId = (int)$subject->getProduct()->getStore()->getWebsiteId(); - $stockId = (int)$this->stockByWebsiteId->execute($websiteId)->getStockId(); - return $this->getProductSalableQty->execute($sku, $stockId); + $product = $subject->getProduct(); + + return $this->getProductSalableQty->execute( + $product->getSku(), + (int)$this->stockByWebsiteId->execute((int)$product->getStore()->getWebsiteId())->getStockId() + ); } }