Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom price calculation in prestashop

I'm working on a Prestashop 1.5.x website, where I need to add a custom price-calculation rule for a specific product. My goal is to add 10 dollars per order, but PS adds extra cost by product quantity, so if you order 20 products it ask you 200$ instead of 10... I need to override the calculating process in /classes/Product.php, with something like:

if (product_id = 44) { $price = $price + 10; }
else { $price = $price }

Have you got any idea?

like image 712
Fabio Avatar asked Jan 16 '15 17:01

Fabio


1 Answers

You have to create an override of the Product class in prestashop. To do so, create a new file in override/classes called Product.php and put this code in it :

<?php
class Product extends ProductCore
{
    // Here we will put every method or property override
}

In this class, you will copy / paste the static method priceCalculation (it's at line 2567 of original Product.php file for me). When done, just add these lines at the end of the method, just before the self::$_prices[$cache_id] = $price; :

    if ($id_product == 44 && Context::getContext()->customer->isLogged()) {
        $customer = Context::getContext()->customer;

        $nbTimesBoughtThisProduct = (int) Db::getInstance()->getValue('
            SELECT COUNT(*)
            FROM `' . _DB_PREFIX_ . 'product` p
            JOIN `' . _DB_PREFIX_ . 'order_detail` od
            ON p.`id_product` = od.`product_id`
            JOIN `' . _DB_PREFIX_ . 'orders` o
            ON od.`id_order` = o.`id_order`
            WHERE o.`id_customer` = ' . $customer->id . '
            AND p.`id_product` = ' . $id_product . '
        ');

        $price += $nbTimesBoughtThisProduct * 10;
    }

I did not have the time to test these, but I think that's the way to do what you want to do.

priceCalculation is the method called each time Prestashop needs a product's price. By putting this code at the end of this method, we modify the returned price.

The code first checks if the customer is logged (we can't get orders from him if he is not). If so, a query retrieves the amount of times this customer bought this product in the past. This number is multiplied by ten, and the value is added to the price.

EDIT: If, as Cyril Tourist said, you want to also count the current cart, get this new code (still not tested, but should work) :

    if ($id_product == 44 && Context::getContext()->customer->isLogged()) {
        $customer = Context::getContext()->customer;

        $nbTimesBoughtThisProduct = (int) Db::getInstance()->getValue('
            SELECT COUNT(*)
            FROM `' . _DB_PREFIX_ . 'product` p
            JOIN `' . _DB_PREFIX_ . 'order_detail` od
            ON p.`id_product` = od.`product_id`
            JOIN `' . _DB_PREFIX_ . 'orders` o
            ON od.`id_order` = o.`id_order`
            WHERE o.`id_customer` = ' . $customer->id . '
            AND p.`id_product` = ' . $id_product . '
        ');

        $productsInCart = Context::getContext()->cart->getProducts();

        foreach ($productsInCart as $productInCart) {
            if ($productInCart['id_product'] == 44) {
                $nbTimesBoughtThisProduct++;
            }
        }

        $price += $nbTimesBoughtThisProduct * 10;
    }

Also, I advice you to store the "44" product ID in a constant, configuration variable, or anything, but not keeping it in the code like that. I did that just for the example.

like image 138
Lily Bergonzat Avatar answered Sep 27 '22 20:09

Lily Bergonzat