Envío gratis por producto prestashop

Buenos días, Aquí os dejo un pequeño manual para poder hacer Envío gratis por producto prestashop a través de la base de datos el envío gratis a 1 solo producto de prestashop, funciona correctamente. Muchas gracias a laproteina por permitir publicar este artículo creado por él. 1º Añadir un campo en la tabla products que se llama envio_gratis , es un campo tinyint(1) unsigned que puede ser nulo pero con valor por defecto 0. Si el valor se asigna a 1 este producto implicara los gastos de envío gratis. 2º Modificaciones en las clases(carpeta classes): Product.php, añadir después de

/*** @var array Tags */
public      $tags;

esto otro

Código:
//para los articulos con envio gratuito
/** @var boolean Product statuts */
public $envio_gratis = 0;

y despues de

Código:
$fields['date_upd'] = pSQL($this->date_upd);

añadir este otro codigo

Código:
$fields['envio_gratis'] = pSQL($this->envio_gratis);

El cambio de este archivo creo que no es necesario tal y como lo tengo yo pero si creo que lo sera para poder modificar esta funcionalidad desde el Back Office Y tambien modificar la clase Cart.php , para ser mas precisos dentro de la funcion getOrderShippingCost Os dejo el trozo que estaba antes

Código:
function getOrderShippingCost($id_carrier = NULL, $useTax = true)
{
global $defaultCountry;

if ($this->isVirtualCart())
return 0;

// Checking discounts in cart
$products = $this->getProducts();
$discounts = $this->getDiscounts(true);
if ($discounts)
foreach ($discounts AS $id_discount)
{
$discount = new Discount(intval($id_discount['id_discount']));
if (!Validate::isLoadedObject($discount))
die(Tools::displayError());
if ($discount->id_discount_type == 3)
{
$total_cart = 0;
$categories = Discount::getCategories($discount->id);
foreach($products AS $product)
{
if(count($categories))
if (Product::idIsOnCategoryId($product['id_product'], $categories))
$total_cart += $product['total_wt'];
}
if ($total_cart >= $discount->minimal)
return 0;
}
}

y el que debeis dejar

Código:
function getOrderShippingCost($id_carrier = NULL, $useTax = true)
{
global $defaultCountry;

if ($this->isVirtualCart())
return 0;

// Checking discounts in cart
$products = $this->getProducts();
$discounts = $this->getDiscounts(true);
if ($discounts)
foreach ($discounts AS $id_discount)
{
$discount = new Discount(intval($id_discount['id_discount']));
if (!Validate::isLoadedObject($discount))
die(Tools::displayError());
if ($discount->id_discount_type == 3)
{
$total_cart = 0;
$categories = Discount::getCategories($discount->id);
foreach($products AS $product)
{
if(count($categories))
if (Product::idIsOnCategoryId($product['id_product'], $categories))
$total_cart += $product['total_wt'];
}
if ($total_cart >= $discount->minimal)
return 0;
}
}
// Inicio modificacion
//Si hay algun producto con gastos de envio gratis ya devuelvo cero
$fila = Db::getInstance()->getRow('
SELECT count(*) AS nb
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p ON cp.`id_product` = p.`id_product`
WHERE p.`envio_gratis` = 1 AND cp.`id_cart` = '.intval($this->id));
if (intval($fila['nb']) > 0)
return 0;
//$this->_nb_products = intval($row['nb']);
// fin modificacion

Con esto ya se obtiene el articulo que deja el pedido sin gastos de envio, pero aun he modificado otra Envío gratis por producto prestashop, la siguiente cosa: en el resumen del pedido hay un texto donde sale el dinero que falta para obtener el envio gratuito, si no tocamos algo mas, este texto va a seguir saliendo confundiendo al cliente pues por un lado sale que tiene envio gratuito y por otro lado le dice que aun le falta para conseguirlo. Asi que hay que tocar el archivo Order.phpque se encuentra en el directorio raiz de nuestra tienda Prestashop Buscad el trozo de codigo que pone:

Código:
  if ($free_ship = intval(Configuration::get('PS_SHIPPING_FREE_PRICE')))
{
$discounts = $cart->getDiscounts();
$total_free_ship =  $free_ship - ($summary['total_products_wt'] + $summary['total_discounts']);
foreach ($discounts as $discount)
if ($discount['id_discount_type'] == 3)
{
$total_free_ship = 0;
break ;
}
$smarty->assign('free_ship', $total_free_ship);
}

Y cambiarlo por este otro:

Código:
if ($free_ship = intval(Configuration::get('PS_SHIPPING_FREE_PRICE')))
{
$discounts = $cart->getDiscounts();
// Si los gastos de envio son mayores que cero pues miro a ver si hay otros descuentos
// si los gastos de envio ya son cero pues pongo a cero la variable que controla si debe salir
// el texto de lo que falta para conseguir los gastos de envio gratuitos
if ($summary['total_shipping'] > 0) {
$total_free_ship =  $free_ship - ($summary['total_products_wt'] + $summary['total_discounts']);
foreach ($discounts as $discount)
if ($discount['id_discount_type'] == 3)
{
$total_free_ship = 0;
break ;
}
}
else
$free_ship = 0;
$smarty->assign('free_ship', $total_free_ship);
}

Texto descriptivo indicando que el articulo tiene los gastos de envío gratuitos: En el directorio donde se encuentran los archivos tpl de nuestro tema cambiar En product.tplpara que en la pantalla del producto salga indicado esta oferta Donde ponia:

Código:
         

{if $product->on_sale} {l s=’On sale’} {l s=’On sale!’} {elseif ($product->reduction_price != 0 || $product->reduction_percent != 0) && ($product->reduction_from == $product->reduction_to OR ($smarty.now|date_format:’%Y-%m-%d’ reduction_to && $smarty.now|date_format:’%Y-%m-%d’ >= $product->reduction_from))} {l s=’Price lowered!’} {/if}

Cambiarlo por

Código:

{if $product->envio_gratis} {l s=’Producto con envio gratis!’} {/if} {if $product->on_sale} {l s=’On sale’} {l s=’On sale!’} {elseif ($product->reduction_price != 0 || $product->reduction_percent != 0) && ($product->reduction_from == $product->reduction_to OR ($smarty.now|date_format:’%Y-%m-%d’ reduction_to && $smarty.now|date_format:’%Y-%m-%d’ >= $product->reduction_from))} {if $product->envio_gratis} {/if} {l s=’Price lowered!’} {/if}

Pero tambien hay que hacer que en el listado de articulos se vea que estos tienen la oferta asi que en product-list.tplDonde ponia:

Código:
{if $product.on_sale}

Poner esto:

Código:
{if $product.envio_gratis} {l s=’Producto con envio gratis!’} {/if} {if $product.on_sale}

Listo!!! –> Envío gratis por producto prestashop GENERADO!

Un saludo y gracias!

¿Te ha gustado el artículo?
Sé el primero en calificar esta publicación.
1 Star2 Stars3 Stars4 Stars5 Stars
Loading...
Artículo escrito por

¡Exprésate! Dejanos tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

28 Comentarios

Cralos

Hola! Es válido este post para PS 1.6.0.1  ?? He estado intentándolo pero los archivos no son iguales y no encuentro donde poner el código. Gracias!

Manuel

Hola buenos días, tengo problemas en encontrar partes del codigo en la version 16.1.1 tengo el transporte por rangos de peso. Entiendo que si en el carrito añades un producto de envío gratis y uno que no tiene envío gratis, que se debe cobrar el envío como es logico. Quisiera saber si funcionaria en prestashop 16.1.1 agradecería enormemente si me pudieras responder esto, estoy muy interesado. Muchisimas gracias de antemano

Ivanova Sosa

Hola buenos días, tengo el mismo problema que pilar, yo configuré la tienda para que el transporte lo tome por rangos de peso, pero necesito que sólo para los productos de una marca el envío sea gratis. Si en el carrito compras un producto de envío gratis y uno que no tiene envío gratis, que se debe cobrar el envío Si sólo compra productos de X marca que tiene envío gratis, entonces el envío sale gratis. Quisiera saber si lograste hacer la modificación al código ya que veo que el contenido de la publicación no ha cambiado, agradecería enormemente si me pudieras responder esto. Muchisimas gracias de antemano

Miren

Hola:   Estoy intrigada pro la ampliación del manual que le anunciaste a la pregunta de Pilar Bosch arriba, el 17/04/2013. Mi caso es muy parecido, solo que además yo quiero ofrecer gestos de envíos diferents según el producto, y que además en caso de coincidir dos productos de distinto coste de envio en la misma cesta, prevalezca el coste de envio que yo determine como standar, que será el más alto. al final no se si lo pudiste hacer .Te agradecería me avisases por correo... gracias!!  

Óscar

Muy buenas, tengo una pregunta, mi mejor opción es poner un coste de envío fijo para cada producto y al superar los 25€ de porte convertir el pedido a envío gratuito, esto es necesario hacerlo a través de código, no hay en Prestashop ninguna opción que permita poner precios de envíos fijos por categorias??, gracias de antemano

Pilar Bosch

Hola, si así es eso es lo que necesito, te estaría inmensamente agradecida si hicieras eso, la verdad que llevo bastante tiempo intentando hacerlo pero no se como. La versión de Prestashop para la que quiero la modificación es la 1.4.8.2 y muchiiisimas gracias por todo, te estoy muy agradecida de verdad. Saludos!

Rubén Muñoz Autor

Vale Pilar, ahora creo que si te he entendido bien :D Habría que hacer una modificación al código para que detecte: 1- Si hay productos con envío gratis --> Gratis 2- Si hay productos con envío gratis y productos que no tienen envío gratis y la cantidad total del carrito es menor de 120€ --> Cobra Envío 3- Si hay productos con envío gratis y productos sin envío gratis, pero el pedido es superior a 120€ --> No cobres envío. Según lo que tú me comentas, veo que la tercera opción la tienes cubierta con prestashop que era lo que yo te decía con las opciones de transporte. La primera opción también la tienes cubierta con el manual del que estamos hablando más arriba. Ahora te falta la segunda :D, esto será una modificación seguramente en el cart.php, voy a intentar sacar un hueco de "donde pueda" y te comento la posible solución y actualizo el manual. ¿Es así verdad?

Pilar Bosch

Hola Ruben, siento si no me explicado bien, voy a intentar hacerlo, tengo una tienda que tiene todos los productos con gastos de envío, y en transporte tengo configurada una franja que a partir de 120 euros los gastos de envío son gratis. Ahora bien, quiero meter en la tienda unos productos que no tienen que llevar gastos de envío si compras solo ese producto, pero si añades algún otro producto que si tiene gastos de envío entonces si que tienen que llevar gastos de envío. El problema lo tengo en que si añado ese producto al carrito ( el que no lleva gastos de envío) el carrito marca sin gastos de envío Y si el cliente añade otro producto que si lleva gastos de envío el carrito sigue mostrando gastos de envío 0 al haber añadido el producto anterior. Yo lo que quiero que el producto en cuestión (al que le he hecho la modificación que muestras arriba ) cuando se compre ese solo, no lleve gastos de envío pero si se compra junto a otro producto distinto entonces si se cobren los gastos de envío. Como crees que puedo lograrlo, te agradezco mucho tu ayuda. Espero haberme explicado bien. Saludos!  

Rubén Muñoz Autor

Hola Pilar, Lo primero te voy a pedir disculpas, es un artículo que hace bastante tiempo que escribí y la verdad no lo recuerdo muy bien. Pero voy a intentar solucionar lo mejor que pueda el asunto. Vale, si realizas las modificación por producto que hay en el artículo, debería de funcionar como tu dices. Si tengo productos con gasto de envío asociado, siempre aparecerá en el carrito de la compra unos gastos de envío asociados. Si no tengo productos con gastos de envío, tendrías que configurar el sistema de transporte o de envíos en el prestashop, para definir que reglas tienes para que no exista gastos de envío, por ejemplo con gastos superiores a 20€ o no hay gastos de envío en ningún caso. Si seleccionas que no existen gastos de envío en ningún caso, nunca los habrá salvo en el caso de que incluyan un producto que tenga la modificación de código que propone el artículo. ¿Es así como quieres que funcione?

Pilar Bosch

Hola Rubén, gracias por responder, no sé si te he entendido bien, dices que pruebe con la configuración de transporte del back-office para conseguir  que: cuando compras un producto con gastos de envío y otro sin,  siempre haya gastos de envío y cuando compras solo el producto sin gastos de envío se quede tal cual. Podrías especificar un poco más que tendría que hacer? te lo agradezco mucho. Un saludo!  

Rubén Muñoz Autor

Hola Pilar, si se podría hacer pero hay que combinar este código con la parte de envíos o transportistas de prestashop. Ahora mismo no puedo realizar las pruebas necesarias, pero te insto a que analices la manera de combinarlo con las reglas de transporte que tengas en tu administración. Si encuentras una solución por favor, compártela con nosotros. un saludo

Pilar Bosch

Buenas tardes, he probado vuestro tutorial, y funciona,  pero comprando un artículo sin gastos de envío y otro con gastos de envío te sigue saliendo gratis el envío, no se podría modificar para que si compras un artículo con portes gratis y otro que no, si que te cobrara los portes, y si compras solo el de envío gratis entonces no lo cobrara. No se si me he explicado con claridad, muchas gracias anticipadas y un saludo.  

Rubén Muñoz Autor

Pues me alegro que te haya funcionado, porque eso quiere decir que ya al menos, has localizado el problema, está en la anterior instalación. ¿Cuál es el problema? Pues ni idea habría que verlo más detallado. ¿No te valdría con instalar uno nuevo? a veces es mejor no conocer la verdad xD

val_carter

Hola de nuevo, jejeje, a ver, me he montado un prestashop en un momentito y realizando esta modificación todo funciona ok, no ocurre lo antes mencionado. Pensaba que el prestashop que empleaba llevaba todo por defecto, pero por lo visto no es así. Alguna idea de lo que puede ser?? Gracias de antemano.

Rubén Muñoz Autor

Creo que es una buena solución lo que comentas, instalar desde 0 con esta modificación, si tienes la posibilidad de hacerlo en un hosting que no sea en Local, puede ser un buen test también. Suerte y espero que nos cuentes como te ha ido :D

val_carter

Esta tarde/noche diré algo, gracias por la ayuda!

Rubén Muñoz Autor

¿Has probado a realizar un echo o var_dump de la variable del id de la zona para intentar averiguar que pasa? Desde luego es extraño, y parece bastante obvio que desde otro lado se actualiza el valor cuando haces el return

Rubén Muñoz Autor

Hola val_carter, Gracias!! por el comentario. Sobre tu consulta, creo que efectivamente está calculando 2 veces la base de la zona geográfica. Preguntas: ¿Tienes algún plugin/módulo para zonas geográficas? ¿Es el que tiene Prestashop por defecto? ¿Estás programando sobre el core o has creado un plugin?

val_carter

He probado a establecer el id de la zona como un valor fijo, sin realizar consulta alguna, y observo lo que te comento, entrar si que entra, porque durante un segundillo establece bien los portes, pero luego los establece a cero. Cosa que no pasa si del carrito quito el producto que tiene "envio_gratis"=1. No sé..., lo que probaré es montar un prestashop inicial con esta modificación sólo a ver qué pasa...de todas maneras si se te ocurre qué puede ser o a otro compañero, no dudes en decirmelo. Gracias!

val_carter

Hola, lo que viene con prestashop por defecto, empleo el codigo if-else que ví más adelante en la clase Cart.php para obtener el valor del id de la zona. Lo que me extraña es que entrando en el return, luego se vuelva a modificar ese valor. Tampoco sé si es que algo más se ejecuta ( en esta clase u otra…) Ningún plugin, seguí estas intrucciones, tengo un prestashop en local y toqué la base de datos, luego el Product.php, el Cart.php…etc.

val_carter

Hola, lo que viene con prestashop por defecto, empleo el codigo if-else que ví más adelante en la clase Cart.php para obtener el valor del id de la zona. Lo que me extraña es que entrando en el return, luego se vuelva a modificar ese valor. Tampoco sé si es que algo más se ejecuta ( en esta clase u otra...) Ningún plugin, seguí estas intrucciones, tengo un prestashop en local y toqué la base de datos, luego el Product.php, el Cart.php...etc.

val_carter

Hola!!, llevo unos días trasteando prestashop, son mis comienzos, jejeje. Siguiendo las instrucciones de este increíble post he conseguido llevar a cabo la funcionalidad, es decir, establecer un producto que implique los gastos de envío gratis. Ahora bien, yo estoy interesado en que esto sólo ocurra para una determinada zona, Península, por ejemplo. Lo primero que se me ocurrió fue añadir en el código, que además de que a la consulta que hemos incluida para ver el campo "envio_gratis" también aprovechar para obtener el id_zona e incluirlo en el if. Tras incluir el código y volver a la tienda, si refresco, los portes se calculan bien....pero inmediatamente se vuelven a poner a cero, es como si pasara por algún sitio más. Durante un segundo veo que, por ejemplo, si estoy registrado en Canararias, no aplica el envío total a cero, pero inmediatamente se pone a cero. ¿Alguna idea?, lo único que hago es añadir en el código el tema del if y la consulta para obtener el id de la zona (no lo pongo porque lo tengo en el portatil, lo puedo poner luego): // Inicio modificacion //Si hay algun producto con gastos de envio gratis ya devuelvo cero $fila = Db::getInstance()->getRow(' SELECT count(*) AS nb FROM `'._DB_PREFIX_.'cart_product` cp LEFT JOIN `'._DB_PREFIX_.'product` p ON cp.`id_product` = p.`id_product` WHERE p.`envio_gratis` = 1 AND cp.`id_cart` = '.intval($this->id)); if (intval($fila['nb']) > 0){ //Modificacion //Ya sé que tiene envío gratis, veamos la zona ....Consulta para obtener id_zona if($id_zonaAux==9){ return 0; } } //$this->_nb_products = intval($row['nb']); // fin modificacion  

Rubén Muñoz Autor

Hola Jesús, Pues si mal no recuerdo la versión era precisamente esta, la 1.4.7.0 no obstante si haces una copia de seguridad mejor, pues no te lo podría precisar con exactitud.

Jesus

Buenas, iba a probarlo, pero tengo prestashop 1.4.7.0 y no sé si va a funcionar. ¿en qué versión habéis comprobado que funciona? gracias anticipadas.

Ruben

Si claro que se podría realizar, en vez de tocar product sería sobre las categorías, pero ¿Qué quieres hacer exactamente?

Manuel

¿Se podría hacer algo parecido con las categorías?

Rubén

Hola José Carlos, Lo primero saludarte, gracias por escribir el comentario. Si tienes cualquier duda te puedo ayudar, pero también te aseguro que a nosotros nos ha servido para poner 1 solo producto de una cesta con costes de envío gratis. Si necesitas ayuda aquí nos tienes.

José Carlos

Hola, es un buen artículo, bien explicado y por tanto fácil de llevar a cabo. Pero falla en la esencia: cuando uno lee "Envío gratis por producto PrestaShop" lo que espera es que se pueda establecer que el coste de envío de un producto concreto sea cero. Sin embargo, el código aquí expuesto lo que hace es que si en el pedido hay algún producto de envío gratuito, los costes de envío serán cero para TODO el pedido. Esto hace que esta contribución resulte poco útil. Saludos, José Carlos