4

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!

  • You want to assign custom qty value in foreach? – Rohan Hapani Oct 28 '18 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 – Bhargava Rama Oct 28 '18 at 5:26
  • Can you please upload your full plugin code? – Rohan Hapani Oct 28 '18 at 5:28
  • @RohanHapani I have edited the question please check. – Bhargava Rama Oct 28 '18 at 5:32
  • Please check my answer and let me know. – Rohan Hapani Oct 28 '18 at 6:15
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.

  • 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 – Bhargava Rama Oct 28 '18 at 8:10
  • remove generated folder and try again. because I have tested above code and I get qty in extension_attributes array – Rakesh Varma Oct 28 '18 at 8:13
  • and if possible update your question with extension_attributes.xml file with its location. – Rakesh Varma Oct 28 '18 at 8:16
  • I have updated the question. Please check. Also I have removed the folder, even the result is same – Bhargava Rama Oct 28 '18 at 8:23
  • 1
    extension attribute class is wrong use this class Magento\Catalog\Api\Data\ProductInterface – Rakesh Varma Oct 28 '18 at 8:24
1

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.

  • 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 – Bhargava Rama Oct 28 '18 at 6:26
  • Try, /V1/stockItems/:productSku . For more details, you can refer devdocs.magento.com/guides/v2.0/rest/list.html#cataloginventory – Manish Bhojwani Oct 28 '18 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. – Bhargava Rama Oct 29 '18 at 8:18
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.

  • 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 – Bhargava Rama Oct 28 '18 at 6:22
  • No. I didn't worked – Bhargava Rama Oct 28 '18 at 6:47
  • Is there any error log or system log? – Rohan Hapani Oct 28 '18 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 – Bhargava Rama Oct 28 '18 at 7:03

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.