Jump to content

Block Layered Price Slider - Use "Unit Price"


threeopus3

Recommended Posts

Hi Forum,

 

I am wondering whether anyone can help me to modify that price slider that is part of the block layered module. I suspect that this would be a mod to "blocklayered.js".

 

Currently the price slider uses the the price values. I would like it to use "unit price" values.

 

Can you help? If so, please name your price and let me know how long it will take.

 

Thanks,

Kent

  • Like 1
Link to comment
Share on other sites

Hi Kent,

 

Which version of Prestashop do you use? The layered navigation price slider actually uses an index table (ps_layered_price_index) to cache prices as integers. If you're confident that every product will have a unit price and you don't need the original price slider I can simply modify the blocklayered.php file to divide prices by the saved unit_price_ratio (which I can do right away).

 

If a product doesn't have a unit price I would have to make the indexed min/max prices 0 and that would mean those products come up at all times. If you don't want this to occur some front end stuff may need changing (which I haven't played around with yet).

 

Cheers,

 

Michael

Link to comment
Share on other sites

Thanks for the reply, Michael.

 

Sometimes the products are for sale by the single unit, in which case the unit price is the same as the actual price.

 

Sometimes the products are for sale by 12 or 6 packs, in which case the unit price would be the actual price divided by 12 or 6. In such cases, the products have features set up called "Minimum Order" (products > features) and the "Minimum Order" values are 12 or 6.

 

So, in blocklayered.php, if I could access the the feature called "Minimum Order", I would know how whether to divide by 12, 6 or 1. Are you able to modify blocklayered.php so that we can access the product's "feature" that is called "Minimum Order". This is my ideal scenario.

 

Thanks for any thoughts,

Kent

Link to comment
Share on other sites

Hi Kent,

 

Which version of Prestashop are you using? I believe by mimimum order you were referring to "minimum quantities" under Products -> Quantites. If that is the case, I don't think that is exactly what you're looking for.

 

I haven't set up packs myself on a production server but this is how I think it works in 1.5.4.1:

 

Imagine 1 item costs $5

 

Setting a minimum quantity sets in stone a minimum number of items that may be ordered. For example, if you say 6 items is the minimum at $2 a piece, the customer can still order 7 or 100 of that item at $2 a piece, even though a 12 pack may be only $1.50 a piece (so you might get some unhappy customers).

 

It sounds like you in fact wanted to set up packs (Product->information->Type->Pack) of the item e.g. product_id 2 is a 6 pack and products_id 3 is a 12 pack of product_id 1, respectively.

 

This doesn't prevent you from adding "specific prices" (products->prices->specific prices) for individual product_id 1 as you buy multiple. e.g. you could say 60% off for 6 or more and set 80% for 12 or more. Depending on your template, this should show up on screen. The catch is that you will have to manually calculate and input the cost "per item" for all packs and products (which I can hack for the layered navigation price slider to be used for displaying per item prices rather than per pack).

 

Whether you could avoid packs altogether and display package deals with the layered slider system is another issue. By default Prestashop doesn't even include the discounts in the price search (which I released a hack for just yesterday), let alone a range of quantity-dependent discounts.

 

Cheers

Link to comment
Share on other sites

Hi,

 

If you still think you need the modified slider I can post the 1.5.4.1 version here when I get the chance. You'd want to modify product-list.tpl in your theme as well so that unit prices are listed. I've made it so that if unit prices are not entered a product is considered to be a single unit. For packs you would have to manually enter the initial unit prices (which can be reduced just like any other product).

 

Note that I've modified the slider somewhat to my tastes (e.g. no steps below 1 "dollar", no price values outside range).

 

Cheers

Link to comment
Share on other sites

Emzed,

 

I would be so grateful if you could post that. I actually hired some developers to help me with this and they are breaking the store in the process. So, I would be so thankful it if you could post a working version.

 

I promise, in the name of karma, that I will give back.

 

Cheers!!!

Link to comment
Share on other sites

Hi Kent,

 

Admittedly my version is also un-tested and is based on the modified price slider I published yesterday on the forum (http://www.prestashop.com/forums/topic/272474-layered-navigation-price-range-with-specific-prices/?do=findComment&comment=1394663). As I mentioned previously, I've changed some important functions to get price reductions recognised foremost and for my own sanity I've made the slider range stricter and more consistent for smaller amounts. While it works in my 1.5.4.1 development setup with actual products under various scenarios I haven't tested it with all features applied. The functions I've changed only set data in a blocklayered module's table, so while core data tables shouldn't be disturbed I still hope you back up and test on a development server with actual scenarios.

 

These are modified files from blocklayered in PS1.5.4.1, since it's the version I'm most familiar with bug-wise and experience-wise.

 

blocklayered.php - This version did not work without taxes

 

19Oct2013-blocklayered.php - Rename to blocklayered.php

 

blocklayered.tpl.txt - Remove the .txt extension

 

Depending on your theme you'll want to add the unit price in the product list. You can put it where you want but make sure all the conditional clauses are set appropriately (i.e. not if in catalog mode, show prices is set, available for order, you have unity and unit_price_ratio as I lay out so as not to break display rules). In the default template's product-list.tpl where you have this:

{if (!$PS_CATALOG_MODE AND ((isset($product.show_price) && $product.show_price) || (isset($product.available_for_order) && $product.available_for_order)))}

<div class="content_price">

{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}

{if isset($product.available_for_order) && $product.available_for_order && !isset($restricted_country_mode)}<span class="availability">{if ($product.allow_oosp || $product.quantity > 0)}{l s='Available'}{elseif (isset($product.quantity_all_versions) && $product.quantity_all_versions > 0)}{l s='Product available with different options'}{else}{l s='Out of stock'}{/if}</span>{/if}

</div>
				
{if isset($product.online_only) && $product.online_only}<span class="online_only">{l s='Online only'}</span>{/if}

{/if}

you could add the following lines or similar to the div:

{if !empty($product.unity) && $product.unit_price_ratio > 0.000000}{math equation="pprice / punit_price"  pprice=$product.price  punit_price=$product.unit_price_ratio assign=unit_price}<span id="unit_price_display">{convertPrice price=$unit_price} {l s='per'} {$product.unity|escape:'htmlall':'UTF-8'}</span>{/if}

{if empty($product.unity) && $product.unit_price_ratio == 0.000000}<span id="unit_price_display">{convertPrice price=$product.price}{l s=' per item'}</span>{/if}

Note that I automatically gave an amount per item where no unit price ratio or unit value has been set.

 

Cheers

 

Edited by Emzed (see edit history)
  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

Hello ,

I also confirm that it works (prestashop 1.5.4) . Thank you very much for this contribution !

Anyway, i have a question in relation with this solution.

 

In fact, I have a problem with the field "sort by".

 

I display my products using the unit price (price depends by square meters).

When I want to display my products by price asc or desc, my products are classified with the sales price but not with the unit price.
 

I know that is the classic behavior of prestashop but when i want to manage product with unit price, this behavior is not good in my case.

 

Is it possible to sort products depend by unit price and not by sales price with this field ?
 

Any help would be really appreciated !

 

PS: you have a screenshot for better understanding

 

Thanks you very much !

post-329857-0-62016400-1381421971_thumb.jpg

Edited by vincegx (see edit history)
Link to comment
Share on other sites

Hi vincegx,

 

Since my unit-price modification was implemented as a quick hack rather than a new feature (the table structure of ps_layered_price_index hasn't been modified) the function you require isn't readily accessible, but can be introduced.

 

Prestashop uses the Tools::orderbyPrice comparison function to sort prices after statically extracting the prices (per product id) from the database by calling the Product::getPriceStatic function, which in turn calls Product::priceCalculation. Ideally, you could make your own version of priceCalculation (say, priceCalculationForUnitSort) strictly for the sorting function where you divide the final $price variable by $row['unit_price_ratio'] (already called from product_shop) if unit_price_ratio > 0 (and I guess create a separate cache name in the function to avoid conflict with the actual non-unit price). You could name getPriceStatic something like getPriceStaticByUnit and change it to this in Tools::orderbyPrice. If you still wanted order by price you would make even more changes, such as changing Tools::orderbyPrice to a new name and calling it from blocklayered.php's getProductByFilters function near the end where you've changed your tpl template dropdowns to create specific get requests for unit price.

e.g. in blocklayered.php something like

if (Tools::getProductsOrder('by', Tools::getValue('orderby'), true) == 'p.unit_price')
			Tools::orderbyPrice($this->products, Tools::getProductsOrder('way', Tools::getValue('orderway')));

where you add unit_price as an option in Tools::getProductsOrder and your template creates unit_price as the GET variable.

 

Alternatively, you could rely on a pre-indexed table as done for the layered_price_index but you'll have to ensure this table is always up to date to avoid strange sorting behaviour (you'd want to keep layered indexes up to date anyway to filter correctly).

 

We could use the existing ps_layered_price_index table but the problem is that the price_min/price_max have been converted to integers for the module. You could create new columns without integer rounding if you don't mind modifying default table structure.

 

If you don't care about cents here's a quick explanation of how you can use the existing price_max in the layered price index to sort by unit price.

 

In blocklayered.php in the last big query of getProductByFilters ($this->products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS etc) you can add a select of

 

psi.price_max as unit_price_ceiling,

 

and then a LEFT JOIN such as 

 

LEFT JOIN '._DB_PREFIX_.'layered_price_index psi ON (psi.id_product = p.id_product AND psi.id_shop = '.(int)Context::getContext()->shop->id.' AND psi.`id_currency` = '.$id_currency.')

 

Then in classes/Tools.php in the orderbyPrice function you can replace

 

$row['price_tmp'] = Product::getPriceStatic($row['id_product'], true, ((isset($row['id_product_attribute']) && !empty($row['id_product_attribute'])) ? (int)$row['id_product_attribute'] : null), 2);

 

with

 

$row['price_tmp'] = $row['unit_price_ceiling'];

 

Keep in mind this will still look a little unusual since something like $5.30 can appear before $5.90 due to the ceiling rounding within the table.

 

Cheers

Link to comment
Share on other sites

  • 2 weeks later...

New version is available for download above (19Oct2013-blocklayered.php). It now works when taxes haven't been added.

 

Kent, please try the latest version.

 

vincegx, I know you've already paid a freelancer to make some sorting changes to the original modification but you can use a tool like quickdiff.com to see the new changes to the updated file.

Edited by Emzed (see edit history)
Link to comment
Share on other sites

Hi Emzed,

 

Thanks for this. I will give it a try.

 

However, I was able to get the previous version to work when I turned of taxes at the module indexing stage.

 

With this update to the pho file, taxes appear.

'.(int)$min_price[$currency['id_currency']].',
'.(int)Tools::ceilf($max_price[$currency['id_currency']] * (100 + $max_tax_rate) / 100, 0).')';


//change to


'.(int)(1.13 * $min_price[$currency['id_currency']]).',
'.(int)Tools::ceilf(1.13 * $max_price[$currency['id_currency']] * (100 + $max_tax_rate) / 100, 0).')';

Thanks again for your hard work on this. This code that you have provided is a huge update to Prestashop, as far as I'm concerned.

 

Thanks again,

Kent

Link to comment
Share on other sites

  • 1 year later...
  • 1 year later...
  • 1 year later...

Hi !

 

I am using prestashop 1.6.1.1.

I found on the forum how to show unit price in the product-list.

But I am searching how to make the price slider in the blocklayered work by "unit price" instead of product price...

Any idea ?

 

I too am looking for this exact same thing. I've searched everywhere online with no success.

 

Here is my site:

https://floorsunlimited.com/prefinished-flooring-products

 

As you can see I am using Retail Price and Unit Price

I'm selling flooring where the Unit price = "SQFT Price" and the Retail Price = "Box Price"

Each product has a specific number of SQFT per box (unit_price_ratio)

 

I'd like my main pricing to show the Unit Price (SQFT Price) like it does on most of the site.

So having BlockLayered Showing the Retail Price (Box Price) in the Min/Max doesn't help at all.

 

Please someone guide me how to accomplish this.

 

Eric

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...