2

please visit configurable product

please search for "color" using CTRL + F , than you can see "choose an option"

enter image description here

MRP : 100 , Special price : 50, Discount : 50 % OFF = > Fine

please change choose an option" to "Blue" ,than

MRP : 100 , Special price : 60 , Discount : 50 % OFF = > This is the problem, IT should show **"40% OFF" after change to "Blue".

enter image description here

Configurable.phtml

app/design/frontend/base/default/template/catalog/product/view/type/options/configurable.phtml  

<?php
$_product    = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
?>
<?php if ($_product->isSaleable() && count($_attributes)):?>
    <dl>
    <?php foreach($_attributes as $_attribute): ?>
        <dt><label class="required"><em>*</em><?php echo $_attribute->getLabel() ?></label></dt>
        <dd<?php if ($_attribute->decoratedIsLast){?> class="last"<?php }?>>
            <div class="input-box">
                <select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="required-entry super-attribute-select">
                    <option><?php echo $this->__('Choose an Option...') ?></option>
                  </select>
              </div>
        </dd>
    <?php endforeach; ?>
    </dl>
    <script type="text/javascript">
        var spConfig = new Product.Config(<?php echo $this->getJsonConfig() ?>);
    </script>
<?php endif;?>

Configurable.js

if (typeof Product == 'undefined') {
    var Product = {};
}

