Tienda con productos digitales y/o físicos

En el siguiente tutorial, explicamos cómo hacer que una tienda adapte el flujo de compra cuando vende productos físicos y productos digitales o servicios, considerando la posibilidad de tener carritos “mixtos” con ambos tipos de productos. 

Los cambios de este tutorial aplican al detalle del producto y el carrito, sin embargo el proceso de checkout también está adaptado para productos digitales y/o físicos en la misma compra (para este punto no necesitamos modificar nada).
Básicamente lo que va a cambiar, es que cuando un carrito contenga sólo productos digitales o servicios, se va a ocultar y anular todo tipo de información relacionada al envío.

Si la tienda sólo vende productos físicos o sólo vende productos digitales es probable que no necesites este tutorial ya que la info de envíos puede ser activada o desactivada desde la sección de Personalizar tu diseño dependiendo el caso.

Antes de avanzar es importante que tengas el calculador de envíos agregado al código de tu diseño.

HTML

1. Lo primero que vamos a hacer es modificar la forma en la cual es importado el tpl del calculador de envíos.
Para esto tenemos que cambiar el archivo shipping-calculator.tpl dentro de la carpeta snipplets > shipping , removiendo el primer condicional de twig que hay. Debería ser el siguiente.

{% if shipping_calculator_show %}

Y luego obviamente remover el cierre de dicho condicional al final del archivo.

2. Luego vamos a modificar la forma y las condiciones bajo las cuales el calculador se va a mostrar en el detalle del producto, ya que no queremos que se muestre para los productos digitales ni productos con envío gratis. Estos cambios también aplicaran a mostrar u ocultar locales.

En el archivo product-form.tpl de la carpeta snipplets > product (o en el archivo donde tengamos la inclusión del calculador de envíos para el detalle del producto) vamos a ubicar el condicional de twig que muestra u oculta el calculador. Debería ser algo así:

{% if settings.shipping_calculator_product_page and not product.free_shipping %}

Arriba del condicional vamos a definir los nuevos casos donde queremos mostrar el calculador y los locales guardándolos en una variable para luego reemplazar el viejo condicional, quedando algo como lo siguiente:

