2

I have a configurable products with few sizes, let's say : 123, 160, M, S, L, XL

When I put products M and S on qty 0, which means it is out of stock, then sizes disappear form the swatches option.

I was expected to see also out of stock products with a special class and to be non clickable, but out of stock products disappear.

I found a solution and I will post my answer. Maybe that will help someone.

4

3 Answers 3

5

To solve this issue:

Step 1

I installed this module( for some other versions of magento maybe this will work without step 2)

https://github.com/mjankiewicz/MagentoConfigurableProduct

Step 2

Create a module with:

etc/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\Swatches\Block\Product\Renderer\Configurable" type="Vendor\Namespace\Block\Outstock" />
</config>

then create Block/Outstock.php

<?php 

namespace vendor\namespace\Block;

class Outstock extends \Magento\Swatches\Block\Product\Renderer\Configurable
{

   public function getAllowProducts()
    {
        if (!$this->hasAllowProducts()){
             $skipSaleableCheck = 1;
             $products = $skipSaleableCheck ?
             $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null) :
                $this->getProduct()->getTypeInstance()->getSalableUsedProducts($this->getProduct(), null);
            $this->setAllowProducts($products);
        }
        return $this->getData('allow_products');
    }
}

After this run

php bin/magento setup:upgrade 

php bin/magento cache:clean

php bin/magento cache:flush

Of course that you can combine those 2 modules. You can take /Helper/Data.php form the first module JanSoft_ConfigurableProduct and put this into the second module, or the oposite.

15
  • Thanks it working, but how can i disable the option that is out of stock?
    – Waqar
    Commented Oct 3, 2017 at 10:06
  • i am not sure that i undestand your question Commented Oct 3, 2017 at 10:11
  • 1
    be sure that your block form step 2 is override Commented Oct 6, 2017 at 12:49
  • 1
    @AlinLupoiu sorry for such a late reply. If I'm going to combine the modules, how do I combine the etc/di.xml files ? Currently file structure is: app/code/JanSoft/CongurableProduct/ ...etc/di.xml (containing original jansoft code) ...Helper/data.php (containing original jansoft code) ...Block/outstock.php (containing your code) with this option, should I change Vendor\Namespacer to JanSoft\ConfigurableProduct in your code that you posted for di.xml and Block/Outstock.php?
    – Jason
    Commented Dec 21, 2017 at 19:18
  • 3
    is this still working this url github.com/mjankiewicz/MagentoConfigurableProduct doesn't work anyone help Commented Jun 19, 2019 at 9:55
1

You can also override the plugin to display the swatches as well as dropdown option if product is out of stock.

1)etc/di/xml.

<type name="Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Attribute\InStockOptionSelectBuilder">
        <plugin name="Magento_ConfigurableProduct_Plugin_Model_ResourceModel_InStockOptionSelectBuilder"
                type="Vendor\Mymodule\Plugin\Attribute\InStockOptionSelector"/>
    </type>

2)Plugin\Attribute

namespace Vendor\Mymodule\Plugin\Attribute;

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

class InStockOptionSelector extends \Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Attribute\InStockOptionSelectBuilder
{
    private $stockStatusResource;

    public function __construct(Status $stockStatusResource)
    {
        parent::__construct($stockStatusResource);
    }

    /**
     * @param OptionSelectBuilderInterface $subject
     * @param Select $select
     * @return Select
     */
    public function afterGetSelect(OptionSelectBuilderInterface $subject, Select $select)
    {

        return $select;
    }
}

3) override block in di.xml

<preference for="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable" type="Vendor\Mymodule\Block\Product\View\Type\Configurable"/>

4)Configurable.php

namespace Vendor\Mymodule\Block\Product\View\Type;

use Magento\ConfigurableProduct\Model\ConfigurableAttributeData;
use Magento\Customer\Helper\Session\CurrentCustomer;
use Magento\Customer\Model\Session;
use Magento\Framework\Locale\Format;
use Magento\Framework\Pricing\PriceCurrencyInterface;

class Configurable extends \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable
{
    public function __construct(\Magento\Catalog\Block\Product\Context $context, \Magento\Framework\Stdlib\ArrayUtils $arrayUtils, \Magento\Framework\Json\EncoderInterface $jsonEncoder, \Magento\ConfigurableProduct\Helper\Data $helper, \Magento\Catalog\Helper\Product $catalogProduct, CurrentCustomer $currentCustomer, PriceCurrencyInterface $priceCurrency, ConfigurableAttributeData $configurableAttributeData, array $data = [], $localeFormat = null, $customerSession = null)
    {
        parent::__construct($context, $arrayUtils, $jsonEncoder, $helper, $catalogProduct, $currentCustomer, $priceCurrency, $configurableAttributeData, $data, $localeFormat, $customerSession);
    }

    public function getAllowProducts()
    {
        if (!$this->hasAllowProducts()) {
            $products = [];
            $skipSaleableCheck = $this->catalogProduct->getSkipSaleableCheck();
            $allProducts = $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null);
            foreach ($allProducts as $product) {
                if ($product->isSaleable() || $skipSaleableCheck == 1) {
                    $products[] = $product;
                }
            }
            $this->setAllowProducts($products);
        }
        return $this->getData('allow_products');
    }

}

Hope so it will help .

0

Add into di.xml

 <type name="Magento\ConfigurableProduct\Model\Product\Type\Configurable">
        <plugin name="Vendor_Module::disable-stock-filter" type="Vendor\Module\Plugins\ConfigurableProduct\Model\Product\Type\Configurable"/>
 </type>

create file Configurable.php

namespace Vendor\Module\Plugins\ConfigurableProduct\Model\Product\Type;

use Magento\ConfigurableProduct\Model\Product\Type\Configurable as NativeConfigurable;
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection;

class Configurable
{ 
    public function afterGetUsedProductCollection(NativeConfigurable $subject, $collection)
    {
        $collection->setFlag('has_stock_status_filter', true);

        return $collection;
    }
}

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.