Tridian Los Angeles Web Design Firm - blog design, web design, flash animation, ecommerce & transaction processing, software & database development and search engine optimization firm in Los Angeles California





Web Design & Development Los Angeles - blog design, web design, flash animation, ecommerce & transaction processing, software & database development and search engine optimization


Tridian Developer Blog



Tier Pricing in Magento

February 27th, 2009

So, Magento is a really great piece of software, but like any relatively new product, it’s missing some things that people think are important. One thing in particular that’s missing is a major aspect of tier pricing pertaining to configurable products. For example, if someone were to buy 4 red shirts and 6 blue shirts all from the same product, then they should still receive the discount for 10 shirts of that product.  Currently Magento only applies the tier pricing if they bought say 10 red shirts (all the same color, instead of a mix of colors).  This is a big problem when involving colors and sizes - if your customer orders 5 smalls and 5 mediums, and they expect a discount at 10 items, they will be upset that they do not receive the tier pricing discount.

Luckily, I have a solution for you to try out.  Seems to work pretty good for one of Tridian’s Magento clients. Are you curious? Good. Then let’s dive right in.

The goal for this module is to accommodate the following requirement: If you have a tier price discount at 10 and add 5 of one color and 5 of another, the cart will adjust the price for the 2 cart items to the 10 qty price.

I installed it as a module that extends Mage_Catalog_Model_Product_Type_Configurable_Price. 

1. Create your module.  I created mine in app/code/local/Tridian/Catalog.  Use your own namespace instead of Tridian, if you prefer.  Create Model and etc sub folders in Catalog.
2. Add xml to Tridian_All.xml in app/etc/modules/Tridian_All.xml
3. Set up rewrite in app/code/local/Tridian/Catalog/etc/config.xml
4. Extend the class and save to app/code/local/Tridian/Catalog/Model/Product/Type/Configurable/Price.php

Here’s my app/etc/modules/Tridian_All.xml

<?xml version="1.0"?> <config>     <modules>         <Tridian_Catalog>             <active>true</active>             <codePool>local</codePool>         </Tridian_Catalog>     </modules> </config>

Here’s my app/code/local/Tridian/Catalog/etc/config.xml

<?xml version="1.0"?> <config>     <modules>         <Tridian_Catalog>             <version>0.1.0</version>         </Tridian_Catalog>     </modules>     <global>         <models>             <catalog>                 <rewrite>                     <product_type_configurable_price>Tridian_Catalog_Model_Product_Type_Configurable_Price</product_type_configurable_price>                 </rewrite>             </catalog>         </models>     </global> </config>

And lastly here’s the extended class

