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

carrito-deslogeado

Resumen del carrito y bloque de carrito con usuario logeado

carrito-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

Autor
Escrito por Jose Aguilar - Director ejecutivo y tecnológico en JA Modules. Experto programador PrestaShop y Experto programador WordPress.
Te ha servido? Valora esta entrada!
(1 voto, promedio: 5 de 5)
Comparte en las redes sociales
¿Buscas trabajo de programador?

17 respuestas a “Mostrar gastos de envío solo a los usuarios registrados en prestashop”

  1. Jaime dice:

    Sencillamente perfecto. Rápido, claro y sencillo.

    Gracias

  2. Valentín Yonte dice:

    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

    • Ignacio dice:

      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

    • lola dice:

      mil gracias!!!! funciona genial sin tocar codigo!!!!º

  3. Josep M dice:

    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

  4. pablo dice:

    Hola: Gracias funciona casi perfecto, no aparece el coste del transporte pero si el iva del transporte, como podria solucionarlo?

  5. Hugo dice:

    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!

  6. Mauro dice:

    Excelente aportación. Me ha sido de mucha utilidad. Funciona perfectamente en la versión 1.5.6.0. Salu2.

  7. Cesar dice:

    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

  8. Mistique dice:

    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?

  9. Adrian dice:

    Muy bueno, me ha ido perfecto gracias!!!

  10. Jorge Pérez dice:

    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.

  11. Orlando dice:

    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

  12. Mon dice:

    Hola Jose, gracias por tu aportación, me ha sido de gran ayuda. Probado en un Prestashop 1.5.5.0 funciona perfectamente.

Deja una respuesta

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.