5

I'm facing issue that configurable products showing out of stock associated products even if the backend setting "Display Out of Stock Products" at Configuration->Catalog->Inventory->Stock Options is set to "No".

Does anyone knows the fix for this?

1 Answer 1

1

I've fixed this issue by overriding the below file in our custom module: \Magento\ConfigurableProduct\Helper\Data.php

Below are the complete steps:

1) Add below statement in your module's di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="\Magento\ConfigurableProduct\Helper\Data" type="YOUR_COMPANY\MODULE_NAME\Helper\ConfigurableProduct\Data" />
</config>

2) Create a file Data.php at YOUR_COMPANY\MODULE_NAME\Helper\ConfigurableProduct and put below code in it

    <?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace YOUR_COMPANY\MODULE_NAME\Helper\ConfigurableProduct;

use Magento\Catalog\Model\Product;

/**
 * Class Data
 * Helper class for getting options
 *
 */
class Data extends \Magento\ConfigurableProduct\Helper\Data
{
    /**
     * Catalog Image Helper
     *
     * @var \Magento\Catalog\Helper\Image
     */
    protected $imageHelper;
    protected $_productloader;  
    protected $stockRegistry;  
    protected $_storeManager;

    /**
     * @param \Magento\Catalog\Helper\Image $imageHelper
     */
    public function __construct(
        \Magento\Catalog\Helper\Image $imageHelper,
        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
        \Magento\Catalog\Model\ProductFactory $_productloader,
        \Magento\Store\Model\StoreManagerInterface $storeManager        
        )
    {
        $this->imageHelper = $imageHelper;
        $this->stockRegistry = $stockRegistry;
        $this->_productloader = $_productloader;
        $this->_storeManager = $storeManager;
        parent::__construct($imageHelper);
    }

    /**
     * Get Options for Configurable Product Options
     *
     * @param \Magento\Catalog\Model\Product $currentProduct
     * @param array $allowedProducts
     * @return array
     */
    public function getOptions($currentProduct, $allowedProducts)
    {

        $options = [];
        foreach ($allowedProducts as $product) {
            $productId = $product->getId();

            $websiteId = $this->getCurrentWebsiteId();
            if ($websiteId == 2) {
                $product = $this->getLoadProduct($productId);
                $stockitem = $this->stockRegistry->getStockItem($product->getId(), $product->getStore()->getWebsiteId());
                if($stockitem->getQty() <= 0 || $stockitem->getIsInStock() != 1) continue;
            }

            $images = $this->getGalleryImages($product);
            if ($images) {
                foreach ($images as $image) {
                    $options['images'][$productId][] =
                        [
                            'thumb' => $image->getData('small_image_url'),
                            'img' => $image->getData('medium_image_url'),
                            'full' => $image->getData('large_image_url'),
                            'caption' => $image->getLabel(),
                            'position' => $image->getPosition(),
                            'isMain' => $image->getFile() == $product->getImage(),
                        ];
                }
            }
            foreach ($this->getAllowAttributes($currentProduct) as $attribute) {
                $productAttribute = $attribute->getProductAttribute();
                $productAttributeId = $productAttribute->getId();
                $attributeValue = $product->getData($productAttribute->getAttributeCode());

                $options[$productAttributeId][$attributeValue][] = $productId;
                $options['index'][$productId][$productAttributeId] = $attributeValue;
            }
        }
        return $options;
    }

    public function getLoadProduct($id)
    {
        return $this->_productloader->create()->load($id);
    }

    public function getCurrentWebsiteId(){
        return $this->_storeManager->getStore()->getWebsiteId();
    }


    }

I've added condition for website_id as I want to hide out of stock options for 2nd website only. You can remove that condition.

Flush the cache and check any configurable product having out of stock associated products in it.

Thanks!

3
  • hi @Deeps, this doesn't work for me, child out of stock item still not shown Commented Nov 29, 2018 at 9:58
  • Hi @Deeps, gave this a try on Magento 2.3.4 but it's not working. Any idea?
    – David
    Commented Mar 24, 2020 at 9:27
  • Hi again, it appears like these modifications are redundant in 2.3.4 as it was taken care of. But I noticed that the out of stock child items appear ONLY if AT LEAST one child item has stock.
    – David
    Commented Mar 24, 2020 at 12:09

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.