5

Since magento 2.2.3 is displaying out of stock items in product listing, I would like to get the qty attribute in the listing using rest API. I'm using afterGetList plugin.

di.xml

<type name="Magento\Catalog\Api\ProductRepositoryInterface">
    <plugin name="get_product_metrics" type="Custom\Module\Plugin\ProductGet"/>
</type>

Custom/Module/etc/extension_attributes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
        <attribute code="qty" type="string"/>
    </extension_attributes>
</config>

ProductGet.php

 <?php

namespace Custom\Module\Plugin;

use Magento\Catalog\Api\Data\ProductInterface;

class ProductGet{
protected $productExtensionFactory;
protected $productFactory;

public function __construct(
    \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory,
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Magento\CatalogInventory\Api\StockStateInterface $stockItem,
    \Psr\Log\LoggerInterface $logger,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface $mediaGallery,
    \Magento\Eav\Model\Config $eavConfig
)
{
    $this->productFactory = $productFactory;
    $this->storeManager = $storeManager;
    $this->logger = $logger;
    $this->stockItem = $stockItem;
    $this->productExtensionFactory = $productExtensionFactory;
    $this->eavConfig = $eavConfig;
    $this->mediaGallery = $mediaGallery;
}

public function afterGet(
    \Magento\Catalog\Api\ProductRepositoryInterface $subject,
    \Magento\Catalog\Api\Data\ProductInterface $product){

    $this->logger->info("Inside AfterGet ");

    $imageUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);

    if($product->getImage()){
        $product->setCustomAttribute("image", $imageUrl.'catalog/product'.$product->getImage());
    }

    return $product;
}


/**
 * @param \Magento\Catalog\Api\ProductRepositoryInterface $subject
 * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $products
 * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
    public function afterGetList(
    \Magento\Catalog\Api\ProductRepositoryInterface $subject,
    $products
    )
    {
        $this->logger->info("list: ".json_encode($products->getItems()));
        /** @var  $product */
        foreach ($products->getItems() as $key => $product) {
            $qty = $this->stockItem->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
            $extensionattributes = $product->getExtensionAttributes();
            $extensionattributes->setQty($qty);
            $product->setExtensionAttributes($extensionattributes);
        }
        return $products;
    }
}

Can anyone help on this? Thanks in advance!

12
  • You want to assign custom qty value in foreach? Commented Oct 28, 2018 at 5:25
  • @RohanHapani No, I want to get the qty attribute for each product in a collection. I need this in product listing rest api Commented Oct 28, 2018 at 5:26
  • Can you please upload your full plugin code? Commented Oct 28, 2018 at 5:28
  • @RohanHapani I have edited the question please check. Commented Oct 28, 2018 at 5:32
  • Please check my answer and let me know. Commented Oct 28, 2018 at 6:15

3 Answers 3

3

you can add qty attribute using extension_attributes.xml. Here is the code for that

create extension_attributes.xml in etc/ folder of your module.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">

<extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
    <attribute code="qty" type="string"/>
</extension_attributes>

and add this code in your afterGetList()

public function afterGetList(
    \Magento\Catalog\Api\ProductRepositoryInterface $subject,
    $products
) {
    foreach ($products->getItems() as $key => $product) {
        $qty = $this->stockItem->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
        $extensionattributes = $product->getExtensionAttributes();
        $extensionattributes->setQty($qty);
        $product->setExtensionAttributes($extensionattributes);
    }
    return $products;
}

You can get more idea from here https://devdocs.magento.com/guides/v2.2/extension-dev-guide/extension_attributes/adding-attributes.html

Hope it will help you.

5
  • I tried this extension attributes also. I have compiled and upgrade. But it is throwing an exception Fatal Error: 'Uncaught Error: Call to undefined method Magento\\Catalog\\Api\\Data\\ProductExtension::setQty() in Commented Oct 28, 2018 at 8:10
  • remove generated folder and try again. because I have tested above code and I get qty in extension_attributes array Commented Oct 28, 2018 at 8:13
  • and if possible update your question with extension_attributes.xml file with its location. Commented Oct 28, 2018 at 8:16
  • I have updated the question. Please check. Also I have removed the folder, even the result is same Commented Oct 28, 2018 at 8:23
  • 1
    extension attribute class is wrong use this class Magento\Catalog\Api\Data\ProductInterface Commented Oct 28, 2018 at 8:24
2

Instead of using plugin, you can directly copy list.phtml from vendor/magento/module-catalog/view/frontend/templates/product/list.phtml

to

app/design/frontend/vendor/theme/Magento_Catalog/templates/product/list.phtml

and add following code

$_product->getExtensionAttributes()->getStockItem()->getQty();

I am using the same and its perfectly working fine.

4
  • Thanks for replying. But my application is mobile based and I need to use rest apis. I need qty where ever the products list/collection loads Commented Oct 28, 2018 at 6:26
  • Try, /V1/stockItems/:productSku . For more details, you can refer devdocs.magento.com/guides/v2.0/rest/list.html#cataloginventory Commented Oct 28, 2018 at 16:13
  • I know there is an api. I need the qty in the product listing. I cant loop all the products and call the stock api to get it. Anyways I got the solution. Thanks! for replying. Commented Oct 29, 2018 at 8:18
  • This isn't working for me in Magento 2.4, looks like the stock extension attribute is not their on the product Commented Aug 9, 2020 at 14:36
1

You can get each product's qty by using this below code :

foreach ($products->getItems() as $key => $product) {
    $stockItem = $product->getExtensionAttributes()->getStockItem();
    print_r($stockItem->getQty());
}

EDIT :

You can set it by this below code :

$product->setStockData(['qty' => $stockItem, 'is_in_stock' => (bool)$stockItem]);
$product->setQuantityAndStockStatus(['qty' => $stockItem, 'is_in_stock' => (bool)$stockItem]);
$product->save();

Hope, It will helpful for you.

4
  • I'm able to get the quantity in the loop. My question is how to set back to the collection so that products list rest api will show the qty Commented Oct 28, 2018 at 6:22
  • No. I didn't worked Commented Oct 28, 2018 at 6:47
  • Is there any error log or system log? Commented Oct 28, 2018 at 6:50
  • Actually when I run this, I got empty list in the rest api. When I see the admin console the quantity is showing as null. Again I have added the qty and list is displayed in rest api Commented Oct 28, 2018 at 7:03

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.