/**************************** CONFIGURABLE PRODUCT **************************/
Product.Config = Class.create();
Product.Config.prototype = {
    initialize: function(config){
        this.config     = config;
        this.taxConfig  = this.config.taxConfig;
        if (config.containerId) {
            this.settings   = $$('#' + config.containerId + ' ' + '.super-attribute-select');
        } else {
            this.settings   = $$('.super-attribute-select');
        }
        this.state      = new Hash();
        this.priceTemplate = new Template(this.config.template);
        this.prices     = config.prices;

        // Set default values from config
        if (config.defaultValues) {
            this.values = config.defaultValues;
        }

        // Overwrite defaults by url
        var separatorIndex = window.location.href.indexOf('#');
        if (separatorIndex != -1) {
            var paramsStr = window.location.href.substr(separatorIndex+1);
            var urlValues = paramsStr.toQueryParams();
            if (!this.values) {
                this.values = {};
            }
            for (var i in urlValues) {
                this.values[i] = urlValues[i];
            }
        }

        // Overwrite defaults by inputs values if needed
        if (config.inputsInitialized) {
            this.values = {};
            this.settings.each(function(element) {
                if (element.value) {
                    var attributeId = element.id.replace(/[a-z]*/, '');
                    this.values[attributeId] = element.value;
                }
            }.bind(this));
        }

        // Put events to check select reloads
        this.settings.each(function(element){
            Event.observe(element, 'change', this.configure.bind(this))
        }.bind(this));

        // fill state
        this.settings.each(function(element){
            var attributeId = element.id.replace(/[a-z]*/, '');
            if(attributeId && this.config.attributes[attributeId]) {
                element.config = this.config.attributes[attributeId];
                element.attributeId = attributeId;
                this.state[attributeId] = false;
            }
        }.bind(this))

        // Init settings dropdown
        var childSettings = [];
        for(var i=this.settings.length-1;i>=0;i--){
            var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
            var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
            if (i == 0){
                this.fillSelect(this.settings[i])
            } else {
                this.settings[i].disabled = true;
            }
            $(this.settings[i]).childSettings = childSettings.clone();
            $(this.settings[i]).prevSetting   = prevSetting;
            $(this.settings[i]).nextSetting   = nextSetting;
            childSettings.push(this.settings[i]);
        }

        // Set values to inputs
        this.configureForValues();
        document.observe("dom:loaded", this.configureForValues.bind(this));
    },

    configureForValues: function () {
        if (this.values) {
            this.settings.each(function(element){
                var attributeId = element.attributeId;
                element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
                this.configureElement(element);
            }.bind(this));
        }
    },

    configure: function(event){
        var element = Event.element(event);
        this.configureElement(element);
    },

    configureElement : function(element) {
        this.reloadOptionLabels(element);
        if(element.value){
            this.state[element.config.id] = element.value;
            if(element.nextSetting){
                element.nextSetting.disabled = false;
                this.fillSelect(element.nextSetting);
                this.resetChildren(element.nextSetting);
            }
        }
        else {
            this.resetChildren(element);
        }
        this.reloadPrice();
    },

    reloadOptionLabels: function(element){
        var selectedPrice;
        if(element.options[element.selectedIndex].config && !this.config.stablePrices){
            selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
        }
        else{
            selectedPrice = 0;
        }
        for(var i=0;i<element.options.length;i++){
            if(element.options[i].config){
                element.options[i].text = this.getOptionLabel(element.options[i].config, element.options[i].config.price-selectedPrice);
            }
        }
    },

    resetChildren : function(element){
        if(element.childSettings) {
            for(var i=0;i<element.childSettings.length;i++){
                element.childSettings[i].selectedIndex = 0;
                element.childSettings[i].disabled = true;
                if(element.config){
                    this.state[element.config.id] = false;
                }
            }
        }
    },

    fillSelect: function(element){
        var attributeId = element.id.replace(/[a-z]*/, '');
        var options = this.getAttributeOptions(attributeId);
        this.clearSelect(element);
        element.options[0] = new Option('', '');
        element.options[0].innerHTML = this.config.chooseText;

        var prevConfig = false;
        if(element.prevSetting){
            prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
        }

        if(options) {
            var index = 1;
            for(var i=0;i<options.length;i++){
                var allowedProducts = [];
                if(prevConfig) {
                    for(var j=0;j<options[i].products.length;j++){
                        if(prevConfig.config.allowedProducts
                            && prevConfig.config.allowedProducts.indexOf(options[i].products[j])>-1){
                            allowedProducts.push(options[i].products[j]);
                        }
                    }
                } else {
                    allowedProducts = options[i].products.clone();
                }

                if(allowedProducts.size()>0){
                    options[i].allowedProducts = allowedProducts;
                    element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
                    if (typeof options[i].price != 'undefined') {
                        element.options[index].setAttribute('price', options[i].price);
                    }
                    element.options[index].config = options[i];
                    index++;
                }
            }
        }
    },

    getOptionLabel: function(option, price){
        var price = parseFloat(price);
        if (this.taxConfig.includeTax) {
            var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
            var excl = price - tax;
            var incl = excl*(1+(this.taxConfig.currentTax/100));
        } else {
            var tax = price * (this.taxConfig.currentTax / 100);
            var excl = price;
            var incl = excl + tax;
        }

        if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
            price = incl;
        } else {
            price = excl;
        }

        var str = option.label;
        if(price){
            if (this.taxConfig.showBothPrices) {
                str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
            } else {
                str+= ' ' + this.formatPrice(price, true);
            }
        }
        return str;
    },

    formatPrice: function(price, showSign){
        var str = '';
        price = parseFloat(price);
        if(showSign){
            if(price<0){
                str+= '-';
                price = -price;
            }
            else{
                str+= '+';
            }
        }

        var roundedPrice = (Math.round(price*100)/100).toString();

        if (this.prices && this.prices[roundedPrice]) {
            str+= this.prices[roundedPrice];
        }
        else {
            str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
        }
        return str;
    },

    clearSelect: function(element){
        for(var i=element.options.length-1;i>=0;i--){
            element.remove(i);
        }
    },

    getAttributeOptions: function(attributeId){
        if(this.config.attributes[attributeId]){
            return this.config.attributes[attributeId].options;
        }
    },

    reloadPrice: function(){
        if (this.config.disablePriceReload) {
            return;
        }
        var price    = 0;
        var oldPrice = 0;
        for(var i=this.settings.length-1;i>=0;i--){
            var selected = this.settings[i].options[this.settings[i].selectedIndex];
            if(selected.config){
                price    += parseFloat(selected.config.price);
                oldPrice += parseFloat(selected.config.oldPrice);
            }
        }

        optionsPrice.changePrice('config', {'price': price, 'oldPrice': oldPrice});
        optionsPrice.reload();

        return price;

        if($('product-price-'+this.config.productId)){
            $('product-price-'+this.config.productId).innerHTML = price;
        }
        this.reloadOldPrice();
    },

    reloadOldPrice: function(){
        if (this.config.disablePriceReload) {
            return;
        }
        if ($('old-price-'+this.config.productId)) {

            var price = parseFloat(this.config.oldPrice);
            for(var i=this.settings.length-1;i>=0;i--){
                var selected = this.settings[i].options[this.settings[i].selectedIndex];
                if(selected.config){
                    price+= parseFloat(selected.config.price);
                }
            }
            if (price < 0)
                price = 0;
            price = this.formatPrice(price);

            if($('old-price-'+this.config.productId)){
                $('old-price-'+this.config.productId).innerHTML = price;
            }

        }
    }
}

Price .phtml = > http://pastebin.com/cPXyxy6E // only 30000 char allowed

we are using following code for

app/code/community/OrganicInternet/SimpleConfigurableProducts/Catalog/Model/Product/Type/Configurable/Price.php 

<?php

    #The methods in there have become a bit convoluted, so it could benefit from a tidy,
    #...though the logic is not that simple any more.

    class OrganicInternet_SimpleConfigurableProducts_Catalog_Model_Product_Type_Configurable_Price
        extends Mage_Catalog_Model_Product_Type_Configurable_Price
    {
        #We don't want to show a separate 'minimal' price for configurable products.
        public function getMinimalPrice($product)
        {
            return $this->getPrice($product);
        }

        public function getMaxPossibleFinalPrice($product) {
            #Indexer calculates max_price, so if this value's been loaded, use it
            $price = $product->getMaxPrice();
            if ($price !== null) {
                return $price;
            }

            $childProduct = $this->getChildProductWithHighestPrice($product, "finalPrice");
            #If there aren't any salable child products we return the highest price
            #of all child products, including any ones not currently salable.

            if (!$childProduct) {
                $childProduct = $this->getChildProductWithHighestPrice($product, "finalPrice", false);
            }

            if ($childProduct) {
                return $childProduct->getFinalPrice();
            }
            return false;
        }

        #If there aren't any salable child products we return the lowest price
        #of all child products, including any ones not currently salable.
        public function getFinalPrice($qty=null, $product)
    {
        //Start edit
        $selectedAttributes = array();
        if ($product->getCustomOption('attributes')) {
            $selectedAttributes = unserialize($product->getCustomOption('attributes')->getValue());
        }
        //End edit
        if (sizeof($selectedAttributes)) return $this->getSimpleProductPrice($qty, $product);

        if (is_null($qty) && !is_null($product->getCalculatedFinalPrice())) {
            return $product->getCalculatedFinalPrice();
        }

        $basePrice = $this->getBasePrice($product, $qty);
        $finalPrice = $basePrice;
        $product->setFinalPrice($finalPrice);
        Mage::dispatchEvent('catalog_product_get_final_price', array('product' => $product, 'qty' => $qty));
        $finalPrice = $product->getData('final_price');

        $finalPrice += $this->getTotalConfigurableItemsPrice($product, $finalPrice);
        $finalPrice += $this->_applyOptionsPrice($product, $qty, $basePrice) - $basePrice;
        $finalPrice = max(0, $finalPrice);

        $product->setFinalPrice($finalPrice);
        return $finalPrice;
    }

    public function getSimpleProductPrice($qty=null, $product)
        {
            $cfgId = $product->getId();
            $product->getTypeInstance(true)
                ->setStoreFilter($product->getStore(), $product);
            $attributes = $product->getTypeInstance(true)
                ->getConfigurableAttributes($product);
            $selectedAttributes = array();
            if ($product->getCustomOption('attributes')) {
                $selectedAttributes = unserialize($product->getCustomOption('attributes')->getValue());
            }
            $db = Mage::getSingleton('core/resource')->getConnection('core_read');
            $dbMeta = Mage::getSingleton('core/resource');
            $sql = <<<SQL
    SELECT main_table.entity_id FROM {$dbMeta->getTableName('catalog/product')} `main_table` INNER JOIN
    {$dbMeta->getTableName('catalog/product_super_link')} `sl` ON sl.parent_id = {$cfgId}
    SQL;
            foreach($selectedAttributes as $attributeId => $optionId) {
                $alias = "a{$attributeId}";
                $sql .= ' INNER JOIN ' . $dbMeta->getTableName('catalog/product') . "_int" . " $alias ON $alias.entity_id = main_table.entity_id AND $alias.attribute_id = $attributeId AND $alias.value = $optionId AND $alias.entity_id = sl.product_id";
            }
            $id = $db->fetchOne($sql);
            return Mage::getModel("catalog/product")->load($id)->getFinalPrice($qty);
        }

        public function getPrice($product)
        {
            #Just return indexed_price, if it's been fetched already
            #(which it will have been for collections, but not on product page)
            $price = $product->getIndexedPrice();
            if ($price !== null) {
                return $price;
            }

            $childProduct = $this->getChildProductWithLowestPrice($product, "finalPrice");
            #If there aren't any salable child products we return the lowest price
            #of all child products, including any ones not currently salable.
            if (!$childProduct) {
                $childProduct = $this->getChildProductWithLowestPrice($product, "finalPrice", false);
            }

            if ($childProduct) {
                return $childProduct->getPrice();
            }

            return false;
        }

        public function getChildProducts($product, $checkSalable=true)
        {
            static $childrenCache = array();
            $cacheKey = $product->getId() . ':' . $checkSalable;

            if (isset($childrenCache[$cacheKey])) {
                return $childrenCache[$cacheKey];
            }

            $childProducts = $product->getTypeInstance(true)->getUsedProductCollection($product);
            $childProducts->addAttributeToSelect(array('price', 'special_price', 'status', 'special_from_date', 'special_to_date'));

            if ($checkSalable) {
                $salableChildProducts = array();
                foreach($childProducts as $childProduct) {
                    if($childProduct->isSalable()) {
                        $salableChildProducts[] = $childProduct;
                    }
                }
                $childProducts = $salableChildProducts;
            }

            $childrenCache[$cacheKey] = $childProducts;
            return $childProducts;
        }

    /*
        public function getLowestChildPrice($product, $priceType, $checkSalable=true)
        {
            $childProduct = $this->getChildProductWithLowestPrice($product, $priceType, $checkSalable);
            if ($childProduct) {
                if ($priceType == "finalPrice") {
                    $childPrice = $childProduct->getFinalPrice();
                } else {
                    $childPrice = $childProduct->getPrice();
                }
            } else {
                $childPrice = false;
            }
            return $childPrice;
        }
    */
        #Could no doubt add highest/lowest as param to save 2 near-identical functions
        public function getChildProductWithHighestPrice($product, $priceType, $checkSalable=true)
        {
            $childProducts = $this->getChildProducts($product, $checkSalable);
            if (count($childProducts) == 0) { #If config product has no children
                return false;
            }
            $maxPrice = 0;
            $maxProd = false;
            foreach($childProducts as $childProduct) {
                if ($priceType == "finalPrice") {
                    $thisPrice = $childProduct->getFinalPrice();
                } else {
                    $thisPrice = $childProduct->getPrice();
                }
                if($thisPrice > $maxPrice) {
                    $maxPrice = $thisPrice;
                    $maxProd = $childProduct;
                }
            }
            return $maxProd;
        }

        public function getChildProductWithLowestPrice($product, $priceType, $checkSalable=true)
        {
            $childProducts = $this->getChildProducts($product, $checkSalable);
            if (count($childProducts) == 0) { #If config product has no children
                return false;
            }
            $minPrice = PHP_INT_MAX;
            $minProd = false;
            foreach($childProducts as $childProduct) {
                if ($priceType == "finalPrice") {
                    $thisPrice = $childProduct->getFinalPrice();
                } else {
                    $thisPrice = $childProduct->getPrice();
                }
                if($thisPrice < $minPrice) {
                    $minPrice = $thisPrice;
                    $minProd = $childProduct;
                }
            }
            return $minProd;
        }

        //Force tier pricing to be empty for configurable products:
        public function getTierPrice($qty=null, $product)
        {
            return array();
        }
    }
  • What's your piece of code that writes the discount block? I think price.php is a red herring - When you change the dropdown selection, there's a piece of script that updates the price... Start in in /template/catalog/product/view/type/options/configurable.phtml - where it references var spConfig. I think you're going to need to update /js/varien/configurable.js to update the discount amount as well. – SamC Feb 26 '16 at 21:00
  • Thanks for opening my eyes. I posted configurable.phtml & configurable.js in question. – Baby in Magento Feb 27 '16 at 5:11
  • please check you don't have give price in associate product under configurable product..b''coz sometime it will add price – Dhaval Patel Feb 27 '16 at 7:09
  • i gave price for associated products also – Baby in Magento Feb 27 '16 at 7:26
