1

I copied the extension from https://github.com/pkarsai/show-out-of-stock-products-magento2 whose code is

Myweb/ShowOutOfStockProducts/configurableProduct/Helper/Data/Data.php

<?php

namespace Myweb\ShowOutOfStockProducts\ConfigurableProduct\Helper\Data;

class Data extends \Magento\ConfigurableProduct\Helper\Data
{

    public function getOptions($currentProduct, $allowedProducts)
    {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $stockRegistry = $objectManager->get('Magento\CatalogInventory\Api\StockRegistryInterface');

        $options = [];
        $allowAttributes = $this->getAllowAttributes($currentProduct);

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

            $product = $objectManager->get('Magento\Catalog\Model\Product')->load($productId);
            $stockitem = $stockRegistry->getStockItem($product->getId(), $product->getStore()->getWebsiteId());
            if($stockitem->getQty() == 0) continue;

            foreach ($allowAttributes as $attribute) {
                $productAttribute = $attribute->getProductAttribute();
                $productAttributeId = $productAttribute->getId();
                $attributeValue = $product->getData($productAttribute->getAttributeCode());

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


}

Myweb/ShowOutOfStockProducts/etc/frontend/di.xml

<?xml version="1.0"?>
<!--
    /**
    * @author     Peter Karsai
    * @package    Myweb_ShowOutOfStockProducts
    * @copyright  Copyright (c) 2019 My Web Kft. (http://www.my-web.hu)
    */
-->
<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="Myweb\ShowOutOfStockProducts\ConfigurableProduct\Helper\Data\Data"/>

    <type name="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable">
        <plugin name="ShowOutOfStockProducts" type="Myweb\ShowOutOfStockProducts\Plugin\ShowOutOfStockProductsPlugin" />
    </type>

    <type name="Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilderInterface">
        <plugin name="Magento_ConfigurableProduct_Plugin_Model_ResourceModel_Attribute_InStockOptionSelectBuilder" disabled="true" />
        <plugin name="ShowAllProductSwatches" type="Myweb\ShowOutOfStockProducts\Plugin\InStockOptionSelectorPlugin"/>
    </type>
</config>

Myweb/ShowOutOfStockProducts/Plugin/InStockOptionSelectorPlugin.php

<?php

namespace Myweb\ShowOutOfStockProducts\Plugin;

use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Model\ResourceModel\Stock\Status;
use Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilderInterface;
use Magento\Framework\DB\Select;

class InStockOptionSelectorPlugin extends \Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Attribute\InStockOptionSelectBuilder
{
    /**
     * @var StockConfigurationInterface
     */
    private $stockConfiguration;
    /**
     * InStockOptionSelectBuilder constructor
     *
     * @param Status $stockStatusResource
     * @param StockConfigurationInterface $stockConfiguration
     */
    public function __construct(
        Status $stockStatusResource,
        StockConfigurationInterface $stockConfiguration
    ) {
        parent::__construct($stockStatusResource);
        $this->stockConfiguration = $stockConfiguration;
    }
    /**
     * Only Add In stock Filter if Show Out Of Stock Products is set to No
     *
     * @param OptionSelectBuilderInterface $subject
     * @param Select $select
     * @return Select
     */
    public function afterGetSelect(
        OptionSelectBuilderInterface $subject,
        Select $select
    ) {
        if (!$this->stockConfiguration->isShowOutOfStock()) {
            return parent::afterGetSelect($subject, $select);
        }
        return $select;
    }
}

Myweb/ShowOutOfStockProducts/Plugin/ShowOutOfStockProductsPlugin.php

<?php

namespace Myweb\ShowOutOfStockProducts\Plugin;

class ShowOutOfStockProductsPlugin {

    /**
     * Get Allowed Products
     *
     * @return \Magento\Catalog\Model\Product[]
     */
    public function beforeGetAllowProducts(\Magento\ConfigurableProduct\Block\Product\View\Type\Configurable $subject)
    {
        if (!$subject->hasAllowProducts()) {
            $allProducts = $subject->getProduct()->getTypeInstance()->getUsedProducts($subject->getProduct(), null);
            $products = [];
            foreach ($allProducts as $product) {
                if ($product->getStatus() != \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED) {
                    $products[] = $product;
                }
            }
            $subject->setAllowProducts($products);
        }
        return [];
    }

}

Now the output of the plugin is

enter image description here

now the colors which I Circled is out of stock and it is also showing but now I want when the user click on this product then it shows a message Out Of stock.. How is it possible??

1 Answer 1

0

Change at file

Myweb/ShowOutOfStockProducts/Plugin/ShowOutOfStockProductsPlugin.php

use getSalableUsedProducts instead getUsedProducts

    <?php

    namespace Myweb\ShowOutOfStockProducts\Plugin;

    class ShowOutOfStockProductsPlugin {

        /**
         * Get Allowed Products
         *
         * @return \Magento\Catalog\Model\Product[]
         */
        public function beforeGetAllowProducts(\Magento\ConfigurableProduct\Block\Product\View\Type\Configurable $subject)
        {
            if (!$subject->hasAllowProducts()) {
               // $allProducts = $subject->getProduct()->getTypeInstance()->getUsedProducts($subject->getProduct(), null);
$allProducts = $subject->getProduct()->getTypeInstance()->getSalableUsedProducts($subject->getProduct(), null);
                $products = [];
                foreach ($allProducts as $product) {
                    if ($product->getStatus() != \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED) {
                        $products[] = $product;
                    }
                }
                $subject->setAllowProducts($products);
            }
            return [];
        }

    }

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.