Display the lowest price in Prestashop product list

If you sell products which have a lower price when bought in stocks, you might want to display the lowest possible price in your product list. Let’s see how Prestashop can be bent to this.

  • Prestashop version: 1.5.3.1

Introduction

Before trying to do anything, it’s worth knowing that you can’t achieve the rulst without an ovverride. Therefore, you might want to have a look at the Official Prestashop documentation on how to override default behaviors before starting, if you don’t know anything about the subject. Specifically, we will override the category controller.

Step 1 – Retrieving quantity discounts in the CategoryController override

In override/controllers/front open up CategoryController.php, and add the following method inside the class:


	public function initContent()
	{
		parent::initContent();
		
		if($this->cat_products) {

			$id_customer = (isset($this->context->customer) ? (int)$this->context->customer->id : 0);
			$id_group = (isset($this->context->customer) ? $this->context->customer->id_default_group : _PS_DEFAULT_CUSTOMER_GROUP_);
			$id_country = (int)$id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT');
			$id_currency = (int)$this->context->cookie->id_currency;
			$id_shop = $this->context->shop->id;



			foreach ($this->cat_products as $key => $product) {

				$prices_array = array();

				/* For each product, grab quantity discounts */
				$quantity_discounts = SpecificPrice::getQuantityDiscounts($product['id_product'], $id_shop, $id_currency, $id_country, $id_group, null, true);
				
			}
		}
	}

Explanation: Lots of stuff going on here. First, we call the parent’s initContent method, so that we are sure products have already been picked from this category. Then, if there are some products (if $this->cat_products), we assign some variables we need to get an accurate specific price. Lastly, for each of our products, we call the built-in method SpecificPrice::getQuantityDiscounts, passing the current product’s ID as first parameter, along with the others we retrieved earlier. Note that I also created an empty array, which will hold all reduced prices for this product. We need to create it here, so that it’s being reset for every product!

At this point, if you dump the quantity discounts variable, you’ll see your discounts appear.

Step 2 – Processing discounts to get the real product price

We can’t use those discounts as they are, as some of them may be fixed amounts, some other percentages, or another set price. Let’s crush them down to the same thing: the real price of the product with each discount applied. Add this right after getting $quantity_discounts:

				/* Process quantity discounts to get the real price */

				if ($quantity_discounts)
				{
					foreach ($quantity_discounts as $qkey => $discount) {
						
						if (!(float)$discount['reduction'])
							$price = $discount['price'];
						else {
							if ($discount['reduction_type'] == 'percentage')
							{
								$price = $product['price_without_reduction'] - ($product['price_without_reduction'] * $discount['reduction']);
							}
							else {
								$price = $product['price_without_reduction'] - $discount['reduction'];							
							}
						}

						$prices_array[] = $price;

					}

				} // end if quantity discounts

Explanation: If there are quantity discounts, for each of them check the reduction. If the floating number for $product['reduction'] is 0, it means that we applied a new fixed price, otherwise we have 2 options: percentage or amount reduction. In the first case, we do some math and reduce the product price by its percentage, in the other we simply subtract the discount amount. After this, we end up having the $price variable as a floating point number for all our discounts, so that we can compare it. As the last thing, we put this in an array with all previous prices.

The last things wee need to do are, after the quantity discounts foreach loop, assigning the new price to the current instance of the product in the list, and tell the system this product has quantity discounts (we will see why later on):

$this->cat_products[$key]['price'] = min($prices_array);
$this->cat_products[$key]['qt_disc'] = true;

And finally, after “} // end if quantity discounts”, reassign the product list with our corrected prices:

$this->context->smarty->assign('products', $this->cat_products);

And this is it! You’ll now see your lowest price appearing in the list. There is a little thing left: adding “from” in the product list.

Step 3 – Adding “from” in the product list

Navigate to your theme’s folder, and open up product-list.tpl. Find this piece of code, at about line 52 of the original version (1.5.3.1)

					{if isset($product.show_price) && $product.show_price && !isset($restricted_country_mode)}<span class="price" style="display: inline;">{if !$priceDisplay}{convertPrice price=$product.price}{else}{convertPrice price=$product.price_tax_exc}{/if}</span><br />{/if}

Change it the following way:

					{if isset($product.show_price) && $product.show_price && !isset($restricted_country_mode)}<span class="price" style="display: inline;">{l s='From'} {if !$priceDisplay}{convertPrice price=$product.price}{else}{convertPrice price=$product.price_tax_exc}{/if}</span><br />{/if}

This way, all products will have a “from” before the price. if you want to assign the “from” word only to those products which actually have quantity discounts, you can change the previous lines the following way instead:

					{if isset($product.show_price) && $product.show_price && !isset($restricted_country_mode)}
						<span class="price" style="display: inline;">
							{if isset($product.qt_disc)}
								{l s='From'}
							{/if}
							{if !$priceDisplay}
								{convertPrice price=$product.price}
							{else}
								{convertPrice price=$product.price_tax_exc}
							{/if}
						</span><br />
					{/if}

