How to show out of stock configurable options with Magento

Create a new php file called Configurable.php and located in app/code/local/XLPages/ManageStock/Block/Product/View/Type/Configurable.php.

create config.xml with the following content and under app/code/local/XLPages/ManageStock/config.xml:




    
        
            0.1.0
        
    
    
        
            
               
                    XLPages_ManageStock_Block_Product_View_Type_Configurable

                
            
        
    

create a file called XLPages_ManageStock.xml with the following content and located
under app/etc/modules/XLPages_ManageStock.xml

  

    
        
            true
            local
        
    

In Admin create a new attribute called backorder_date and add it to your attribut_set, this will let customer knows if the item is on backorder and what is the backorder date.

< ?php

class XLPages_ManageStock_Block_Product_View_Type_Configurable  extends Mage_Catalog_Block_Product_View_Type_Configurable
{
   
	
	public function getJsonConfig()
	{
		$attributes = array();
		$options = array();
		$store = Mage::app()->getStore();
		foreach ($this->getAllowProducts() as $product) {
			$productId  = $product->getId();

			foreach ($this->getAllowAttributes() as $attribute) {

				$productAttribute = $attribute->getProductAttribute();
				$attributeValue = $product->getData($productAttribute->getAttributeCode());

				$options['qty'][$product -> getAttributeText($productAttribute->getName())] = floor($product->getStockItem()->getQty());


				if (!isset($options[$productAttribute->getId()])) {
					$options[$productAttribute->getId()] = array();

				}
				if (!isset($options[$productAttribute->getId()][$attributeValue])) {
					$options[$productAttribute->getId()][$attributeValue] = array();

				}
				$options[$productAttribute->getId()][$attributeValue][] = $productId;

			}
		}

		$this->_resPrices = array(
		$this->_preparePrice($this->getProduct()->getFinalPrice())
		);
		foreach ($this->getAllowAttributes() as $attribute) {
			$productAttribute = $attribute->getProductAttribute();
			$attributeId = $productAttribute->getId();

			$info = array(
			'id'        => $productAttribute->getId(),
			'code'      => $productAttribute->getAttributeCode(),
			'label'     => $attribute->getLabel(),
			'options'   => array()
			);

			$optionPrices = array();
			$prices = $attribute->getPrices();

			if (is_array($prices)) {
				foreach ($prices as $value) {
					if(!$this->_validateAttributeValue($attributeId, $value, $options)) {
						continue;
					}
					if($attribute->getLabel() != "Color") {
						$products= $options[$attributeId][$value['value_index']];
                                                $numItems= count($products)
						for($i=0;$i<$numItems;$i++){
							$backoder_date=null;
							$a = array(0 => $products[$i]);
							$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($products[$i]);
							$currentItem = Mage::getModel('catalog/product')->load($products[$i]);
							$info['options'][] = array(
							'id'    => $value['value_index'],
							'label' => ($stockItem->getQty() <= 0) ? $value['label'] . ' (out of stock'.$this->formatDate($currentItem ->getData('backorder_date')).")" : $value['label'],
							//'price' => $this->_preparePrice($value['pricing_value'], $value['is_percent']),
							'price' =>  $this->_registerJsPrice($this->_convertPrice($currentItem ->getData('price'))) - $this->_registerJsPrice($this->_convertPrice($this->getProduct()->getPrice())),
							'products'   => isset($options[$attributeId][$value['value_index']]) ? $a : array(),
							);
						}
					} else {
						$info['options'][] = array(
						'id'    => $value['value_index'],
						'label' => $value['label'],
						'price' => $this->_preparePrice($value['pricing_value'], $value['is_percent']),
						'products'   => isset($options[$attributeId][$value['value_index']]) ? $options[$attributeId][$value['value_index']] : array(),
						);
					}
					$optionPrices[] = $this->_preparePrice($value['pricing_value'], $value['is_percent']);
				}

			}
			/**
             * Prepare formated values for options choose
             */
			foreach ($optionPrices as $optionPrice) {
				foreach ($optionPrices as $additional) {
					$this->_preparePrice(abs($additional-$optionPrice));
				}
			}
			if($this->_validateAttributeInfo($info)) {
				$attributes[$attributeId] = $info;
			}
		}
		$config = array(
		'attributes'=> $attributes,
		'template'  => str_replace('%s', '#{price}', $store->getCurrentCurrency()->getOutputFormat()),
		'prices'    => $this->_prices,
		'basePrice' => $this->_registerJsPrice($this->_convertPrice($this->getProduct()->getFinalPrice())),
		'oldPrice'  => $this->_registerJsPrice($this->_convertPrice($this->getProduct()->getPrice())),
		'productId' => $this->getProduct()->getId(),
		'chooseText'=> Mage::helper('catalog')->__('Choose option...'),
		);
		return Zend_Json::encode($config);
	}
	