class Tridian_Catalog_Model_Product_Type_Configurable_Price extends Mage_Catalog_Model_Product_Type_Configurable_Price {     /**      * Get product final price      *      * @param   double $qty      * @param   Mage_Catalog_Model_Product $product      * @return  double      */     public function getFinalPrice($qty=null$product)     {         if (is_null($qty) && !is_null($product->getCalculatedFinalPrice())) {             return $product->getCalculatedFinalPrice();         }         $finalPrice = parent::getFinalPrice($qty$product);         // Call config product tier pricing function - Chris Lohman 1/6/2009         /* This allows for tier price to affect configurable items of different sizes, colors, etc.          * so that when you have some qty of each, the total will be counted towards the tier pricing matrix.          */         $tierPrice = $this->calcConfigProductTierPricing($product);         if($tierPrice > 0)             $finalPrice = $tierPrice;           $finalPrice = $this->_applySpecialPrice($product$finalPrice);                  $product->getTypeInstance()->setStoreFilter($product->getStore());         $attributes = $product->getTypeInstance()->getConfigurableAttributes();         $selectedAttributes = array();         if ($product->getCustomOption('attributes')) {             $selectedAttributes = unserialize($product->getCustomOption('attributes')->getValue());         }                  $basePrice = $finalPrice;         foreach ($attributes as $attribute) {             $attributeId = $attribute->getProductAttribute()->getId();             $value = $this->_getValueByIndex(                 $attribute->getPrices() ? $attribute->getPrices() : array(),                 isset($selectedAttributes[$attributeId]) ? $selectedAttributes[$attributeId] : null             );             if($value) {                 if($value['pricing_value'] != 0) {                     $finalPrice += $this->_calcSelectionPrice($value$basePrice);                 }             }         }         $product->setFinalPrice($finalPrice);         return max(0$product->getData('final_price'));     }     /**      * Get product final price via configurable product's tier pricing structure.  Uses qty of parent item to determine price.      *      * @param   float $price      * @param   Mage_Catalog_Model_Product $product      * @return  float      */     public function calcConfigProductTierPricing($product)     {         $tierPrice = 0;         if($items = Mage::getSingleton('checkout/session')->getQuote()->getItemsCollection())         {             //The items collection has instances of the parent and simple product.  The correct quantity value is related to the parent             //so if we loop through and create an array of skus w/quantities, the quantities will fall into array items under the parent sku (array key).             $cfg_quantities = array();             foreach ($items as $item)             {                 $sku = $item->getSku();                 $qty = $item->getQty();                 $cfg_quantities[$sku][] = $qty;             }             if(array_key_exists($product->getSku()$cfg_quantities))             {                 $cfg_qty = array_sum($cfg_quantities[$product->getSku()]);                 $tierPrice = $this->getTierPrice($cfg_qty$product);             }         }         return $tierPrice;     } }

I know - that’s a lot of code, right? Well, let me explain how it works and you’ll see that it’s not all that bad, ok? The theory is to use the relationship that already exists between the configurable product and its child simple products. The function getTierPrice takes a quantity and a product as parameters, so all we need to do is figure out the total number of items in the cart that share the same parent configurable item and then pass that new total to the getTierPrice function. This is exactly what our calcConfigProductTierPricing function does. Counting up the products is accomplished by taking advantage of the structure of the products collection that’s returned from the cart. The product collection has entries for the parent and simple version of each product in the cart. The quantity of that item in the cart is assigned to the parent member of the collection. So when we have 2 items in the cart that share the same parent, as a red shirt and black shirt of the same product, we can loop through the collection and take the sku value from the parent and then create a secondary array of the quantity of each item. That way, quantities for different child products will all become secondary arrays under the same key (which happens to be the sku of the parent). Once we’ve looped through the entire cart collection, we check if the current product’s sku is in the configurable products array using the array_key_exists function, and if so, we sum the quantities of the array and then use that new total to submit to our getTierPrice function. Now, if you offer a price break at ten items and someone buys 5 red and 5 black, they’ll get the pricing discount!

Keep in mind, that if you are using a different version of Magento, like 1.1.7 or 1.1.8, etc. you should extend *YOUR* version of Mage_Catalog_Model_Product_Type_Configurable_Price, instead of copying my code from this post.  Most of the code of the function getFinalPrice in my extended class is copied directly from my 1.1.6 version of Mage_Catalog_Model_Product_Type_Configurable_Price.  The only lines I added to getFinalPrice() are the 4 lines that call my calcConfigProductTierPricing() function, then check to see if the price is greater than 0, and then apply the special price if it’s lower than the tier price. Everything else in the function is existing code from the core class.

// Call config product tier pricing function - Chris Lohman 1/6/2009         /* This allows for tier price to affect configurable items of different sizes, colors, etc.          * so that when you have some qty of each, the total will be counted towards the tier pricing matrix.          */         $tierPrice = $this->calcConfigProductTierPricing($product);         if($tierPrice > 0)             $finalPrice = $tierPrice;         $finalPrice = $this->_applySpecialPrice($product$finalPrice);

So, use the getFinalPrice function from *YOUR* Magento version’s Mage_Catalog_Model_Product_Type_Configurable_Price class as your starting point, and then insert those 4 additional lines to call calcConfigProductTierPricing, and then your version of Tridian_Catalog_Model_Product_Type_Configurable_Price will be good to go.

Cheers!

Posted by: chris
chris

Tags: , ,

17 Responses to “Tier Pricing in Magento”

  1. Hey,

    Thanks for such a great and helpful post about Tier Pricing. Tier pricing is a promotional tool that lets you price items differently for higher quantities. This is an effective way to move more merchandise.

  2. Christian says:

    Hi Chris,

    in my opinion your code is exactly what I want and searched for. I try to make it work in my magento 1.2.1 shop, but it has no effect.
    I’ve never installed a module without using the magento connect manager, so I think there is the problem. I don’t know where to activat your module.
    Can you help? Hope to here from you soon.

