35

How to get stock quantity of each product in list.phtml in Magento 2 ?

1

7 Answers 7

63

Solution:1

Create Helper file Stock.php in your module

<?php
namespace {VendorName}\{ModuleName}\Helper;

class Stock extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * @var Magento\CatalogInventory\Api\StockStateInterface
     */
    protected $stockState;

    /**
     * Output constructor.
     * @param \Magento\Framework\App\Helper\Context $context
     * @param \Magento\CatalogInventory\Api\StockStateInterface $stockState
     */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\CatalogInventory\Api\StockStateInterface $stockState
    ) {
        $this->stockState = $stockState;
        parent::__construct($context);
    }

    /**
     * Retrieve stock qty whether product
     *
     * @param int $productId
     * @param int $websiteId
     * @return float
     */
    public function getStockQty($productId, $websiteId = null)
    {
        return $this->stockState->getStockQty($productId, $websiteId);
    }
}

After add bellow code in your list.phtml file

$websiteId = 1;  // Current websiteId
$productId = 2; // $_product->getId()  Product Id
$_helperStock = $this->helper({VendorName}\{ModuleName}\Helper\Stock::class);
echo $_helperStock->getStockQty($productId, $websiteId);

Solution:2

Add bellow code in your list.phtml file

<?php 
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
    echo $StockState->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
?>

OR

<?php
   $stockItem = $product->getExtensionAttributes()->getStockItem();
   print_r($stockItem->getQty()); 
?>
13
  • 1
    For some reason, running this in a cron job always returns '0' Apr 18, 2016 at 15:26
  • 11
    Please use DI instead of ObjectManager directly! Jun 14, 2017 at 12:47
  • 7
    Never use code like this directly. Use constructor DI instead. Jun 19, 2017 at 7:30
  • 2
    @WackGet devdocs.magento.com/guides/v2.3/extension-dev-guide/… - "Magento prohibits the direct use of the ObjectManager in your code because it hides the real dependencies of a class. See usage rules." Standards are there for a reason, developers should respect that.
    – Tisch
    Aug 2, 2019 at 15:00
  • 3
    @Tisch There are plenty of cases where using ObjectManager directly is fine. Standalone scripts, product feeds, cron jobs, etc.; all fine. From your own link, Magento states: "In a global scope, like in fixtures of integration tests, you can use the object manager." Don't just blindy parrot stuff when the reality is far more nuanced.
    – WackGet
    Oct 18, 2019 at 17:28
26

Like some comments have mentioned, you want to use dependency injection. Do not use the object manager; in other words, do not do what any of the other responses state. The following technique can be applied anywhere. For Blocks, set the class to your class in layout XML, which extends the original, and inject the right information.

Inject the StockRegistryInterface interface where you need access:

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

/**
 * Constructor for DI.
 *
 * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
 */
public function __construct(
    \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
) {
    $this->stockRegistry = $stockRegistry;
}

/**
 * Get the product stock data and methods.
 *
 * @return \Magento\CatalogInventory\Api\StockRegistryInterface
 */
public function getStockRegistry()
{
    return $this->stockRegistry;
}

To use it somewhere:

/** @var \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry */
$stockRegistry = [$this|$block]->getStockRegistry();

/** @var \Magento\Catalog\Model\Product $product */
$product = [Grab Product instance however you want. This is up to you.]

// Get stock data for given product.
$productStock = $stockRegistry->getStockItem($product->getId());

// Get quantity of product.
$productQty = $productStock->getQty();

For reference, Magento2 uses this exact interface all over the catalog when it comes to retrieving product stock information.

Note that anything within square brackets needs to be modified.

6
  • 4
    This should be marked as the correct answer. Although I haven't tested it (yet) it follows conventions. Aug 9, 2018 at 11:27
  • 3
    I've tested it, and this is the correct way to do this. using the object manager is a no-no.
    – circlesix
    Aug 30, 2018 at 15:16
  • 3
    Allways +1 for best practices!
    – Akif
    Jan 9, 2019 at 22:18
  • 2
    This should be the accepted answer as StockRegistryInterface works on every case, not the StockStateInterface. Jun 28, 2019 at 6:33
  • 1
    just a note that going forward StockRegistryInterface won't be a viable option as it is implementing \Magento\CatalogInventory\Api\StockStateInterface which is @deprecated 100.3.0 Replaced with Multi Source Inventory
    – Radu
    Feb 19, 2020 at 9:33
12

How to get stock quantity of each product in Magento 2

