5

We are currently showing our available qty in stock on the frontend of each product using the following code:

<?php 
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
    $qty = $StockState->getStockQty($_product->getId());
?>

But when we enable the new MSI feature in Magento 2 the above code always outputs 0. How are we able to show the total salable qty in the frontend of all inventory sources?

Edit:

I found out that when I enable the Default source and assign it to a product and give it for example 10pcs. The above code outputs 10, so the above code doesnt take all the inventory sources into count. It should show the total salable qty like its showing in the backend.

Edit 2:

Explanation with images.

Default source enabled

With the above settings the above code outputs 10. It should output 25.

Default source disabled

When Default Source is unassigned the above code outputs 0. It should output 15.

4
  • Let us know in which file you want to show status ? Commented Mar 26, 2019 at 13:04
  • In app/design/frontend/Theme/default/Magento_Catalog/templates/product/view/type/default.phtml
    – JudgeB
    Commented Mar 26, 2019 at 13:20
  • you want to show qty or only status ?? Commented Mar 26, 2019 at 13:31
  • I want to show qty in stock
    – JudgeB
    Commented Mar 26, 2019 at 13:33

5 Answers 5

13

The definition of salable quantity includes the quantity minQty.

Nowadays MSI is the approach. So no other methods, shortcuts, objectmanagers or M1 flashback code. It all has to be an MSI approach that will be compatible with future versions of M2.

So, let's get into it:

    $websiteCode = $this->storeManager->getWebsite()->getCode();
    $stock = $this->stockResolver->execute(SalesChannelInterface::TYPE_WEBSITE, $websiteCode);
    $stockId = $stock->getStockId();

This gets your stock id for your website. It might always be the same but you have to look it up.

If on the frontend you want to show a different message for an item on backorder then you can do this:

        $stockItem = $this->getStockItemConfiguration->execute($product->getSku(), $stockId);
        $minQty = $stockItem->getMinQty();

        $salableQty = $this->productSalableQty->execute($product->getSku(), $stockId);

To determine if the product is in stock and on sale:

        $product->isSalable()

If you want to show what is low stock then you can get this from:

    $lowStock = $this->scopeConfig->getValue(self::XML_PATH_STOCK_THRESHOLD_QTY, ScopeInterface::SCOPE_STORE);

Combining these values to show stock availability:

        if (($salableQty + $minQty) > $lowStock) {

This shows what is readily available with no wait on backorders and no low stock.

If you want to know what is in stock including low stock, change the above to:

        if (($salableQty + $minQty) > 0) {

To setup your class use the interfaces:

use Magento\InventoryConfigurationApi\Api\GetStockItemConfigurationInterface;
use Magento\InventorySalesApi\Api\GetProductSalableQtyInterface;
use Magento\InventorySalesApi\Api\StockResolverInterface;
use Magento\Store\Model\StoreManagerInterface;

Then, for your constructor:

const XML_PATH_STOCK_THRESHOLD_QTY = 'cataloginventory/options/stock_threshold_qty';

private $getStockItemConfiguration;
private $productSalableQty;
private $stockResolver;
private $storeManager;

public function __construct(
    . . .
    GetProductSalableQtyInterface $productSalableQty,
    GetStockItemConfigurationInterface $getStockItemConfiguration,
    StockResolverInterface $stockResolver,
    StoreManagerInterface $storeManager,
    . . .
) {
    $this->getStockItemConfiguration = $getStockItemConfiguration;
    $this->productSalableQty = $productSalableQty;
    $this->stockResolver = $stockResolver;
    $this->storeManager = $storeManager;
    . . .
}
2
  • Where can you find the $stockItem->getMinQty(); in the admin panel? Or how can you configure it? Commented Jul 15, 2020 at 8:44
  • 1) Thanks, 2) M2 DI sucks, just for this the headers of my class ended up with the triple of the size Commented Dec 10, 2021 at 22:02
4

I found my own solution in the following piece of code:

<?php 
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $StockState = $objectManager->get('\Magento\InventorySalesApi\Api\GetProductSalableQtyInterface');
    $qty = $StockState->execute($_product->getSku(), 2);
?>

I hope it can be of help for others! :)

2 = $stockId

1
  • 2
    How to get the stock id?
    – Ramya
    Commented Dec 13, 2019 at 7:18
3

Try this. A complete solution based on the other answers

use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;

$productSalable = $objectManager->get('\Magento\InventorySalesApi\Api\GetProductSalableQtyInterface');
$stockResolver = $objectManager->get('\Magento\InventorySalesApi\Api\StockResolverInterface');

$stockId    = $stockResolver->execute(SalesChannelInterface::TYPE_WEBSITE, $website_code)->getStockId();
$stockQty   = $productSalable->execute($product_sku, $stockId);

$website_code = code of the website from all store. $product_sku = the sku of the product. Result($stockQty) will be the qty of the product of specific stock and not the default stock value

1
2

All the CatalogInventory interfaces including StockStateInterface are deprecated since Magento 2.3.1 You can see that in Magento source code, also they would be highlighted as deprecated if you are using PHP IDE for development. https://github.com/magento/magento2/blob/2.3-develop/app/code/Magento/CatalogInventory/Api/StockStateInterface.php#L13-L15

Since Magento 2.3 the proper way of getting salable quantity is next:

         /** @var \Magento\InventorySalesApi\Api\StockResolverInterface */
        $stockId = $this->stockResolver->execute(SalesChannelInterface::TYPE_WEBSITE, $websiteCode)->getStockId();
        /** @var \Magento\InventorySalesApi\Api\GetProductSalableQtyInterface */
        $qty = (int)$this->getProductSalableQty->execute($sku, $stockId);
0

Try this

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$StockState = $objectManager->get('\Magento\InventorySalesAdminUi\Model\GetSalableQuantityDataBySku');
$qty = $StockState->execute($_product->getSku());
print_r($qty)

Result should be

Array ( [0] => Array ( [stock_name] => other [qty] => 980 [manage_stock] => 1 ) ) 
2
  • So you are using 'object manager' and an 'admin ui' class to get stock data for the frontend. What is wrong with the API methods? Commented Feb 12, 2020 at 15:55
  • You can use proper standard instead of '$object manager'. This is one way to get the list of stocks with stock names (warehouse). With API methods, I tried, I could not get list of available Qty with the warehouse. But we can get salable Qty. Commented Feb 14, 2020 at 4:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.