Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento tier prices - class declaration for tier price in BUY x for Y - javascript

There is an outstanding bug in 1.6+ versions of Magento where the % savings for tier prices defaults to 100% when an option is selected. Other contributors have suggested changing product.js around line 747 from

for (var i = 0; i < this.tierPrices.length; i++) {

to be

for (var i = 0; i > this.tierPrices.length; i++) {

This resolves the issue with % savings but that code block is never executed. I am by no means a Javascript expert but this block appears to be updating the tier price and % savings when options are selected. I wanted to find the root of the issue, rather than 'commenting it out'.

From my debugging in Firebug I noticed that the classes for tier price is wrong in product.js and therefore, a tier price of 0 is retrieved, which accounts for why % savings is always 100%. Firebug shows the price as

class="tier-prices product-pricing">   
        Buy 10 for  
        <span class="price">$40.00</span>

whereas product.js is attempting to retrieve the objects using

$$('.price.tier-' + i).each(function (el) {

If you change the above to

$$('.tier-prices .price).each(function (el) {

the tier price is retrieved, but for more than one tier price on a product, there is no way to refer to them individually. The class "price" above does not have a unique identifier or iterative number declared.

Where is class="price" declared for the tier price? In the code of tierprices.phtml it looks like this

<?php echo $this->__('Buy %1$s for %2$s each', $_price['price_qty'], $_price['formated_price'])?>
like image 645
GenAtBlueJalappeno Avatar asked Nov 22 '12 00:11

GenAtBlueJalappeno


People also ask

How many types of price in Magento 2?

Magento 2 Special price: is the discounted price in a specific time period. Group price: specify promotional price set up for each customer group. Manufacturer's Suggested Retail Price: is the price suggested by manufacturers.

Which price offer a quantity discount from the catalog list and product detail pages?

Tier pricing lets you offer a quantity discount from a product listing or product page in the storefront.


1 Answers

I've just spent some time on this as it was really starting to bug me after I upgraded a customer's Magento site to 1.7.0.2.

There are two parts to this, I'm going to state the locations and the fixes, but these will not be upgrade proof (for that you will want to create copies of the files and put them in your theme specific folders, although I'm not sure if it's possible with the JS file in question).

1) View Fix

In the file /design/frontend/base/default/template/catalog/product/view/tierprices.phtml

you need to replace lines 32-34

$_product = $this->getProduct();
$_tierPrices = $this->getTierPrices();
$_finalPriceInclTax = $this->helper('tax')->getPrice($_product, $_product->getFinalPrice(), true);

with the following code:

$_product = $this->getProduct();
$_tierPrices = array();

foreach($this->getTierPrices() as $index => $info) {
    $_tierPrices[$index] = $info;
    $_tierPrices[$index]['formated_price'] = str_replace('class="price"', 'class="price tier-'.$index.'"', $info['formated_price']);
    $_tierPrices[$index]['formated_price_incl_tax'] = str_replace('class="price"', 'class="price tier-'.$index.' tier-'.$index.'-incl-tax"', $info['formated_price_incl_tax']);
}
$_finalPriceInclTax = $this->helper('tax')->getPrice($_product, $_product->getFinalPrice(), true);

This fixes the issue with the class not being rendered correctly as you had already figured out. Here is where I found this code - although it didn't fix all the issues, hence the JS changes.

2) JS fix

in the file js/Varien/product.js you need to replace lines 757-769:

$$('.benefit').each(function (el) {
    var parsePrice = function (html) {
        return parseFloat(/\d+\.?\d*/.exec(html));
    };
    var container = $(this.containers[3]) ? this.containers[3] : this.containers[0];
    var price = parsePrice($(container).innerHTML);
    var tierPrice = $$('.price.tier-' + i);
    tierPrice = tierPrice.length ? parseInt(tierPrice[0].innerHTML, 10) : 0;
    var $percent = Selector.findChildElements(el, ['.percent.tier-' + i]);
    $percent.each(function (el) {
        el.innerHTML = Math.ceil(100 - ((100 / price) * tierPrice));
    });
}, this);

With this:

//
// Code fixed to prevent the redundant inner loop and to use actual tiered pricing in calculation
// It also takes the optional price variants into consideration (eg: +£2 for a blue tshirt)
// Note: I've made this comment deliberately large, to keep the line numbers in sync
//
var parsePrice = function (html) {
    return parseFloat(/\d+\.?\d*/.exec(html));
};
var container = $(this.containers[3]) ? this.containers[3] : this.containers[0];
var price = parsePrice($(container).innerHTML);
$$('.percent.tier-' + i).each(function (el) {
    el.innerHTML = Math.ceil(100 - ((100 / price) * (this.tierPrices[i] + parseFloat(optionPrices))));
}, this);

I hope this saves at least one person a few hours of their life.

T

like image 91
Tr1stan Avatar answered Oct 21 '22 23:10

Tr1stan