	function formatDate($date){
	   $_date = explode(" ", $date);
	     if($_date[0] != ""){
        	return " ~ ".$_date[0]; 
        }
	}
}

?>



NB: If you are using Magento 1.4 version, the function getJsonConfig() must be replaced by this new one (see below).

< ?php
class Ayasoftware_SimpleProductPricing_Catalog_Block_Product_View_Type_Configurable  extends Mage_Catalog_Block_Product_View_Type_Configurable
{
public function getJsonConfig() {
	    $attributes = array();
		$options = array();
		$store = Mage::app()->getStore();
		foreach ($this->getAllowProducts() as $product) {
			$productId  = $product->getId();
			foreach ($this->getAllowAttributes() as $attribute) {
				$productAttribute = $attribute->getProductAttribute();
				$attributeValue = $product->getData($productAttribute->getAttributeCode());
				if (!isset($options[$productAttribute->getId()])) {
					$options[$productAttribute->getId()] = array();
				}

				if (!isset($options[$productAttribute->getId()][$attributeValue])) {
					$options[$productAttribute->getId()][$attributeValue] = array();
				}
				$options[$productAttribute->getId()][$attributeValue][] = $productId;
			}
		}

		$this->_resPrices = array(
		$this->_preparePrice($this->getProduct()->getFinalPrice())
		);
		$optionsLabel = array();
		foreach ($this->getAllowAttributes() as $attribute) {
			array_push($optionsLabel, $attribute->getLabel()) ;
		}
		$numberOfOptions =  count($optionsLabel);
		foreach ($this->getAllowAttributes() as $attribute) {
			$productAttribute = $attribute->getProductAttribute();
			$attributeId = $productAttribute->getId();
			$info = array(
			'id'        => $productAttribute->getId(),
			'code'      => $productAttribute->getAttributeCode(),
			'label'     => $attribute->getLabel(),
			'options'   => array()
			);
			$optionPrices = array();
			$prices = $attribute->getPrices();
			if (is_array($prices)) {
				foreach ($prices as $value) {
					if(!$this->_validateAttributeValue($attributeId, $value, $options)) {
						continue;
					}					
					if($attribute->getLabel() == $optionsLabel[$numberOfOptions - 1]) {
					   $products= $options[$attributeId][$value['value_index']];
                       $numItems= count($products);
						for($i=0;$i<$numItems;$i++){
							$backoder_date=null;
							$a = array(0 => $products[$i]);
							$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($products[$i]);
							$currentItem = Mage::getModel('catalog/product')->load($products[$i]);
							$info['options'][] = array(
							'id'    => $value['value_index'],
							'label' => ($stockItem->getQty() <= 0) ? $value['label'] . ' (out of stock) ' : $value['label'],
							'price' =>  $this->_registerJsPrice($this->_convertPrice($currentItem ->getData('price'))) - $this->_registerJsPrice($this->_convertPrice($this->getProduct()->getPrice())),
							'products'   => isset($options[$attributeId][$value['value_index']]) ? $a : array(),
							);
						}
					} else {
						$info['options'][] = array(
						'id'    => $value['value_index'],
						'label' => $value['label'],
						'price' => $this->_preparePrice($value['pricing_value'], $value['is_percent']),
						'products'   => isset($options[$attributeId][$value['value_index']]) ? $options[$attributeId][$value['value_index']] : array(),
						);
					}
					$optionPrices[] = $this->_preparePrice($value['pricing_value'], $value['is_percent']);
				}

			}
			
			/**
             * Prepare formated values for options choose
             */
			foreach ($optionPrices as $optionPrice) {
				foreach ($optionPrices as $additional) {
					$this->_preparePrice(abs($additional-$optionPrice));
				}
			}
			if($this->_validateAttributeInfo($info)) {
				$attributes[$attributeId] = $info;
			}
		}

		$_request = Mage::getSingleton('tax/calculation')->getRateRequest(false, false, false);
		$_request->setProductClassId($this->getProduct()->getTaxClassId());
		$defaultTax = Mage::getSingleton('tax/calculation')->getRate($_request);

		$_request = Mage::getSingleton('tax/calculation')->getRateRequest();
		$_request->setProductClassId($this->getProduct()->getTaxClassId());
		$currentTax = Mage::getSingleton('tax/calculation')->getRate($_request);

		$taxConfig = array(
		'includeTax'        => Mage::helper('tax')->priceIncludesTax(),
		'showIncludeTax'    => Mage::helper('tax')->displayPriceIncludingTax(),
		'showBothPrices'    => Mage::helper('tax')->displayBothPrices(),
		'defaultTax'        => $defaultTax,
		'currentTax'        => $currentTax,
		'inclTaxTitle'      => Mage::helper('catalog')->__('Incl. Tax'),
		);

		$config = array(
		'attributes'        => $attributes,
		'template'          => str_replace('%s', '#{price}', $store->getCurrentCurrency()->getOutputFormat()),
		'basePrice'         => $this->_registerJsPrice($this->_convertPrice($this->getProduct()->getFinalPrice())),
		'oldPrice'          => $this->_registerJsPrice($this->_convertPrice($this->getProduct()->getPrice())),
		'productId'         => $this->getProduct()->getId(),
		'chooseText'        => Mage::helper('catalog')->__('Choose an Option...'),
		'taxConfig'         => $taxConfig,
		);

		return Mage::helper('core')->jsonEncode($config);
	}
}
?> 

