Mostrar gastos de envío solo a los usuarios registrados en prestashop
El prestashop de serie muestra los gastos de envío a los usuarios aunque no estén logeados, mostrando un valor por defecto de envío incierto en muchos casos. Muchos usuarios de prestashop ven esta funcionalidad ilógica o incierta y creen que lo mejor es no visualizarlos si el usuario no está logeado.
El efecto de este artículo es conseguir lo siguiente:
Resumen del carrito y bloque de carrito con usuario deslogeado
Resumen del carrito y bloque de carrito con usuario logeado
Seguramente hay otras formas de ocultarlo pero yo bajo mi experiencia quiero compartir como solucioné este aspecto.
En este artículo vamos a ver como mostrar los gastos de envío solo a los usuarios registrados y logeados en Prestashop 1.5.x. Es decir, cuando eres un invitado, por ningún lugar verás gastos de envío. En cambio, cuando te registras y estás logeados ya visualizarás tanto en el carrito como en la página de carrito los gastos de envío correspondientes a la dirección de envío.
Voy a empezar a modficar la página del carrito. Lo primero que tendremos que hacer es editar el archivo themes/your-theme/shopping_cart.tpl condicionando la visualización de los gastos de envío en función de si el usuario está logeado o no.
Tendremos que buscar en la tabla de los detalles de la cesta el tr que contenga el class=»cart_total_delivery», en una plantilla básica, rondaría por la línea 124 donde veremos todo este código que controla la visualización de los gastos de envío.
{if $total_shipping_tax_exc <= 0 && !isset($virtualCart)}
<tr style="{if !isset($carrier->id) || is_null($carrier->id)}display:none;{/if}">
<td colspan="5">{l s='Shipping'}</td>
<td colspan="2" id="total_shipping">{l s='Free Shipping!'}</td>
</tr>
{else}
{if $use_taxes && $total_shipping_tax_exc != $total_shipping}
{if $priceDisplay}
<tr {if $total_shipping_tax_exc <= 0} style="display:none;"{/if}>
<td colspan="5">{if $display_tax_label}{l s='Total shipping (tax excl.)'}{else}{l s='Total shipping'}{/if}</td>
<td colspan="2" id="total_shipping">{displayPrice price=$total_shipping_tax_exc}</td>
</tr>
{else}
<tr{if $total_shipping <= 0} style="display:none;"{/if}>
<td colspan="5">{if $display_tax_label}{l s='Total shipping (tax incl.)'}{else}{l s='Total shipping'}{/if}</td>
<td colspan="2" id="total_shipping" >{displayPrice price=$total_shipping}</td>
</tr>
{/if}
{else}
<tr{if $total_shipping_tax_exc <= 0} style="display:none;"{/if}>
<td colspan="5">{l s='Total shipping'}</td>
<td colspan="2" id="total_shipping" >{displayPrice price=$total_shipping_tax_exc}</td>
</tr>
{/if}
{/if}
Todo este código, lo condicionaremos de la siguiente forma:
{if $logged}
{if $total_shipping_tax_exc <= 0 && !isset($virtualCart)}
<tr style="{if !isset($carrier->id) || is_null($carrier->id)}display:none;{/if}">
<td colspan="5">{l s='Shipping'}</td>
<td colspan="2" id="total_shipping">{l s='Free Shipping!'}</td>
</tr>
{else}
{if $use_taxes && $total_shipping_tax_exc != $total_shipping}
{if $priceDisplay}
<tr {if $total_shipping_tax_exc <= 0} style="display:none;"{/if}>
<td colspan="5">{if $display_tax_label}{l s='Total shipping (tax excl.)'}{else}{l s='Total shipping'}{/if}</td>
<td colspan="2" id="total_shipping">{displayPrice price=$total_shipping_tax_exc}</td>
</tr>
{else}
<tr{if $total_shipping <= 0} style="display:none;"{/if}>
<td colspan="5">{if $display_tax_label}{l s='Total shipping (tax incl.)'}{else}{l s='Total shipping'}{/if}</td>
<td colspan="2" id="total_shipping" >{displayPrice price=$total_shipping}</td>
</tr>
{/if}
{else}
<tr{if $total_shipping_tax_exc <= 0} style="display:none;"{/if}>
<td colspan="5">{l s='Total shipping'}</td>
<td colspan="2" id="total_shipping" >{displayPrice price=$total_shipping_tax_exc}</td>
</tr>
{/if}
{/if}
{/if}
Con esto lo que estamos haciendo tan solo es condicionar la visualización de los gastos de envío en función de si hay cookie o no.
Ahora faltaría sobreescribir la classe Cart.php añdiendo el siguiente código en override/classes/Cart.php
<?php
class Cart extends CartCore
{
public function getSummaryDetails($id_lang = null, $refresh = false)
{
$context = Context::getContext();
if (!$id_lang)
$id_lang = $context->language->id;
$delivery = new Address((int)$this->id_address_delivery);
$invoice = new Address((int)$this->id_address_invoice);
// New layout system with personalization fields
$formatted_addresses['delivery'] = AddressFormat::getFormattedLayoutData($delivery);
$formatted_addresses['invoice'] = AddressFormat::getFormattedLayoutData($invoice);
$base_total_tax_inc = $this->getOrderTotal(true);
$base_total_tax_exc = $this->getOrderTotal(false);
$total_tax = $base_total_tax_inc - $base_total_tax_exc;
if ($total_tax < 0)
$total_tax = 0;
$currency = new Currency($this->id_currency);
$products = $this->getProducts($refresh);
$gift_products = array();
$cart_rules = $this->getCartRules();
$total_shipping = $this->getTotalShippingCost();
$total_shipping_tax_exc = $this->getTotalShippingCost(null, false);
$total_products_wt = $this->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$total_products = $this->getOrderTotal(false, Cart::ONLY_PRODUCTS);
$total_discounts = $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS);
$total_discounts_tax_exc = $this->getOrderTotal(false, Cart::ONLY_DISCOUNTS);
// The cart content is altered for display
foreach ($cart_rules as &$cart_rule)
{
// If the cart rule is automatic (wihtout any code) and include free shipping, it should not be displayed as a cart rule but only set the shipping cost to 0
if ($cart_rule['free_shipping'] && (empty($cart_rule['code']) || preg_match('/^'.CartRule::BO_ORDER_CODE_PREFIX.'[0-9]+/', $cart_rule['code'])))
{
$cart_rule['value_real'] -= $total_shipping;
$cart_rule['value_tax_exc'] -= $total_shipping_tax_exc;
$cart_rule['value_real'] = Tools::ps_round($cart_rule['value_real'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
$cart_rule['value_tax_exc'] = Tools::ps_round($cart_rule['value_tax_exc'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
if ($total_discounts > $cart_rule['value_real'])
$total_discounts -= $total_shipping;
if ($total_discounts_tax_exc > $cart_rule['value_tax_exc'])
$total_discounts_tax_exc -= $total_shipping_tax_exc;
// Update total shipping
$total_shipping = 0;
$total_shipping_tax_exc = 0;
}
if ($cart_rule['gift_product'])
{
foreach ($products as $key => &$product)
if (empty($product['gift']) && $product['id_product'] == $cart_rule['gift_product'] && $product['id_product_attribute'] == $cart_rule['gift_product_attribute'])
{
// Update total products
$total_products_wt = Tools::ps_round($total_products_wt - $product['price_wt'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
$total_products = Tools::ps_round($total_products - $product['price'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
// Update total discounts
$total_discounts = Tools::ps_round($total_discounts - $product['price_wt'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
$total_discounts_tax_exc = Tools::ps_round($total_discounts_tax_exc - $product['price'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
// Update cart rule value
$cart_rule['value_real'] = Tools::ps_round($cart_rule['value_real'] - $product['price_wt'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
$cart_rule['value_tax_exc'] = Tools::ps_round($cart_rule['value_tax_exc'] - $product['price'], (int)$context->currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
// Update product quantity
$product['total_wt'] = Tools::ps_round($product['total_wt'] - $product['price_wt'], (int)$currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
$product['total'] = Tools::ps_round($product['total'] - $product['price'], (int)$currency->decimals * _PS_PRICE_DISPLAY_PRECISION_);
$product['cart_quantity']--;
if (!$product['cart_quantity'])
unset($products[$key]);
// Add a new product line
$gift_product = $product;
$gift_product['cart_quantity'] = 1;
$gift_product['price'] = 0;
$gift_product['price_wt'] = 0;
$gift_product['total_wt'] = 0;
$gift_product['total'] = 0;
$gift_product['gift'] = true;
$gift_products[] = $gift_product;
break; // One gift product per cart rule
}
}
}
foreach ($cart_rules as $key => &$cart_rule)
if ($cart_rule['value_real'] == 0)
unset($cart_rules[$key]);
if ($context->customer->logged == 0)
$base_total_tax_inc = $base_total_tax_inc - $total_shipping;
return array(
'delivery' => $delivery,
'delivery_state' => State::getNameById($delivery->id_state),
'invoice' => $invoice,
'invoice_state' => State::getNameById($invoice->id_state),
'formattedAddresses' => $formatted_addresses,
'products' => array_values($products),
'gift_products' => $gift_products,
'discounts' => $cart_rules,
'is_virtual_cart' => (int)$this->isVirtualCart(),
'total_discounts' => $total_discounts,
'total_discounts_tax_exc' => $total_discounts_tax_exc,
'total_wrapping' => $this->getOrderTotal(true, Cart::ONLY_WRAPPING),
'total_wrapping_tax_exc' => $this->getOrderTotal(false, Cart::ONLY_WRAPPING),
'total_shipping' => $total_shipping,
'total_shipping_tax_exc' => $total_shipping_tax_exc,
'total_products_wt' => $total_products_wt,
'total_products' => $total_products,
'total_price' => $base_total_tax_inc,
'total_tax' => $total_tax,
'total_price_without_tax' => $base_total_tax_exc,
'is_multi_address_delivery' => $this->isMultiAddressDelivery() || ((int)Tools::getValue('multi-shipping') == 1),
'free_ship' => $total_shipping ? 0 : 1,
'carrier' => new Carrier($this->id_carrier, $id_lang),
);
}
}
Donde tan solo estamos sobreescribiendo el método getSummaryDetails() añadiendo el código marcado en rojo que lo único que hace es controlar si no hay sesión establecida, al total le restamos el coste de envío. De esta forma, se cuadrará el total con el total de productos.
En el caso de que estemos utilizando el módulo blockcart con ajax, tendríamos también que modificar este módulo.
En el archivo themes/your_theme/modules/blockcart.tpl deberás condicionar la visualización de los gastos de envío de la siguiente forma:
{if $logged}
<span id="cart_block_shipping_cost">{$shipping_cost}</span>
<span>{l s='Shipping' mod='blockcart'}</span>
<br/>
{/if}
Y además tendrás que añadir las siguientes líneas de código en el archivo modules/blockcart/blockcart.php
Por debajo de la siguiente linea:
$totalToPay = $params['cart']->getOrderTotal($useTax);
Añade:
if ($params['cookie']->logged == 1) $totalToPay = $params['cart']->getOrderTotal($useTax); else $totalToPay = $params['cart']->getOrderTotal($useTax) - $shipping_cost_float;
Con el fin de mostar el total correctamente en el caso de que el usuario no esté en linea.
Si te ha servido este tutorial, no dudes en hacerte fan de la página de facebook del blog Jose Aguilar


Sencillamente perfecto. Rápido, claro y sencillo.
Gracias
Os comparto una opción sin tocar código que quizás os sirva.
– IMPORTANTE: Desactivar el transportista por defecto (no el de Recogida en tienda).
– Crear un nuevo transportista y en los grupos a aplicar quitar la marca a Invitados y huéspedes, dejando sólo marcada Clientes.
– Configurar el transporte según nuestras necesidades y asignar los pesos y zonas.
– Hacer click en finalizar.
Ahora, cuando un usuario nuevo agregue productos al carrito, no le aparecerán los gastos de transporte. Solamente los verá en el Checkout una vez registrado..
Ahora sólo los usuarios registrados verán el transporte.
Saludos
Gracias Valentín, me ha servido de gran ayuda.
En resumen la idea es desactivar en todos los transportistas disponibles el acceso al grupo «Visitor», de esa manera si no se ha iniciado sesión, no hay transportista disponible por lo que NO puede aparecer los gastos de transporte.
Es básico pero a la vez GENIAL.
Muchas gracias
mil gracias!!!! funciona genial sin tocar codigo!!!!º
Hola Jose, muy interesante el articulo. Me interesaría saber si esta modificación serviría para la versión 1.6.0.14.
Muchas gracias,
JOsep M
Hola, me temo que en algo varía pero no he tenido tiempo de revisarlo.
Hola: Gracias funciona casi perfecto, no aparece el coste del transporte pero si el iva del transporte, como podria solucionarlo?
Hola!
Muchas gracias por aportar esta solución.
En prestashop 1.6 se queda a medias porque utiliza otro tipo de carrito diferente a las versiones anteriores. ¿Sabrías aportar una solución para esa versión?
Gracias!
Excelente aportación. Me ha sido de mucha utilidad. Funciona perfectamente en la versión 1.5.6.0. Salu2.
Lo hice pero me sigue saliendo el precio de envio, tengo la version 1.5.6.1, saben si funciona en esa, y si es asi, para revisar nuevamente los archivos.
gracias
Hola. He implementado paso a paso las indicaciones en prestashop 1.4. Ya he corregido los archivos por si faltaba algo pero sigue apareciendo el total con el valor del shipping por defecto. Sabes que podría ser?
En prestashop 1.4 deberá ser otra historia. Este post funciona en prestashop 1.5.x
Muy bueno, me ha ido perfecto gracias!!!
Muy buen artículo. Yo tengo un problema con mi web y no se como solucionarlo. He quitado los gastos de envio del carrito eliminando las lineas:
{l s=’Shipping’ mod=’blockcart’}
{$shipping_cost}
Pero en el sumatorio total me sigue saliendo productos más gastos de envio.
Que solución crees que tendría que darle a este problema?
Gracias por tus artículos.
Seguramente te falte o está mal hecha la sobreescritura de la clase Cart.php
Me funciono perfecto en 1.5.
La única observación es que el archivo Cart.php lo encontré en classes/Cart.php y no en override/classes/Cart.php
GRACIAS
Hola Jose, gracias por tu aportación, me ha sido de gran ayuda. Probado en un Prestashop 1.5.5.0 funciona perfectamente.