Magento 2.2 How to show out of stock in configurable product
app/code/Ravindra/Custom/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Ravindra_Custom" setup_version="2.2.2">
</module>
</config>
app/code/Ravindra/Custom/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Ravindra_Custom',
__DIR__
);
app/code/Ravindra/Custom/etc/di.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<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="Ravindra\Custom\Block\Product\View\Type\Configurable" />
<preference for="Magento\ConfigurableProduct\Model\ConfigurableAttributeData" type="Ravindra\Custom\Model\Rewrite\ConfigurableAttributeData" />
</config>
app/code/Ravindra/Custom/Block/Product/View/Type/Configurable.php
<?php
namespace Ravindra\Custom\Block\Product\View\Type;
use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Helper\Product as CatalogProduct;
use Magento\ConfigurableProduct\Helper\Data;
use Magento\ConfigurableProduct\Model\ConfigurableAttributeData;
use Magento\Customer\Helper\Session\CurrentCustomer;
use Magento\Framework\Json\EncoderInterface;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Catalog\Model\Product;
use Magento\Framework\Stdlib\ArrayUtils;
use Magento\Store\Model\ScopeInterface;
use Magento\Swatches\Helper\Data as SwatchData;
use Magento\Swatches\Helper\Media;
use Magento\Swatches\Model\Swatch;
class Configurable extends \Magento\Swatches\Block\Product\Renderer\Configurable
{
public function __construct(
Context $context,
ArrayUtils $arrayUtils,
EncoderInterface $jsonEncoder,
Data $helper,
CatalogProduct $catalogProduct,
CurrentCustomer $currentCustomer,
PriceCurrencyInterface $priceCurrency,
ConfigurableAttributeData $configurableAttributeData,
SwatchData $swatchHelper,
Media $swatchMediaHelper,
array $data = []
){
$this->swatchHelper = $swatchHelper;
$this->swatchMediaHelper = $swatchMediaHelper;
parent::__construct(
$context,
$arrayUtils,
$jsonEncoder,
$helper,
$catalogProduct,
$currentCustomer,
$priceCurrency,
$configurableAttributeData,
$swatchHelper,
$swatchMediaHelper,
$data
);
}
public function getJsonConfig() {
$store = $this->getCurrentStore();
$currentProduct = $this->getProduct();
$regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price');
$finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price');
$options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());
$attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);
$config = [
'attributes' => $attributesData['attributes'],
'template' => str_replace('%s', '<%- data.price %>', $store->getCurrentCurrency()->getOutputFormat()),
'optionPrices' => $this->getOptionPrices(),
'optionStock' => $this->getOptionStocks(),
'prices' => [
'oldPrice' => [
'amount' => $this->_registerJsPrice($regularPrice->getAmount()->getValue()),
],
'basePrice' => [
'amount' => $this->_registerJsPrice(
$finalPrice->getAmount()->getBaseAmount()
),
],
'finalPrice' => [
'amount' => $this->_registerJsPrice($finalPrice->getAmount()->getValue()),
],
],
'productId' => $currentProduct->getId(),
'chooseText' => __('Choose an Option...'),
'images' => isset($options['images']) ? $options['images'] : [],
'index' => isset($options['index']) ? $options['index'] : [],
];
if ($currentProduct->hasPreconfiguredValues() && !empty($attributesData['defaultValues'])) {
$config['defaultValues'] = $attributesData['defaultValues'];
}
$config = array_merge($config, $this->_getAdditionalConfig());
return $this->jsonEncoder->encode($config);
}
/*-----------------------custom code----------------------*/
protected function getOptionStocks() {
$stocks = [];
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$stockObject=$objectManager->get('Magento\CatalogInventory\Api\StockRegistryInterface');
foreach ($this->getAllowProducts() as $product) {
$productStockObj = $stockObject->getStockItem($product->getId());
$isInStock = $productStockObj['is_in_stock'];
$stocks[$product->getId()] = ['stockStatus' => $isInStock];
}
return $stocks;
}
}
app/code/Ravindra/Custom/Block/ConfigurableProduct.php
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Ravindra\Custom\Block;
use Magento\Framework\View\Element\Template;
class ConfigurableProduct extends Template
{
protected $_storeManager;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
array $data = []
){
parent::__construct($context, $data);
$this->_storeManager = $context->getStoreManager();
}
}
app/code/Ravindra/Custom/Model/Rewrite/ConfigurableAttributeData.php
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Ravindra\Custom\Model\Rewrite;
use Magento\Catalog\Model\Product;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute;
class ConfigurableAttributeData extends \Magento\ConfigurableProduct\Model\ConfigurableAttributeData
{
protected $eavConfig;
public function __construct(\Magento\Eav\Model\Config $eavConfig) {
$this->eavConfig = $eavConfig;
}
public function getAttributeOptionsData($attribute, $config) {
$attributeOptionsData = [];
$attributeId = $attribute->getAttributeId();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$eavModel = $objectManager->create('Magento\Catalog\Model\ResourceModel\Eav\Attribute');
$attr = $eavModel->load($attributeId);
$attributeCode=$eavModel->getAttributeCode();
$attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
$options = $attribute->getSource()->getAllOptions();
foreach ($options as $attributeOption) {
$optionId = $attributeOption['value'];
$attributeOptionsData[] = [
'id' => $optionId,
'label' => $attributeOption['label'],
'products' => isset($config[$attribute->getAttributeId()][$optionId])
? $config[$attribute->getAttributeId()][$optionId]
: [],
];
}
return $attributeOptionsData;
}
}
app/code/Ravindra/Custom/view/frontend/layout/catalog_product_view.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="Ravindra_Custom::css/configurableproduct.css"/>
</head>
</page>
app/code/Ravindra/Custom/view/frontend/layout/catalog_product_view_type_configurable.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info.configurable">
<action method='setTemplate'>
<argument name="template" xsi:type="string">Ravindra_Custom::configurable-available.phtml</argument>
</action>
</referenceBlock>
</body>
</page>
app/code/Ravindra/Custom/view/frontend/templates/configurable-available.phtml
<?php /* @var $block \Magento\Catalog\Block\Product\View\AbstractView */?>
<?php $_product = $block->getProduct() ?>
<?php $stockblock = $this->getLayout()->createBlock('Ravindra\Custom\Block\ConfigurableProduct'); ?>
<?php if ($block->displayProductStockStatus()): ?>
<?php if ($_product->isAvailable()): ?>
<div class="stock available mcs-available" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>">
<span><?php /* @escapeNotVerified */ echo __('In stock') ?></span>
</div>
<?php else: ?>
<div class="stock unavailable" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>">
<span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span>
</div>
<div class="ravi-stockalert">
<div class="rav-subscriber-title"><?php
/* @escapeNotVerified */
?>
</div>
<div class="ravi-stockalert-form">
<form name="stockalert_form" id="stockalert_form" method="POST" action="<?php echo $stockblock->getStockalertPostUrl(); ?>" data-mage-init='{"validation":{}}'>
<div class="email-stockalert-input">
<input class="input-text" type="email" data-validate="{required:true, 'validate-email':true}" type="text" placeholder="Enter email address" name="email" />
</div>
<input type="hidden" id="cp_product_id" name="product_id" value="<?php echo $_product->getId(); ?>" >
<input type="hidden" name="product_name" value="<?php echo $_product->getName(); ?>" >
<div class="submit-stockalert-input">
<input type="submit" class="stockalert-submit-btn" name="submit" value="subscribe">
</div>
</form>
<div style="clear:both;"></div>
</div>
</div>
<?php endif; ?>
<div class="mcs-config-product-stockalert" id="mcs-config-product-stockalert" style="display:none;">
<div class="stock unavailable" title="<?php /* @escapeNotVerified */ echo __('UnAvailability') ?>">
<span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span>
</div>
</div>
<?php endif; ?>
app/code/Ravindra/Custom/view/frontend/web/css/configurableproduct.css
.email-stockalert-input{
float:left;
width: 80%;
}
.submit-stockalert-input {
width: 20%;
float: right;
}
.email-stockalert-input input, .submit-stockalert-input input{
height: 40px;
}
.submit-stockalert-input input{
float: left;
width: 100%;
background: #1979c3;
border: 1px solid #1979c3;
color: #ffffff;
cursor: pointer;
display: inline-block;
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 600;
font-size: 14px;
text-transform: capitalize;
}
.stockalert-submit-btn:hover{
background: #333;
border: 1px solid #333;
}
.ravi-stockalert, .ravi-stockalert-bundle, .ravi-stockalert-group{
/*text-align: center !important;*/
margin: 10px 0px;
border: 1px #ccc solid;
padding: 10px;
}
.product-info-stock-sku{
display:block !important;
}
.product-info-price{
/*width: 55% !important;*/
}
.product-info-main .product-info-price .price-box{
width: 100%;
float: left;
}
.product-info-main .product-info-stock-sku{
float: left;
min-width: 100%;
padding-left: 0px;
}
.stock.unavailable{
text-align:left;
color:#F00;
font-size: 16px;
font-weight: 400 !important;
}
.sku .value, .sku{
text-align:left;
}
.ravi-stockalert-form {
margin: 5px 0;
width: 100%;
}
.page-product-grouped .product-info-price{
width:100%;
}
.table.grouped .col.item {
width: 13%;
}
.grouped .email-stockalert-input{
width: 69%;
}
.grouped .submit-stockalert-input{
width: 31%
}
.grouped .submit-stockalert-input input{
font-size: 12px;
}
.grouped .table.grouped .col.qty{
padding: 11px 0px;
}
.item span, .item strong{
color: #1979C3;
}
.grouped .product-item-name {
color: #000 !important;
font-size: 16px;
}
.rav-subscriber-title {
text-align: left;
}
.guest_users_message{
text-align:left;
}
app/code/Ravindra/Custom/view/frontend/requirejs-config.js
var config = {
map: {
'*': {
'Magento_Swatches/js/swatch-renderer':'Ravindra_Custom/js/swatch-renderer',
configurable:'Ravindra_Custom/js/configurable',
}
}
};