How to display configurable product swatches when product is Out of stock
-
14-04-2021 - |
문제
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;
}
}