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

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!

  • hi @Deeps, this doesn't work for me, child out of stock item still not shown – jafar pinjar Nov 29 '18 at 9:58

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.