for controller or block inject \Magento\CatalogInventory\Api\StockStateInterface

 public function __construct(
    \Magento\CatalogInventory\Api\StockStateInterface $stockItem
   )
  {
    $this->stockItem = $stockItem;
  }

and then use getStockQty function to get qty

 $this->stockItem->getStockQty($product->getId(), $product->getStore()->getWebsiteId());

if you want to get quantity in .phtml file then use

 <?php 
 $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
 $StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
 echo $StockState->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
?>
2
  • returning qty 0 for me even though i have qty 30 Nov 16, 2018 at 10:30
  • @jafarpinjar found out today this also factors status - if disabled returns 0 - I can't decide if this is a good thing or not... Jul 7, 2019 at 0:11
7

The below script will be helpful to get the product stock qty, min qty and stock details in magento2.

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productStockObj = $objectManager->get('Magento\CatalogInventory\Api\StockRegistryInterface')->getStockItem($productId);
print_r($productStockObj->getData());
3

If you want to $productobj after saving product from backend side so you can easily use catalog_product_save_after event.

I am assuming that you already know how to create a module in M2.

Right now you have to need develop new module for M2

Then Create this events.xml file in below path

app\code\YOUR_NAMESPACE\YOURMODULE\etc\adminhtml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_save_after">
        <observer name="test_name" instance="YOUR_NAMESPACE\YOUR_MODULENAME\Observer\Productsaveafter" />
    </event>
</config>

And Create your observer file Productsaveafter.php in below path

app\code\YOUR_NAMESPACE\YOURMODULE\Observer\

<?php

namespace YOURNAMESPACE\YOURMODULENAME\Observer;

use Magento\Framework\Event\ObserverInterface;

class Productsaveafter implements ObserverInterface
{    
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $product = $observer->getEvent()->getProduct();
        $id = $product->getId(); //Get Product Id

        //Get Quantity
        $stockItem = $product->getExtensionAttributes()->getStockItem();
        $stockData = $stockItem->getQty();
        // Get new Qty
        $_vendor_qty = $product->getVendorQty();
        $_on_hand_qty = $product->getOnHandQty();
        $totalQty = $_vendor_qty+$_on_hand_qty; //Add New Qty


        $stockItem->setQty($totalQty); //Set New Qty to Main Qty
        $stockItem->save();

    }   
}
1

If you have the product object and do not want to use the other classes, You can try in the following way.

// For phtml file
$prodObj = $_product->load($_product->getId()); // $_product object in list.phtml
$stockItem = $prodObj->getExtensionAttributes()->getStockItem();
$stockQty = $stockItem->getQty(); // $stockItemData = $stockItem->getData();

// For php class file
$stockItem = $prodObj->getExtensionAttributes()->getStockItem();
$stockQty = $stockItem->getQty(); // $stockItemData = $stockItem->getData();
1

Registry and \Magento\CatalogInventory\Api\ classes are deprecated. So you can use helper class in Magento\Catelog

 <?php


namespace Package\ModuleName\Block;


use Magento\Catalog\Helper\Data;
use Magento\Framework\View\Element\Template;


class StockLeft extends Template
{

    /**
     * @var \Magento\Catalog\Helper\Data
     */
    private Data $helper;
    /**
     * @var \Magento\CatalogInventory\Model\Stock\StockItemRepository
     */
    private \Magento\CatalogInventory\Model\Stock\StockItemRepository $stockItemRepository;


    public function __construct(
        Template\Context $context,
        array $data=[],
        Data $helper,
        \Magento\CatalogInventory\Model\Stock\StockItemRepository $stockItemRepository
    ) {
        $this->helper = $helper;
        $this->stockItemRepository = $stockItemRepository;
        parent::__construct($context, $data);

    }//end __construct()


    public function getRemaining()
    {
        return $this->stockItemRepository->get($this->helper->getProduct()->getId())->getQty();

    }//end getRemaining()


}//end class

To get salable Qty you can use \Magento\InventorySalesAdminUi\Model\GetSalableQuantityDataBySku

public function __construct(
        Template\Context $context,
        array $data=[],
        Data $helper,
        \Magento\InventorySalesAdminUi\Model\GetSalableQuantityDataBySku $getSalableQuantityDataBySku
    ) {
        $this->helper              = $helper;
        $this->getSalableQuantityDataBySku = $getSalableQuantityDataBySku;
        parent::__construct($context, $data);

    }//end __construct()


    public function getRemaining()
    {
        $salableQty = $this->getSalableQuantityDataBySku->execute($this->helper->getProduct()->getSku());
        return $salableQty[0]['qty'];

    }//end getRemaining()

Your Answer

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

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