0

I want to add stock labels to the options fields of my configurable products, but I don't understand how it works in Magento. I have read that I have to use the Mage_Catalog_Block_Product_View_Type_Configurable class. So I have created a little extension which uses this class, but there are some issues with my extension and I think this issuses exists because of a lack of knowledge.

Details:

My configurable products have configurable attributes like the following: enter image description here

Furthermore if someone choose an option he will get something like this: enter image description here

This looks great so far, but the values are sadly not correct.

Here is the core class of my extension:

<?php

class Fox_OutOfStockLabel_Block_Configurable extends
    Mage_Catalog_Block_Product_View_Type_Configurable
{
    public function getJsonConfig()
    {
        $store = Mage::app()->getStore();
        $attributes = array();
        $options = array();

        $allowedProducts = $this->getAllowProducts();
        $allowedAttributes = $this->getAllowAttributes();

        foreach ($allowedProducts as $product) {

            $productId = $product->getId();

            foreach ($allowedAttributes as $attribute) {

                $productAttribute = $attribute->getProductAttribute();
                $attributeId = $productAttribute->getId();
                $attributeCode = $productAttribute->getAttributeCode();
                $attributeValue = $product->getData($attributeCode);
                $attributeLabel = $product->getAttributeText($attributeCode);
                $qty = floor($product->getStockItem()->getQty());

                if (!isset($options[$attributeId])) {
                    $options[$attributeId] = array();
                }
                if (!isset($options[$attributeId][$attributeValue])) {
                    $options[$attributeId][$attributeValue] = array();
                }
                $options[$attributeId][$attributeValue][] = $productId;
                $options['qty'][$attributeLabel] = $qty;
            }
        }

        $this->_resPrices = array(
            $this->_preparePrice($this->getProduct()->getFinalPrice())
        );

        foreach ($allowedAttributes as $attribute) {

            $productAttribute = $attribute->getProductAttribute();
            $attributeId = $productAttribute->getId();
            $attributeCode = $productAttribute->getAttributeCode();
            $attributeLabel = $attribute->getLabel();

            $info = array(
                'id' => $attributeId,
                'code' => $attributeCode,
                'label' => $attributeLabel,
                'options' => array()
            );

            $optionPrices = array();
            $prices = $attribute->getPrices();
            if (is_array($prices)) {
                foreach ($prices as $value) {
                    if (!$this->_validateAttributeValue($attributeId, $value, $options)) {
                        continue;
                    }
                    $label = $value['label'].$this->__(' (Out of stock)');
                    if ($options['qty'][$value['label']] > 0) {
                        $label = $value['label'].$this->__(' (%s in stock)', $options['qty'][$value['label']]);
                    }
                    $info['options'][] = array( 
                        'id' => $value['value_index'],
                        'label' => $label,
                        'price' => $this->_preparePrice($value['pricing_value'], $value['is_percent']),
                        'qty' => isset($options[$attributeId][$value['label']]) ? $options[$attributeId][$value['label']] : array(),
                        'products' => isset($options[$attributeId][$value['value_index']]) ? $options[$attributeId][$value['value_index']] : array(),
                    );
                    $optionPrices[] = $this->_preparePrice($value['pricing_value'], $value['is_percent']);
                }
            }

            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()),
//            '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')->__('Option wählen...'),
            'taxConfig' => $taxConfig,
        );

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

This will create the output from above. This output is not correct and it seems that the options will be overwritten at this position:

$options['qty'][$attributeLabel] = $qty;

because I have multiple products with the same attribute label. To avoid this behaviour I could change it to:

$options['qty'][$attributeLabel][$productId] = $qty;

But is this correct and the right way I have to go? I don't know, because I don't know when Magento will call the function getJsonConfig. Currently it seems that Magento is calling this function only if I visit the detail page of a configurable product, but Magento should calling this function after the selection of an option too, so that the options will be updated or am I wrong?

1 Answer 1

0

Ok, I could eliminate my lack of knowledge and found a solution which is working for me:

<?php

class Fox_StockLabel_Block_Configurable extends Mage_Catalog_Block_Product_View_Type_Configurable
{
    public function getJsonConfig()
    {
        $attributes = array();
        $options = array();
        $optionsLabel = array();
        $store = Mage::app()->getStore();

        $allowedProducts = $this->getAllowProducts();
        $allowedAttributes = $this->getAllowAttributes();

        foreach ($allowedProducts as $product) {
            $productId = $product->getId();

            foreach ($allowedAttributes as $attribute) {
                $productAttribute = $attribute->getProductAttribute();
                $attributeId = $productAttribute->getId();
                $attributeCode = $productAttribute->getAttributeCode();
                $attributeValue = $product->getData($attributeCode);
                $attributeLabel = $product->getAttributeText($attributeCode);

                if (!isset($options[$attributeId])) {
                    $options[$attributeId] = array();
                }
                if (!isset($options[$attributeId][$attributeValue])) {
                    $options[$attributeId][$attributeValue] = array();
                }
                $options[$attributeId][$attributeValue][] = $productId;

                $qty = floor($product->getStockItem()->getQty());
                $options['qty'][$attributeLabel] += $qty;
            }
        }

        $this->_resPrices = array(
            $this->_preparePrice($this->getProduct()->getFinalPrice())
        );

        foreach ($allowedAttributes as $attribute) {
            array_push($optionsLabel, $attribute->getLabel()) ;
        }
        $numberOfOptions = count($optionsLabel);

        foreach ($allowedAttributes as $attribute) {
            $productAttribute = $attribute->getProductAttribute();
            $attributeId = $productAttribute->getId();
            $attributeCode = $productAttribute->getAttributeCode();
            $attributeLabel = $attribute->getLabel();

            $info = array(
                'id' => $attributeId,
                'code' => $attributeCode,
                'label' => $attributeLabel,
                '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++) {
                            $a = array(0 => $products[$i]);
                            $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($products[$i]);
                            $currentItem = Mage::getModel('catalog/product')->load($products[$i]);

                            $qty = floor($stockItem->getQty());
                            $label = $value['label'] . $this->__(' (Out of stock)');
                            if ($qty > 0) {
                                $label = $value['label'] . $this->__(' (%s in stock)', $qty);
                            }
                            $info['options'][] = array(
                                'id' => $value['value_index'],
                                'label' => $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 {
                        $label = $value['label'] . $this->__(' (Out of stock)');
                        if ($options['qty'][$value['label']] > 0) {
                            $label = $value['label'] . $this->__(' (%s in stock)', $options['qty'][$value['label']]);
                        }
                        $info['options'][] = array(
                            'id' => $value['value_index'],
                            'label' => $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']);
                }
            }

            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);
    }
}

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.