How to get stock quantity of each product in list.phtml in Magento 2 ?
7 Answers
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());
?>
-
1
-
11
-
7
-
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.– TischAug 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.– WackGetOct 18, 2019 at 17:28
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.
-
4This should be marked as the correct answer. Although I haven't tested it (yet) it follows conventions. Aug 9, 2018 at 11:27
-
3I've tested it, and this is the correct way to do this. using the object manager is a no-no. Aug 30, 2018 at 15:16
-
3
-
2This should be the accepted answer as StockRegistryInterface works on every case, not the StockStateInterface. Jun 28, 2019 at 6:33
-
1just 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– RaduFeb 19, 2020 at 9:33
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());
?>
-
-
@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
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());
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();
}
}
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();
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()