    Regards
    Christian

    • chris says:

      Hi Christian,

      You don’t need to activate the module in the admin, it will be enabled by default when you add the Tridian_All.xml file to /app/etc/modules. Did you make sure to add that file to your installation?

      -Chris

  3. Ranjeet says:

    Hi There,
    I have done according your instruction. but on my site no control goes to Mage_Catalog_Model_Product_Type_Configurable_Price. So thats why your did not works. Is any setting is required to run the code for Mage_Catalog_Model_Product_Type_Configurable_Price.
    Please reply ASAP.

    Ranjeet

    • chris says:

      Hi Ranjeet,

      I have a few questions - first what version of Magento are you using? Second, what do you mean that no control goes to Mage_Catalog_Model_Product_Type_Configurable_Price? In 1.1.6, this was the class that determined the price. Maybe that’s no longer the case. If so, then you’ll need to find the new class and apply what I’m doing, but with a few changes to reflect that different class.

      Cheers,
      Chris

      • Ranjeet says:

        Hi Chris,

        Thanks for reply. Version of Magento is 1.3.1. No control goes to Mage_Catalog_Model_Product_Type_Configurable_Price means code in this file did not run in any process on my site means this class did not works. your class is extend version of this class so this not help me. Only Mage_Catalog_Model_Product_Type_Price class in run on the cart page to claculate the price.
        Please if you have any solution.

        Ranjeet.

      • Ranjeet says:

        Hi ,

        i m using magento 1.3.2.1 version. control not goes to Mage_Catalog_Model_Product_Type_Configurable_Price means class in this page did not works. your code is extend class of Mage_Catalog_Model_Product_Type_Configurable_Price page class. in any process Mage_Catalog_Model_Product_Type_Configurable_Price page not works.

        Ranjeet.

        • chris says:

          It seems like you could take a similar approach to what I did by overriding Mage_Catalog_Model_Product_Type_Price instead of Mage_Catalog_Model_Product_Type_Configurable_Price. I just downloaded 1.3.2.3 and I see that the function getFinalPrice is in both classes, so override that function in Mage_Catalog_Model_Product_Type_Price and add my calcConfigProductTierPricing function to handle the tier pricing. Everything you need is right there.

          • Fernando says:

            Hey,

            I tried doing as you said Chris, but maybe I can’t find the right spot to put the new code into the Mage_Catalog_Model_Product_Type_Price. I’m using 1.3.2.3 as well, and well, the getFinalPrice function is quite a bit different. Mind showing me the path?

  4. erictr1ck says:

    this is an amazing post, thanks for sharing!

  5. sidewalk says:

    Great post! Thank you for this solution.

    But since I created this override, it shows me a “Special price” on the product detail page when an tier price amount was reached. I think this is because your override just changes the final price. Magento is displaying a special price becaue the final price is not the same as the regular price. I don’t want a special price to be displayed since this is just a tier price.

    Also, when you reached an tier price amount, the amount will dissapear in the “tier prices” table on the product detail page. It’s now looking like the tier price doesn’t exist anymore.

    I think these issues are very confusing to the customer. It would be great if you could help out by finding a solution for this!

    sidewalk

  6. Evi says:

    Thank jou for this great post.

    It works late a charm.

    Regards,

    Evi

  7. Cory says:

    Hey Chris…

    I’m really stuck on this one. I can’t seem to get this to work for Magento version 1.3.2.2
    I read through your post meticulously here and on Magento’s forums and followed your instruction to a “t” but keep getting errors. I’ve even had the product page just show up blank. Could you possibly post up the extended class code for 1.3.2.2? I really need to get this running!

  8. Thank you for providing an easy modification detail for Tire Pricing in Magneto.

  9. Great post..Keep them coming :) Thanks for sharing.

  10. Michael says:

    I can’t seem to get the tier price to show up on front end no matter what i do! version i am using is ver. 1.3.2.4! I have searched wide and far but no luck…i done what suggested on the forum too but no luck either

    config>catalog>catalog>price> set to website —> no joy

    could you please help to point me to the right direction!

Leave a Reply






Los Angeles Web Design Firm Tridian Specializes in: Web Design - Flash Animation - Ecommerce - Online Transaction Processing - Software & Database Programming - Search Engine Optimization