1
+50

I see that you are using the Simple Configurable Product extension. You can simply modify the file scp_product_extension.js and add the below two lines of code after line 177 in the javascript file:

var discountAmount = ((price - finalPrice) / price) * 100;
jQuery('.you_save_price').text(discountAmount + '%');

What this is doing is that everytime you select an option the SCP extension javascript file is reloading the price, so adding this code to that js file should do the trick. I tested it on the site provided above. Please give it a shot and let me know if it works!

  • I added your code below this line updateProductImage(childProductId); } sorry, still showing same result. – Baby in Magento Mar 2 '16 at 22:14
  • You need to edit this file skin/frontend/default/em0113/js/scp_product_extension.js after line 177 after the closing curly brace }. I took a look and I'm not seeing the code in the js file. – Jerry Lopez Mar 2 '16 at 22:18
  • please check here : pastebin.com/suENL1Ci , i added like this. here : link – Baby in Magento Mar 2 '16 at 22:21
  • as it is test site, i added in base folder : /skin/frontend/base/default/js/scp_product_extension.js – Baby in Magento Mar 2 '16 at 22:23
  • You have the file overwritten in skin/frontend/default/em0113/js/ so you need to modify the file in that directory or remove it. Also make sure to clear Magento's cache. – Jerry Lopez Mar 2 '16 at 22:25
1

Lables "50%OFF" only change one time on loading time.

There was no js regarding change in "50%OFF" lable in configurable.js Its calling from price.phtml file.

So need to write javascript for that in your configurable.js file.

Also check in price.phtml file for %OFF coding. I think you are using SCP (https://github.com/organicinternet/magento-configurable-simple)

Place this code in reloadPrice: function() { } before return price in Configurable.js

place your amount/percent in div using jquery.

savePercent = parseFloat( 100 - (Math.round((optionsPrice.productPrice/optionsPrice.productOldPrice) * 100))).toString() ;
saveAmount = parseFloat( optionsPrice.productOldPrice - optionsPrice.productPrice);
console.log( 'Percent: '+savePercent );
console.log( 'Amount: '+saveAmount );

$('save_perc').innerHTML = savePercent;

in your price.phtml file

<div class="You_savee">
    <p class="special-price yousave">
        <span class="label yousave_label">You Save:</span>
        <span class="you_save_price" id="save_perc">50%</span>
    </p>
</div>

add "save_perc" id in you_save_price class. Clear cache folder.

I hope this helps you. Enjoy coding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.