want to disable the selection if it shows "out of stock? replace this bloc in js/varien/product.js

 if(allowedProducts.size()>0){
                	
                    options[i].allowedProducts = allowedProducts;
                    var option_label = this.getOptionLabel(options[i], options[i].price);
                    element.options[index] = new Option(option_label, options[i].id);
                   if(option_label.indexOf('stock') !== -1) {
                    $(element.options[index]).addClassName('disabled');
					element.options[index].disabled = true;
                    }
                    element.options[index].config = options[i];
                    index++;
                }

Need help ? Get instant answers to Your Magento Programming Questions .

Comments

Show out of stock products

To show out of stock products do the following: open Configurable.php add the following function to your class: public function getAllowProducts() { if (!$this->hasAllowProducts()) { $products = array(); $allProducts = $this->getProduct()->getTypeInstance(true) ->getUsedProducts(null, $this->getProduct()); foreach ($allProducts as $product) { //if ($product->isSaleable()) { Disable to show out of stock products $products[] = $product; //} } $this->setAllowProducts($products); } return $this->getData('allow_products'); } See the comment in the code.

Working with 1.5?

I've added the above code to my 1.5 store but am not seeing any out of stock configurable options (sizes in my case). Does this code work with 1.5? I know the code is being used because I've seen modifications that I've made to the dropdown option labels appear, but as I say, only instock items are appearing as they were before I added your code.

Need help ? Get instant answers to Your Magento Programming...

Help! As stated I dont seem to see any difference after adding this code to my site. The code is definately being used but out of stock product options don't show up still. Any ideas where to start trying to diagnose whats wrong? Thanks