Ordenar los productos por los más vendidos en Prestashop

En nuestros últimos proyectos de diseño y desarrollo de tienda online sobre Prestashop, hemos tenido que mejorar la vista de categorías de productos para incluir una ordenación de los más vendidos y menos vendidos.

Las redes sociales son importantes para el SEO


Para ello deberemos realizar un desarrollo haciendo override a las funciones y clases establecidas en la versión de Prestashop.

Comenzaremos añadiendo en nuestro Theme dentro del archivo product-sort.tpl las líneas que necesitamos. De este modo, trabajando sobre un desarrollo propio del Theme, no tendremos que preocuparnos de futuras actualizaciones de versiones en Prestashop.

<option value="sales:desc" {if $orderby eq 'sales' AND $orderway eq 'desc'}selected="selected"{/if}>{l s='Más Vendidos'}</option>

<option value="sales:asc" {if $orderby eq 'sales' AND $orderway eq 'asc'}selected="selected"{/if}>{l s='Menos vendidos'}</option>


Crearemos un fichero dentro de la carpeta raíz llamada override, y dentro, una llamada class y, en ella, crearemos el fichero category.php.

Las redes sociales son importantes para el SEO


El fichero deberá extender la class Categoría y remplazar la función getProducts, para poder incluir nuestra cláusula de order by.

<?php

Class Category extends CategoryCore

{public function getProducts($id_lang, $p, $n, $order_by = null, $order_way = null, $get_total = false, $active = true, $random = false, $random_number_products = 1, $check_access = true, Context $context = null){          if (!$context) {

$context = Context::getContext();           }              if ($check_access && !$this->checkAccess($context->customer->id)) {

return false;       }              $front = in_array($context->controller->controller_type, array('front', 'modulefront'));                $id_supplier = (int)Tools::getValue('id_supplier');            /** Return only the number of products */         if ($get_total) {

$sql = 'SELECT COUNT(cp.`id_product`) AS total FROM `'._DB_PREFIX_.'product` p                '.Shop::addSqlAssociation('product', 'p').'            LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON p.`id_product` = cp.`id_product`              WHERE cp.`id_category` = '.(int)$this->id.

($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '').

($active ? ' AND product_shop.`active` = 1' : '').

($id_supplier ? 'AND p.id_supplier = '.(int)$id_supplier : '');

return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);      }              if ($p < 1) {

$p = 1;  }                              /** Tools::strtolower is a fix for all modules which are now using lowercase values for 'orderBy' parameter */ $order_by  = Validate::isOrderBy($order_by)   ? Tools::strtolower($order_by)  : 'position';                $order_way = Validate::isOrderWay($order_way) ? Tools::strtoupper($order_way) : 'ASC';                                         $order_by_prefix = false;            if ($order_by == 'id_product' || $order_by == 'date_add' || $order_by == 'date_upd') {

$order_by_prefix = 'p';  } elseif ($order_by == 'name') {

$order_by_prefix = 'pl'; } elseif ($order_by == 'manufacturer' || $order_by == 'manufacturer_name') {

$order_by_prefix = 'm';

$order_by = 'name';       } elseif ($order_by == 'position') {

$order_by_prefix = 'cp';               }              if ($order_by == 'price') {

$order_by = 'orderprice';             }              $nb_days_new_product = Configuration::get('PS_NB_DAYS_NEW_PRODUCT');                if (!Validate::isUnsignedInt($nb_days_new_product)) {

$nb_days_new_product = 20;    }              $sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) AS quantity'.(Combination::isFeatureActive() ? ', IFNULL(product_attribute_shop.id_product_attribute, 0) AS id_product_attribute,   product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity' : '').', pl.`description`, pl.`description_short`, pl.`available_now`,          pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, image_shop.`id_image` id_image,                il.`legend` as legend, m.`name` AS manufacturer_name, cl.`name` AS category_default,                DATEDIFF(product_shop.`date_add`, DATE_SUB("'.date('Y-m-d').' 00:00:00",       INTERVAL '.(int)$nb_days_new_product.' DAY)) > 0 AS new, product_shop.price AS orderprice,  IFNULL(NULLIF(ps.quantity,"" ), 0) AS salesFROM `'._DB_PREFIX_.'category_product` cpLEFT JOIN `'._DB_PREFIX_.'product` p    ON p.`id_product` = cp.`id_product`'.Shop::addSqlAssociation('product', 'p').              (Combination::isFeatureActive() ? ' LEFT JOIN `'._DB_PREFIX_.'product_attribute_shop` product_attribute_shopON (p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context->shop->id.')':'').''.Product::sqlStock('p', 0).'LEFT JOIN `'._DB_PREFIX_.'category_lang` cl            ON (product_shop.`id_category_default` = cl.`id_category`         AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')LEFT JOIN `'._DB_PREFIX_.'product_lang` pl    ON (p.`id_product` = pl.`id_product`              AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').')LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id.')LEFT JOIN `'._DB_PREFIX_.'image_lang` il                ON (image_shop.`id_image` = il.`id_image`         AND il.`id_lang` = '.(int)$id_lang.')LEFT JOIN `'._DB_PREFIX_.'manufacturer` m            ON m.`id_manufacturer` = p.`id_manufacturer`LEFT JOIN '._DB_PREFIX_.'product_sale ps               ON ps.id_product = product_shop.id_productWHERE product_shop.`id_shop` = '.(int)$context->shop->id.'       AND cp.`id_category` = '.(int)$this->id

.($active ? ' AND product_shop.`active` = 1' : '')

.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '')

.($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : '');

if ($random === true) {$sql .= ' ORDER BY RAND() LIMIT '.(int)$random_number_products;

} else {$sql .= ' ORDER BY '.(!empty($order_by_prefix) ? $order_by_prefix.'.' : '').'`'.bqSQL($order_by).'` '.pSQL($order_way).'

LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n;

}

$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql, true, false);

if (!$result) {return array();

}

if ($order_by == 'orderprice') {Tools::orderbyPrice($result, $order_way);

}

/** Modify SQL result */

return Product::getProductsProperties($id_lang, $result);}

}

?> 

Una vez realizado deberemos borrar nuestro archivo cache/class_index.php y con esto habremos añadido la posibilidad de mostrar a nuestros visitantes qué productos son los más vendidos y por tanto, indirectamente, los más recomendados por el resto de los clientes. 

Si tenéis una tienda online y no tenéis la opción de mostrar así vuestros productos pero no os atrevéis a realizar lo que os hemos explicado, podéis contactar con el equipo de desarrollo de digitalDot y estarán encantados de solucionároslo.