So, basically we use the previously assigned variable to check if a product has quantity discounts. If it does, show the “from” text.

You like the tuts and want to say "thank you"? Well, you can always feel free to donate:

  • tom

    How to show the lowest price on product.tpl also , the current code is not not working there.

    plz help.

  • iboinas

    Yeap, got it working with 1.5.6.2…
    I believe what misses most people is the proper way to make the override work!!
    In override/controllers/front…. Make file “CategoryController.php”

    This is linux, so please all paths and names are CASE SENSITIVE!!
    Then make it look like this

    —begin file

    —end of file

    Step 1 should replace the comment line!!

    Below i leave all working code!

    Thanks NEMOPS!!!!!

    Just wondering how to translate the new “from” that we added??? :D

    Complete code to override/controllers/front./CategoryController.php

    cat_products) {

    $id_customer = (isset($this->context->customer) ? (int)$this->context->customer->id : 0);

    $id_group = (isset($this->context->customer) ? $this->context->customer->id_default_group : _PS_DEFAULT_CUSTOMER_GROUP_);

    $id_country = (int)$id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get(‘PS_COUNTRY_DEFAULT’);

    $id_currency = (int)$this->context->cookie->id_currency;

    $id_shop = $this->context->shop->id;

    foreach ($this->cat_products as $key => $product) {

    $prices_array = array();

    /* For each product, grab quantity discounts */

    $quantity_discounts = SpecificPrice::getQuantityDiscounts($product['id_product'], $id_shop, $id_currency, $id_country, $id_group, null, true);

    /* Process quantity discounts to get the real price */

    if ($quantity_discounts)

    {

    foreach ($quantity_discounts as $qkey => $discount) {

    if (!(float)$discount['reduction'])

    $price = $discount['price'];

    else {

    if ($discount['reduction_type'] == ‘percentage’)

    {

    $price = $product['price_without_reduction'] – ($product['price_without_reduction'] * $discount['reduction']);

    }

    else {

    $price = $product['price_without_reduction'] – $discount['reduction'];

    }

    }

    $prices_array[] = $price;

    }

    $this->cat_products[$key]['price'] = min($prices_array);

    $this->cat_products[$key]['qt_disc'] = true;

    } // end if quantity discounts

    $this->context->smarty->assign(‘products’, $this->cat_products);

    }

    }

    }

    }

    ?>

  • Newtoprestashop16

    Hi!
    Has someone tried to apply this on Prestashop 1.6?
    Thanks!

  • Shad

    I think I´ve done everything like explained but nothing happened.
    My PS is version 1.5.5.0
    Isn´t it possible with this version?

  • mario ibarra

    is not working in the newest version 1.5.6.2!
    :(

    • NemoPS

      It works for me, try clearing cache and make sure you added everything correctly ;)

  • Prestalearn

    Someone who got this to work on ps 1.5.6.2? Im not getting any functionality on product-list.tpl :/

    • NemoPS

      Approved

      A new comment was posted on Nemo’s Post Scriptum

      _____

      This comment is awaiting moderator approval.

      _____

      Prestalearn (Guest):

      Someone who got this to work on ps 1.5.6.2? Im not getting any functionality on product-list.tpl :/
      7:13 p.m., Tuesday Jan. 28

      Moderate this comment by email

      Email address: emil.jansson@icec.se | IP address: 217.211.131.98
      Reply to this email with “Delete”, “Approve”, or “Spam”, or moderate from the Disqus moderation panel.

      _____

      You’re receiving this message because you’re signed up to receive notifications about activity on threads authored by NemoPS.
      You can unsubscribe from emails about activity on threads authored by NemoPS by replying to this email with “unsubscribe” or reduce the rate with which these emails are sent by adjusting your notification settings.

  • http://rito.dk Dennis Drejer

    Thank you so much.

    I wanted to show all the quantity discounts on the categorypage and keep price as single price.

    Try to have a look at http://rito.dk/98-silke-blanding (hover the images an see the quantity discounts).

    The complete code to orderride the CategoryController:

    cat_products) {

    $id_customer = (isset($this->context->customer) ? (int)$this->context->customer->id : 0);
    $id_group = (isset($this->context->customer) ? $this->context->customer->id_default_group : _PS_DEFAULT_CUSTOMER_GROUP_);
    $id_country = (int)$id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get(‘PS_COUNTRY_DEFAULT’);
    $id_currency = (int)$this->context->cookie->id_currency;
    $id_shop = $this->context->shop->id;

    foreach ($this->cat_products as $key => $product) {

    $prices_array = array();

    /* For each product, grab quantity discounts */
    $quantity_discounts = SpecificPrice::getQuantityDiscounts($product['id_product'], $id_shop, $id_currency, $id_country, $id_group, null, true);

    /* Process quantity discounts to get the real price */

    if ($quantity_discounts)
    {
    foreach ($quantity_discounts as $qkey => $discount) {

    if (!(float)$discount['reduction'])
    $price = $discount['price'];
    else {
    if ($discount['reduction_type'] == ‘percentage’)
    {
    $price = $product['price_without_reduction'] – ($product['price_without_reduction'] * $discount['reduction']);
    }
    else {
    $price = $product['price_without_reduction'] – $discount['reduction'];
    }
    }

    $prices_array[$discount['from_quantity']] = $price;

    }
    ksort($prices_array);
    $this->cat_products[$key]['priceDiscounts'] = $prices_array;
    $this->cat_products[$key]['priceDiscountsLowest'] = min($prices_array);
    $this->cat_products[$key]['qt_disc'] = true;

    } // end if quantity discounts
    }
    $this->context->smarty->assign(‘products’, $this->cat_products);
    }
    }
    }

  • Prestalearn

    Hi!
    I really find this script usefull. Thanks alot!
    However since my primary currency is not euro, I added euro today and noticed that the price “from XXX pounds” changed and displayed “price from -xxx euro” when customer chooses euro as suggested value.. The quantity price got negative, I cant really understand why.
    Any suggestions?
    Thanks and happy new year!

  • http://www.cosmomedica.com Raul

    Hi Nemo.
    First of all sorry for my poor english.

    I can’t get this working.

    In my product.tpl I added this code and it shows the discount for each quantity option:
    {if $quantity_discounts}

    {l s=’Quantity discount’}

    Precio 1 unidad: {convertPrice price=$product->getPrice(false, $smarty.const.NULL, 2)}

    {foreach from=$quantity_discounts item=’quantity_discount’ name=’quantity_discounts’}

    Precio {$quantity_discount.quantity|intval} unidades:
    {if $quantity_discount.price != 0 OR $quantity_discount.reduction_type == ‘amount’}
    {math equation=”pprice – disc” pprice=$productPrice disc=$quantity_discount.real_value assign=price_break}
    {convertPrice price=$price_break} c/u
    {else}
    save {$quantity_discount.real_value|floatval}%
    {/if}

    {/foreach}

    {/if}
    But I can’t get the same result in product-list.tpl. I’ve tried your code. Maybe I did something wrong.

  • nzurita

    In version 1.5.4.1 only works for first page of products in category, next pages, (loaded through ajax) don’t work as it looks like CategoryController is not invoked through ajax calls.

  • Fixfinn

    After upgrading to 1.5.5 it does not work anymore!
    What can I do, to get it working?

    • http://nemops.com Nemo

      Did you use an override or edited core files directly? If it’s the second case, you’ll need to reapply your changes!

      • Fixfinn

        for showing prices in product-list.tpl, I used the override at this side.

    • Fixfinn

      I think I got it working.

      i reset the class_index.php and it looks like it is working know:-)

  • Cat

    Hi,

    This looks great, do you have a solution for PS 1.4.10 ?

    Thanks in advance,
    Cat

  • Mambley

    Hello,

    Thanks for your tip, i have two problems:

    1 – i can only put this working in the /controller/front folder, not the override/controller/front;

    2 – i get the discount price on the product list, not the price with discount (ex: product costs 10$ with 2$ discount, it should show “from 8$” right? But in my case shows “from -2$”. How can i fix this?

    Thanks a lot.

    Cheers

    • Mambley

      I found how to pu working in the override folder, need to delete the class_index.php in cache folder.

      But i still have the price issue. Can you help me?

      Other thing, its possible to enable the add_cart button on the product-list?

      Thanks again.

  • Peterlyberth

    How would I modify this code to show the percentage of the quantity discount insted?

  • Tobias

    Hi again guys, i solved it. I had done it wrong. Here is the proper solution:

    cat_products) {

    $id_customer = (isset($this->context->customer) ? (int)$this->context->customer->id : 0);
    $id_group = (isset($this->context->customer) ? $this->context->customer->id_default_group : _PS_DEFAULT_CUSTOMER_GROUP_);
    $id_country = (int)$id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get(‘PS_COUNTRY_DEFAULT’);
    $id_currency = (int)$this->context->cookie->id_currency;
    $id_shop = $this->context->shop->id;

    foreach ($this->cat_products as $key => $product) {

    $prices_array = array();

    /* For each product, grab quantity discounts */
    $quantity_discounts = SpecificPrice::getQuantityDiscounts($product['id_product'], $id_shop, $id_currency, $id_country, $id_group, null, true);

    /* Process quantity discounts to get the real price */

    if ($quantity_discounts)
    {
    foreach ($quantity_discounts as $qkey => $discount) {

    if (!(float)$discount['reduction'])
    $price = $discount['price'];
    else {
    if ($discount['reduction_type'] == ‘percentage’)
    {
    $price = $product['price_without_reduction'] – ($product['price_without_reduction'] * $discount['reduction']);
    }
    else {
    $price = $product['price_without_reduction'] – $discount['reduction'];
    }
    }

    $prices_array[] = $price;

    }
    $this->cat_products[$key]['price'] = min($prices_array);
    $this->cat_products[$key]['qt_disc'] = true;
    } // end if quantity discounts
    $this->context->smarty->assign(‘products’, $this->cat_products);
    }
    }
    }
    }

    • Kiro

      Hello Tobias,

      Your code is incomplete? Missing something before cat_products) { ?

      I would appreciate more information, I’m stuck and I can not make it work :(

      Thank you, greetings.

  • Tobias

    Hi!

    I don’t get this to work with 1.5.4.1. Can i be doing something wrong?

    Br,
    Tobias

    CONTENTS OF MY CATEGORYCONTROLLER FILE:

    cat_products) {

    $id_customer = (isset($this->context->customer) ? (int)$this->context->customer->id : 0);
    $id_group = (isset($this->context->customer) ? $this->context->customer->id_default_group : _PS_DEFAULT_CUSTOMER_GROUP_);
    $id_country = (int)$id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get(‘PS_COUNTRY_DEFAULT’);
    $id_currency = (int)$this->context->cookie->id_currency;
    $id_shop = $this->context->shop->id;

    foreach ($this->cat_products as $key => $product) {

    $prices_array = array();

    /* For each product, grab quantity discounts */
    $quantity_discounts = SpecificPrice::getQuantityDiscounts($product['id_product'], $id_shop, $id_currency, $id_country, $id_group, null, true);

    }
    /* Process quantity discounts to get the real price */

    if ($quantity_discounts)
    {
    foreach ($quantity_discounts as $qkey => $discount) {

    if (!(float)$discount['reduction'])
    $price = $discount['price'];
    else {
    if ($discount['reduction_type'] == ‘percentage’)
    {
    $price = $product['price_without_reduction'] – ($product['price_without_reduction'] * $discount['reduction']);
    }
    else {
    $price = $product['price_without_reduction'] – $discount['reduction'];
    }
    }

    $prices_array[] = $price;

    }

    } // end if quantity discounts
    }
    }
    }

  • Kiro

    Hello,

    First, thank you for the tutorial.

    But I have a problem, I followed the steps carefully and does not work.

    Any idea?

  • Yazo

    Hi,

    Can i use your override controller with a PS 1.5.4 ?

    Thanks ;)

    • http://nemops.com Nemo

      Yes, but you will need to erase the classes cache in order for PS to see the override (i’ll do a short quick tip about it the sooner)

  • Fixfinn

    Hi again:-)

    I figured it out and put it in categorycontroller.php.

    It is almost working correctly.

    I show my prices without tax. and for product #1 with fixed price-reduction, it shows correctly.
    But for product #2 and #3 with reduction with amount and percent, it shows prices incl. tax?
    Best regards
    Finn

    • http://nemops.com Nemo

      If you want the taxless version, you have to use price_tax_exc

      • Fixfinn

        Thanks I got it to work.
        It was exactly what I was looking for.

        Do You know if there is a place to see the different variables used in prestashop?

        • http://nemops.com Nemo

          Sure, in 1.5 you can choose if you want to open the smarty debug console in advanced preferences->performance. You can do it either by calling ?SMARTY_DEBUG after the url, or always open it. Note that it opens in a popup, so be sure you accept pps from the page if you use an adblockr or similar

      • Fixfinn

        Where do I put this?

        • Fixfinn

          I mean, it looks like the variable priceDisplay change value at products with quantity discount compared to products without quantity discount.?

          products with Q.D. is showing the price without tax and products without Q.D. is showing the price with tax?

          here is the code:

          {if isset($product.show_price) && $product.show_price && !isset($restricted_country_mode)}

          {if isset($product.qt_disc)}
          {l s=’Price starts from’}
          {else}
          {l s=’Price pr. pcs.’}
          {/if}

          {if !$priceDisplay}
          {convertPrice price=$product.price}
          {else}
          {convertPrice price=$product.price_tax_exc}
          {/if}

          {/if}

  • Fixfinn

    Hi!

    It looks like it is what I wanted. But I have some quoestion.

    Where do You put step 2? in which file?

    Best regards

    Finn

    • http://nemops.com Nemo

      Right after getting $quantity_discounts, in that same file :)

Westhost Website Builder 20% off 300x250

Store Top Sales

You like the tuts and want to say "thank you"? Well, you can always feel free to donate: