0

I have a block of type Magento\Catalog\Block\Product\View.

I would like to retrieve the current product's stock status.

The products in my eshop are both simple and configurables.

For configurables I guess I would need to know if all children are out of stock or the opposite, if at least one child is instock.

How should I approach this?

1

You might be looking for something this.

<?php 
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $Stock = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
    echo $Stock->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
?>
4
  • I think using the object manager directly is discouraged by Magento so I was hoping there was an alternative
    – gabtzi
    Jan 26 '20 at 12:55
  • yes, i keep reading that it is, and that we should create a block in a module then call the block in our template. But almost every time I try that, I get mired in error after error as you have to include ALL the right classes and use just the right constructor and it can be quite a nightmare to trace through the whole tree chasing the missing one. But yes, now that you know where to look just put that code in a Block. Or as it is an API there ought to be a way to call it direct?
    – iphigenie
    Jan 26 '20 at 21:38
  • @iphigenie I totally get what you mean. Everything in Magento 2 requires so much effort but I'm hoping there's a reason behind this magento suggestion to avoid using the object manager directly. I too am considering that my only choice might be creating a block for this :( I wonder if we could get a response about the recommended way to achieve this task too before I go on with one of either choices
    – gabtzi
    Jan 27 '20 at 5:16
  • might be worth accepting this answer if it works then asking a new question which will be "how do I do this without objectmanager ;)
    – iphigenie
    Jan 28 '20 at 18:14
1

If you are on a product page then

if ($_product->isSaleable())

or

if ($_product->isAvailable())

should do the job

If you are handling the product collection in your block code, I would look into adding

\Magento\CatalogInventory\Helper\Stock $stockHelper

$stockHelper->AddIsInStockFieldToCollection($productCollection)

for 2.3.3

or

$stockHelper->addStockStatusToProducts($productCollection);

for 2.3.2 and prior

I think both can be accessed via the Stock helper, but I am currently struggling with the context of this on 2.3.3 (where stockhelper no longer is a file but a bunch of migrated classes, plugins, overrides) but in your scenario it should work? And no, you don't need to fetch the children stock status, the parent is properly returned based on children.

MORE DETAILED STOCK

2.3.3 deprecated all the stockHelper ways of doing things, though they still exist. I have been trying to figure out the "correct" new way to do things and I will be honest, I am still fumbling around.

The solution currently in my "show child product stock" uses Object Manager because every time I tried the more correct approaches I get errors

But I will share the different approaches I have seen that get to the StockItem data for a product, maybe that will help you - I haven't tested these much because my current problem needs the "per warehouse" details.

stockItemFactory

\Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory, \Magento\CatalogInventory\Model\Source\Stock $sourceStock,

$stockItem   = $this->stockItemFactory->create()->load($object->getId(), 'product_id');
$stockItem->getIsInStock()

StockRegistry

\Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,

$this->stockRegistry = $stockRegistry;
$stockItem = $this->stockRegistry->getStockItem($productId, $product->getStore()->getWebsiteId());
$stockItem->getManageStock():
$stockItem->getQty();
$stockItem->getIsInStock();
$stockItem->getBackorders();

Product extension \Magento\Catalog\Api\Data\ProductInterface\ProductExtension\ProductExtensionInterface Magento\Catalog\Api\Data\ProductExtension

$extendedAttributes = $product->getExtensionAttributes();
$stockItem = $extendedAttributes->getStockItem();
$stockItem->getManageStock(); 
$stockItem->getQty();
$stockItem->getIsInStock();
$stockItem->getBackorders();
7
  • Unfortunately this is for adding some info required in like 5 core templates based on stock status. So this will happen in product view page mostly and I don't have a collection here. I was trying to avoid having to create blocks for each one of them.
    – gabtzi
    Jan 27 '20 at 10:17
  • If status is all you need then you should be able to use isSaleable as a condition. Works on every type
    – iphigenie
    Jan 27 '20 at 10:36
  • I'm not sure isSaleable works if the product is out of stock but backorders enabled.
    – gabtzi
    Jan 27 '20 at 10:49
  • isSaleable / isSalable is mostly used to decide whether to show price or not, so yes, it shows if product is backorderable.
    – iphigenie
    Jan 27 '20 at 11:11
  • My problem is if a product is orderable yet not in stock. In these cases I need to perform various tasks such as present estimated delivery date etc etc.
    – gabtzi
    Jan 27 '20 at 12:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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