문제

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.

도움이 되었습니까?

해결책

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.

다른 팁

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 .

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;
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 magento.stackexchange
scroll top