En este tutorial vamos a ver cómo deshabilitar un método de pago específico para productos virtuales en Prestashop.
Si estamos vendiendo en nuestra tienda productos virtuales, no tendría sentido habilitar, por ejemplo, el método de pago Contra reembolso, pues el cliente podría descargar el producto virtual inmediatamente después de realizar el pago.
Debemos tener en cuenta que las modificaciones que vamos a hacer deben ser aplicados sobre el módulo que queremos deshabilitar.
Para ello deberemos editar el archivo principal del módulo en cuestión, se llama igual que el módulo y tiene extensión .php.
Compatibilidad: Prestashop 1.5 y
Prestashop 1.6
En versiones iguales o superiores a Prestashop 1.6.0.11, es posible hacer override sobre el archivo principal del módulo. Si tenéis una versión anterior deberéis hacer la modificación sobre el archivo principal del módulo original. En esta ocasión lo haremos mediante un override.
Si queréis aprender a hacer override sobre los archivos principales del los módulos, echarle un vistazo al tutorial Override sobre los módulos a partir de Prestashop 1.6.0.11.
El método hookPayment
La forma más sencilla de deshabilitar un método de pago es modificar el método denominado hookPayment, utilizado por todos los módulos de pago único en Prestashop. Este método es el responsable de mostrar los modos de pago durante el proceso de compra, por lo que deshabilitando alguno de ellos evitaremos que los usuarios de nuestra tienda efectúen la compra con ellos.
Usaremos el módulo cashondelivery, pero podemos hacerlo con cualquier otro siguiendo el mismo procedimiento. Como los módulos no estándar pueden tener sus propias reglas, es mejor añadir nuestras líneas de código al principio del método.
Modificando el archivo principal del módulo
Como he mencionado anteriormente, vamos a hacer un override sobre el módulo cashondelivery. Recordemos que solo es posible el override sobre los módulos a partir de la versión Prestashop 1.6.0.11. De tener esta versión o superior debemos crear una carpeta llamada cashondelivery en ../prestashop/override/modules.
Ahora debemos crear un archivo php llamado cashondelivery.php, y colocarlo en la carpeta cashondelivery. Debemos pegar el siguiente código en el archivo cashondelivery.php:
<?php if (!defined('_PS_VERSION_')) exit; class CashOnDeliveryOverride extends CashOnDelivery { }
Hecho esto tomemos el método hookPayment del módulo original, ubicado en ../prestashop/modules/cashondelivery/cashondelivery.php
Busquemos esta función, copiarla y pegarla en nuestro override:
public function hookPayment($params) { if (!$this->active) return ; global $smarty; // Check if cart has product download $i = 0; $products = $params['cart']->getProducts(); $total = count($products); foreach ($products as $key => $product) { $pd = ProductDownload::getIdFromIdProduct((int)($product['id_product'])); if ($pd AND Validate::isUnsignedInt($pd)) $i++; } if ($i && $total == $i) return false; $smarty->assign(array( 'this_path' => $this->_path, //keep for retro compat 'this_path_cod' => $this->_path, 'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/' )); return $this->display(__FILE__, 'payment.tpl'); }
De forma que quede así.:
<?php if (!defined('_PS_VERSION_')) exit; class CashOnDeliveryOverride extends CashOnDelivery { public function hookPayment($params) { if (!$this->active) return ; global $smarty; // Check if cart has product download $i = 0; $products = $params['cart']->getProducts(); $total = count($products); foreach ($products as $key => $product) { $pd = ProductDownload::getIdFromIdProduct((int)($product['id_product'])); if ($pd AND Validate::isUnsignedInt($pd)) $i++; } if ($i && $total == $i) return false; $smarty->assign(array( 'this_path' => $this->_path, //keep for retro compat 'this_path_cod' => $this->_path, 'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/' )); return $this->display(__FILE__, 'payment.tpl'); } }
El código que vamos a insertar...
$products = $this->context->cart->getProducts(); if($products) { foreach ($products as $product) { if ($product['is_virtual']) { return false; } } }
Analicemos este último fragmento, el cual debemos insertar al inicio del método hookPayment.
Como podemos observar, mediante la variable $products comprobamos si hay productos en el carro. A continuación hacemos un recorrido mediante foreach para comprobar qué productos son virtuales. En el caso de que hubiese algún producto virtual en el carrito no se mostraría el módulo.
Podemos además mostrar un texto informativo como este, es una sugerencia, esto ya depende los gustos de cada uno. En este caso podríamos utilizar este código:
$products = $this->context->cart->getProducts(); if($products) { foreach ($products as $product) { if ($product['is_virtual']) { $texto = 'Tiene en su cesta un producto virtual (no físico). En este caso el método de pago Contra reembolso no se encuentra disponible. Si tiene en su carrito productos virtuales y físicos, puede finalizar la compra de sus productos virtuales por separado, y a continuación iniciar otro carrito con sus productos físicos.
'; return $texto. false; } } }
El código final
Este sería el código final:
<?php if (!defined('_PS_VERSION_')) exit; class CashOnDeliveryOverride extends CashOnDelivery { public function hookPayment($params) { $products = $this->context->cart->getProducts(); if($products) { foreach ($products as $product) { if ($product['is_virtual']) { $texto = 'Tiene en su cesta un producto virtual (no físico). En este caso el método de pago Contra reembolso no se encuentra disponible. Si tiene en su carrito productos virtuales y físicos, puede finalizar la compra de sus productos virtuales por separado, y a continuación iniciar otro carrito con sus productos físicos.
'; return $texto. false; } } } if (!$this->active) return ; global $smarty; // Check if cart has product download $i = 0; $products = $params['cart']->getProducts(); $total = count($products); foreach ($products as $key => $product) { $pd = ProductDownload::getIdFromIdProduct((int)($product['id_product'])); if ($pd AND Validate::isUnsignedInt($pd)) $i++; } if ($i && $total == $i) return false; $smarty->assign(array( 'this_path' => $this->_path, //keep for retro compat 'this_path_cod' => $this->_path, 'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/' )); return $this->display(__FILE__, 'payment.tpl'); } }
Por último el código CSS para dar formato, y que podemos incluir en el archivo ../prestashop/themes/nuestro-tema/css/global.css
div#HOOK_PAYMENT p.no-disponible { margin: 10px 0; font-size:16px; line-height:1.5em; font-weight:bold; background-color:rgb(251, 251, 251); padding:33px 40px 34px 16px; border:1px solid rgb(214, 212, 212); border-radius:4px; -webkit-border-radius:4px; -moz-border-radius:4px; }
El resultado final debería quedarnos más o menos así:
Hola gracias por el genial tutorial, funciona genial en virtuales, pero no logro identificar el valor is_virtual en vez de virtual para un producto standart
ResponderEliminarGracias ya lo he solucionado
ResponderEliminar