{# Define contitions to show shipping calculator and store branches on product page #}

{% set show_calculator_on_product = settings.shipping_calculator_product_page and store.has_shipping and not product.free_shipping %}

{% set show_branches_on_product = store.branches and not product.free_shipping %}

{% if show_calculator_on_product or show_branches_on_product %}

Por último para el detalle del producto, tenemos que cambiar la forma en la cual incluimos el calculador. Todo el componente incluyendo calculador y locales va a quedar así:

{# Define conditions to show shipping calculator and store branches on product page #}

{% set show_calculator_on_product = settings.shipping_calculator_product_page and store.has_shipping and not product.free_shipping %}

{% set show_branches_on_product = store.branches and not product.free_shipping %}

{% if show_calculator_on_product or show_branches_on_product %}

    {# Shipping calculator and branch link #}

    <div id="product-shipping-container" class="product-shipping-calculator list" {% if not product.display_price or not product.has_stock %}style="display:none;"{% endif %} {% if store.has_shipping_polish %}data-shipping-url="{{ store.shipping_calculator_url }}"{% endif %}>
        {% if show_calculator_on_product %}
            {% include "snipplets/shipping/shipping-calculator.tpl" with {'shipping_calculator_variant' : product.selected_or_first_available_variant, 'product_detail': true} %}
        {% endif %}

        {% if show_branches_on_product %}

            {# Link for branches #}
            {% include "snipplets/shipping/branches.tpl" with {'product_detail': true} %}
        {% endif %}
    </div>
{% endif %}

3. Ahora tenemos que hacer algo similar pero para el carrito de compras. La diferencia es que acá precisamos que la información de envíos no esté visible pero a través de Javascript va a mostrarse u ocultarse dependiendo los productos del carrito,

Lo primero que tenemos que hacer es saber si el producto en el carrito requiere envío o no. Para esto hay que modificar el archivo cart-item-ajax.tpl de la carpeta snipplets (o el archivo que contenga a los items del carrito). 

Ubicamos el elemento con la clase “js-cart-item” (si no tenemos esta clase vamos a tener que agregarla) y agregamos el condicional necesario para identificar el tipo de producto. Debería quedar algo como lo siguiente:

<div class="js-cart-item {% if item.product.is_non_shippable %}js-cart-item-non-shippable{% else %}js-cart-item-shippable{% endif %}" data-item-id="{{ item.id }}">

4. Ahora sí podemos modificar la forma en la que incluimos el calculador y los locales. Para esto tenemos que modificar el archivo cart-totals.tpl en la carpeta snipplets (o el archivo donde tengamos incluido el calculador de envíos en el carrito).

Lo primero que vamos a hacer es definir las condiciones bajo las cuales mostraremos el calculador a través de un set de twig al comienzo del archivo:

{% set show_calculator_on_cart = settings.shipping_calculator_cart_page and store.has_shipping %}

Luego tenemos que ubicar el condicional bajo el cual mostramos el calculador y los locales, debería ser algo cómo esto:

{% if settings.shipping_calculator_cart_page %}

Y reemplazarlo por el siguiente:

{% if show_calculator_on_cart or store.branches %}

Justo debajo del comienzo de este condicional vamos a agregar el siguiente div

<div class="js-fulfillment-info js-allows-non-shippable" {% if not cart.has_shippable_products %}style="display: none"{% endif %}>

Y no olvidemos de cerrarlo justo antes del cierre del condicional {% if show_calculator_on_cart or store.branches %}.

Esto nos va a permitir ocultar o mostrar todo lo que contiene al calculador y los locales a medida que el carrito varíe sus productos.

Lo siguiente que debemos hacer es cambiar la forma en la cual incluimos tanto el calculador y los locales dejando un código como el siguiente:

{# Shipping Calculator #}

{% if show_calculator_on_cart %}
    {% include "snipplets/shipping/shipping-calculator.tpl" with { 'product_detail': false} %}
{% endif %}

{# Store branches #}

{% if store.branches %}
    {% include "snipplets/shipping/branches.tpl" with {'product_detail': false} %}
{% endif %}

Lo último que vamos a cambiar (si es que lo necesitamos) son las condiciones para mostrar u ocultar elementos que hablen de envío, dependiendo la condición del carrito. En este caso vamos a modificar un texto que aclara que el subtotal del carrito es “sin envío”. 

Si el carrito es 100% digital o de servicios, es altamente probable que tengamos que ocultar este texto.

Lo primero que haremos es ubicar el texto:

{% if settings.shipping_calculator_cart_page %}
    <small>{{ " (sin envío)" | translate }}</small>
{% endif %}

Y cambiar las condiciones para que siempre se encuentre cargado en el DOM (no dependa de twig para esto) pero cambiar su visibilidad a través de Javascript, cambiando a algo cómo:

<small class="js-fulfillment-info" {% if not cart.has_shippable_products or not show_calculator_on_cart %}style="display: none"{% endif %}>{{ " (sin envío)" | translate }}</small>

Básicamente ocultamos el elemento si el carrito no tiene productos físicos o no tiene configurado el calculador de envíos, pero a través de la clase “js-fulfillment-info” vamos a poder mostrarlo u ocultarlo con JS si lo necesitamos.

El mismo concepto puede aplicar a cualquier elemento que deba mostrarse u ocultarse dependiendo de los productos del carrito, sólo tenemos que pensar que lo que antes se cargaba o no en el DOM a través de twig, ahora debe estar siempre presente y twig solo cambia su visibilidad.

JS

El último paso que queda es modificar el caso en el cual cargamos la función de Javascript “calculateCartShippingOnLoad”. La cual recalcula el envío al cargar la página si hay un código postal guardado o una opción de envío elegida.

Si no tenemos esta función es importante que revisemos el tutorial del calculador de envíos

Antes cargábamos la función sin ningún condicional de twig pero ahora necesitamos usarla solo si el carrito requiere envío. 

Para esto tenemos que ubicarla en el archivo store.js.tpl dentro de la carpeta static > js (o donde tengamos las funciones de JS) y agregarle el condicional necesario para que quede así:

{% if cart.has_shippable_products %}
    calculateCartShippingOnLoad();
{% endif %}

Activación

Para publicar productos digitales simplemente tenemos que agregar o modificar un producto nuevo en la tienda y elegir la opción de “Producto digital o servicio”.

Listo, ya tenés la tienda adaptada tanto para productos que requieren envío como los que no, incluyendo carritos mixtos ¡Excelente!