Skip to content

Commit

Permalink
LYNX-486: not_available_message and only_x_left_in_stock doesn't show…
Browse files Browse the repository at this point in the history
… the same available stock (#279)
  • Loading branch information
deepak-soni1 authored Aug 26, 2024
1 parent 817ba4a commit 2a406ec
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
if ((int) $this->scopeConfig->getValue('cataloginventory/options/not_available_message') === 1) {
return sprintf(
'Only %s available for sale. Please adjust the quantity to continue',
(string) $this->productStock->getProductAvailableStock($cartItem)
(string) $this->productStock->getProductSaleableQty($cartItem)
);
}

Expand Down
77 changes: 74 additions & 3 deletions app/code/Magento/QuoteGraphQl/Model/CartItem/ProductStock.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
namespace Magento\QuoteGraphQl\Model\CartItem;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\CatalogInventory\Model\StockState;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\CatalogInventory\Model\Configuration;
use Magento\CatalogInventory\Model\StockState;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Model\Quote\Item;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\Store\Model\ScopeInterface;

/**
* Product Stock class to check availability of product
Expand All @@ -35,11 +39,15 @@ class ProductStock
* @param ProductRepositoryInterface $productRepositoryInterface
* @param StockState $stockState
* @param StockConfigurationInterface $stockConfiguration
* @param ScopeConfigInterface $scopeConfig
* @param StockRegistryInterface $stockRegistry
*/
public function __construct(
private readonly ProductRepositoryInterface $productRepositoryInterface,
private readonly StockState $stockState,
private readonly StockConfigurationInterface $stockConfiguration
private readonly StockConfigurationInterface $stockConfiguration,
private readonly ScopeConfigInterface $scopeConfig,
private readonly StockRegistryInterface $stockRegistry
) {
}

Expand Down Expand Up @@ -74,6 +82,7 @@ public function isProductAvailable(Item $cartItem): bool
* @param int $previousQty
* @param int|float $requestedQty
* @return bool
* @throws NoSuchEntityException
*/
public function isStockAvailableBundle(Item $cartItem, int $previousQty, $requestedQty): bool
{
Expand Down Expand Up @@ -188,4 +197,66 @@ private function getLowestStockValueOfBundleProduct(Item $cartItem): float

return min($bundleStock);
}

/**
* Returns the lowest stock value of bundle product
*
* @param Item $cartItem
* @param float $thresholdQty
* @return float
*/
private function getLowestSaleableQtyOfBundleProduct(Item $cartItem, float $thresholdQty): float
{
$bundleStock = [];
foreach ($cartItem->getQtyOptions() as $qtyOption) {
$bundleStock[] = $this->getSaleableQty($qtyOption->getProduct(), $thresholdQty);
}
return $bundleStock ? (float)min($bundleStock) : 0.0;
}

/**
* Returns the cart item's saleable qty value
*
* @param Item $cartItem
* @return float
* @throws NoSuchEntityException
*/
public function getProductSaleableQty(Item $cartItem): float
{
$thresholdQty = (float)$this->scopeConfig->getValue(
Configuration::XML_PATH_STOCK_THRESHOLD_QTY,
ScopeInterface::SCOPE_STORE
);

if ($thresholdQty === 0.0) {
return $this->getProductAvailableStock($cartItem);
}

if ($cartItem->getProductType() === self::PRODUCT_TYPE_BUNDLE) {
return $this->getLowestSaleableQtyOfBundleProduct($cartItem, $thresholdQty);
}

$variantProduct = $this->getVariantProduct($cartItem);
if ($variantProduct !== null) {
return $this->getSaleableQty($variantProduct, $thresholdQty);
}

return $this->getSaleableQty($cartItem->getProduct(), $thresholdQty);
}

/**
* Get product saleable qty when "Catalog > Inventory > Stock Options > Only X left Threshold" is greater than 0
*
* @param ProductInterface $product
* @param float $thresholdQty
* @return float
*/
private function getSaleableQty(ProductInterface $product, float $thresholdQty): float
{
$stockItem = $this->stockRegistry->getStockItem($product->getId());
$stockStatus = $this->stockRegistry->getStockStatus($product->getId(), $product->getStore()->getWebsiteId());
$stockCurrentQty = $stockStatus->getQty();
$stockLeft = $stockCurrentQty - $stockItem->getMinQty();
return ($stockCurrentQty >= 0 && $stockLeft <= $thresholdQty) ? (float)$stockCurrentQty : 0.0;
}
}
Loading

0 comments on commit 2a406ec

Please sign in to comment.