Documentación para Diseñadores

Crea tus propias plantillas en Tienda Nube

Calculador inteligente de envíos

Esta mejora se encuentra relacionada al calculador de envíos en tu tienda y lo llamamos “inteligente” debido a que se ocupa de separar el listado de opciones de envío en dos partes: 

  • Medios de envío destacados que representan la mejor relación entre costo y tiempo.

  • El resto de los medios de envío sin destacar.

Algunas aclaraciones sobre cómo trabaja esta separación:

  1. Los medios de envío personalizados y locales siempre se mostrarán entre los destacados.

  2. La separación entre estos dos grupos se dará solamente cuando la tienda tenga medios de envío no personalizados que puedan llegar a competir entre sí ofreciendo un servicio similar. Por ejemplo: si la tienda ofrece Mercado Envíos y Correo Argentino, uno de estos (el que mejor relación costo/tiempo ofrezca) se encontrará entre los destacados y el otro no.

Es fundamental disminuir el estrés de los usuarios a la hora de elegir cómo recibir su pedido, por lo que esta funcionalidad contribuye con eso mostrando menos y mejores opciones.

Por otro lado, este cambio incluye también una mejora en relación a cómo se muestra cada ítem del listado de opciones de envío, dando prioridad al costo y el tiempo por encima de cuál es la empresa de logística.

Para ofrecer el nuevo calculador en la tienda deberás seguir los siguientes pasos: (los mismos se encuentran basados en una plantilla que usa Bootstrap 3)

1. Agregar estos bloques de texto en el archivo translations.txt

es "Ver más opciones"
pt "Ver mais opções"
en "See more options"

es "Ver menos opciones"
pt "Ver menos opções"
en "See less options"

2. Incluir dentro de layout.tpl el siguiente Javascript:

$(document).on("click", ".js-show-more-shipping-options", function(e) {
    e.preventDefault();
    $(this).next().toggle();
    $(this).find(".js-shipping-see-more, .js-shipping-see-less").toggle();
});

3. Crear el siguiente archivo llamado shipping-calculator-item.tpl, dentro de la carpeta snipplets:

<li class="js-shipping-list-item list-item radio-button-item">
    <label class="radio-button" for="{% if smart_shipping and featured_option %}featured-{% endif %}shipping-{{loop.index}}">
        <input id="{% if smart_shipping and featured_option %}featured-{% endif %}shipping-{{loop.index}}" class="js-shipping-method shipping-method" data-price="{{option.cost.value}}" type="radio" value="{{option.code}}" {% if not smart_shipping or (smart_shipping and featured_option) %}{% if loop.first %}checked="checked"{% endif %}{% endif %} name="option" style="display:none" />
        <span class="shipping-option radio-button-content">
            <span class="radio-button-icons">
                <span class="radio-button-icon unchecked"></span>
                <span class="radio-button-icon checked"></span>
            </span>
            <span class="radio-button-label">
                {% if smart_shipping %}
                    
                    <div> 
                        {% if option.show_price %}
                        <span class="text-primary font-medium">
                            <strong>
                                {% if option.cost.value == 0  %}
                                    {{ 'Gratis' | translate }}
                                {% else %}
                                    {{option.cost}}
                                {% endif %}
                            </strong>
                        </span>
                        {% endif %}
                        {% if option.time %}
                            <span><strong>{{ option.time }}</strong></span>
                        {% endif %}
                    </div>
                    {% if option.img_code != "branch" %}
                        <div class="radio-button-text">{{option.short_name}}</div>
                        {% if option.payment_rules %}
                            <div class="font-small">
                                <i class="fa fa-info-circle opacity-80" aria-hidden="true"></i>
                                <i>{{option.payment_rules}}</i>
                            </div>
                        {% endif %}
                    {% else %}
                        <div>{{option.name}}</div>
                    {% endif %}
                    {% if option.warning['enable'] %}
                        <div class="alert alert-warning pull-right m-top m-bottom-none">
                          <p>{{ option.warning['message'] }}</p>
                        </div>
                    {% endif %}
                    {% if option.suboptions is not empty %}
                        {% include "snipplets/shipping_suboptions/#{option.suboptions.type}.tpl" with {'suboptions': option.suboptions} %}
                    {% endif %}
                {% else %}
                    <img class="radio-button-img card-img" src="{{option.img_code | shipping_logo}}"/>
                    <span class="option-name radio-button-text">
                        {{option.name}} 
                        {% if option.show_price %} 
                            {% if option.cost.value == 0  %}
                                -  <strong class="text-primary">{{ 'Gratis' | translate }}</strong>
                            {% else %}
                                - <strong >{{option.cost}}</strong>
                            {% endif %}
                        {% endif %}
                        {% if option.suboptions is not empty %}
                            {% include "snipplets/shipping_suboptions/#{option.suboptions.type}.tpl" with {'suboptions': option.suboptions} %}
                        {% endif %}
                    </span>
                {% endif %}
                {% if option.warning['enable'] %}
                    <div class="alert alert-warning pull-right m-top m-bottom-none">
                      <p class="">{{ option.warning['message'] }}</p>
                    </div>
                {% endif %}
            </span>
        </span>
    </label>
</li>

4. Reemplazar el código existente por el siguiente, dentro del archivo shipping_options.tpl

{% if options %}
<p class="radio-group-label">{{"Vea las opciones de envío para su código postal abajo" | translate}}:</p>
<ul class="list-unstyled shipping-list radio-button-container">

    {% if store.has_smart_shipping %}

        {# Smart shipping hides similar shipping options on a toggle div and also shows an improved shipping item #}

        {# Check if smart shipping is needed #}

        {% set has_options_to_hide = false %}

        {% for option in options_to_hide %}
            {% if options_to_hide|length >= 1 %}
                {% set has_options_to_hide = true %}
            {% endif %}
        {% endfor %}

        {% for option in options_to_show %}
            {% include "snipplets/shipping-calculator-item.tpl" with {'smart_shipping': true, 'featured_option': true} %}
        {% endfor %}

        {% if has_options_to_hide %}
            <a href="#" class="js-show-more-shipping-options btn-link pull-left full-width text-center-xs">
                <span class="js-shipping-see-more">{{ 'Ver más opciones' | translate }}<i class="fa fa-chevron-down m-left-quarter" aria-hidden="true"></i></span>
                <span class="js-shipping-see-less" style="display: none;">{{ 'Ver menos opciones' | translate }}<i class="fa fa-chevron-up m-left-quarter" aria-hidden="true"></i></span>
            </a>
            <div class="js-other-shipping-options m-top pull-left full-width" style="display: none;">
                {% for option in options_to_hide %}
                    {% include "snipplets/shipping-calculator-item.tpl" with {'smart_shipping': true} %}
                {% endfor %}
            </div>
        {% endif %}
    {% else %}
        {% for option in options %}
            {% include "snipplets/shipping-calculator-item.tpl" with {'smart_shipping': false} %}
        {% endfor %}
    {% endif %}
</ul>
<div style="clear: both;"></div>
{% else %}
<span>{{"No hay costos de envío para el código postal dado." | translate}}</span>
{% endif %}


{# Don't remove this #}
<input type="hidden" name="after_calculation" value="1"/>
<input type="hidden" name="zipcode" value="{{zipcode}}"/>

5. En el archivo que representa el detalle de un producto (por lo general es product.tpl), buscar el div que engloba al calculador de envíos y añadir la class list-readonly. Debería quedar similar a lo siguiente:

{% if settings.shipping_calculator %}
    <div id="product-shipping-container" class="product-shipping-calculator m-bottom {% if store.has_smart_shipping %}list-readonly{% endif %}" {% if not product.display_price %}style="display:none;"{% endif %}>
        {% snipplet "shipping_cost_calculator.tpl" with shipping_calculator_show = settings.shipping_calculator_product_page and not product.free_shipping, shipping_calculator_variant = product.selected_or_first_available_variant %}
    </div>
{% endif %}

6. En el archivo de SASS (en este caso style.scss.tpl) agregar lo siguiente:

{# /* // Shipping calculator */ #}

.product-shipping-calculator{
  label{
    cursor: default;
  }
  li input[type="radio"]:checked + .shipping-option{
    outline:0;
  }
  .radio-button-icons{
    display: none
  }
}

.list-readonly .list-item{
  .radio-button-content{
    padding: 0;
  }
  .radio-button-label:after{
    display:none;
  }
}

Opcional: Si no tenés el elemento .radio-button en este archivo, podés colocar este código:

.radio-group-label{
  margin-bottom: 10px;
}
.radio-button{
  width: 100%;
  float: left;
  clear: both;
  margin-bottom: 15px;
  font-weight: normal;
  cursor: pointer;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  &-content{
    position: relative;
    float: left;
    width: 100%;
    padding: 5px;
  }
  &-icons{
    position: relative;
    float: left;
    display: table;
    width: 25px;
    margin: 1px 0 0 0;
  }
  &-icon{
    border-radius: 50%;
    width: 18px;
    height: 18px;
  }
  input[type="radio"]{
    display: none;
    & + .radio-button-content .unchecked{
      float: left;
    }
    & + .radio-button-content .checked{
      position: absolute;
      left:9px;
      top:9px;
      width:0;
      height: 0;  
      @include prefix(transform, translate(-50%,-50%), webkit ms moz o);
      @include prefix(transition, all 0.2s , webkit ms moz o);
    }
    &:checked + .radio-button-content .checked{
      width: 10px;
      height: 10px;
    }
  }
  &-label{
    display: table;
  }
  .radio-button-img{
    float: left;
    display: table;
    width: 40px;
    margin: 0px 10px 0 0;
    vertical-align: middle;
  }
  &-text{
    display: table;
  }
}

7. Si tenés el archivo critical-css.tpl vas a tener que incluir las siguientes clases: (Si no tenés un archivo critical-css.tpl podés agregarlo en tu CSS común al final de todo). Antes de incluirlas, chequeá que ya no las tengas:

.overide-container-width{margin-left:-15px!important;margin-right:-15px!important}.text-danger{color:red!important}.input-error{border:1px solid #cc4845!important}.d-flex{display:flex}.d-inline{display:inline}.d-block{display:block}.d-inline-block{display:inline-block}.d-inline-block-xs{display:none}.center-content{justify-content:center}.p-relative{position:relative!important}.p-absolute{position:absolute!important}.p-fixed{position:fixed}.clear-both{clear:both!important}.opacity-80{opacity:.8!important}.opacity-50{opacity:.5!important}.opacity-10{opacity:.1!important}.full-height{height:100%!important}.full-width{width:100%!important}.m-top{margin-top:20px!important}.m-top-double{margin-top:40px!important}.m-top-half{margin-top:10px!important}.m-top-quarter{margin-top:5px!important}.m-top-none{margin-top:0!important}.m-right{margin-right:20px!important}.m-right-double{margin-right:40px!important}.m-right-half{margin-right:10px!important}.m-right-quarter{margin-right:5px!important}.m-right-none{margin-right:0!important}.m-bottom{margin-bottom:20px!important}.m-bottom-double{margin-bottom:40px!important}.m-bottom-half{margin-bottom:10px!important}.m-bottom-quarter{margin-bottom:5px!important}.m-bottom-none{margin-bottom:0!important}.m-left{margin-left:20px!important}.m-left-half{margin-left:10px!important}.m-left-quarter{margin-left:5px!important}.m-left-none{margin-left:0!important}.m-all{margin:20px!important}.m-all-half{margin:10px!important}.m-all-quarter{margin:5px!important}.m-auto{margin:auto!important}.m-none{margin:0!important}.p-top{padding-top:20px!important}.p-top-double{padding-top:40px!important}.p-top-half{padding-top:10px!important}.p-top-quarter{padding-top:5px!important}.p-top-none{padding-top:0!important}.p-right{padding-right:20px!important}.p-right-double{padding-right:40px!important}.p-right-half{padding-right:10px!important}.p-right-quarter{padding-right:5px!important}.p-right-none{padding-right:0!important}.p-bottom{padding-bottom:20px!important}.p-bottom-double{padding-bottom:40px!important}.p-bottom-half{padding-bottom:10px!important}.p-bottom-quarter{padding-bottom:5px!important}.p-bottom-none{padding-bottom:0!important}.p-left{padding-left:20px!important}.p-left-double{padding-left:40px!important}.p-left-half{padding-left:10px!important}.p-left-quarter{padding-left:5px!important}.p-left-none{padding-left:0!important}.p-all{padding:20px!important}.p-all-half{padding:10px!important}.p-all-quarter{padding:5px!important}.p-none{padding:0!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{-ms-word-break:break-all!important;word-wrap:break-word!important;-webkit-hyphens:auto!important;-moz-hyphens:auto!important;hyphens:auto!important}.text-underline{text-decoration:underline}.list-unstyled-spaced li{margin-bottom:5px}.list-unstyled-spaced i{margin-right:5px}.overflow-none{overflow:hidden}

@media (max-width: 767px) {
  .overide-container-width,.overide-container-width-xs{width:100vw!important}.clear-both-xs{clear:both!important}.f-none-xs{float:none!important}.pull-left-xs{float:left!important}.d-inline-block-xs{display:inline-block!important}.full-width-xs{width:100%!important}.p-all-half-xs{padding:10px!important}.p-all-quarter-xs{padding: 5px!important}.p-none-xs{padding:0!important}.p-top-xs{padding-top:20px!important}.p-right-double-xs{padding-right:40px!important}.p-top-half-xs{padding-top:10px!important}.p-top-quarter-xs{padding-top:5px!important}.p-right-half-xs{padding-right:10px!important}.p-right-quarter-xs{padding-right:5px!important}.p-right-none-xs{padding-right:0!important}.p-bottom-xs{padding-bottom:20px!important}.p-bottom-double-xs{padding-bottom:40px!important}.p-bottom-half-xs{padding-bottom:10px!important}.p-left-half-xs{padding-left:10px!important}.p-left-quarter-xs{padding-left:5px!important}.p-left-none-xs{padding-left:0!important}.m-none-xs{margin:0!important}.m-top-xs{margin-top:20px!important}.m-top-half-xs{margin-top:10px!important}.m-top-quarter-xs{margin-top:5px!important}.m-top-none-xs{margin-top:0!important}.m-right-half-xs{margin-right: 10px!important}.m-bottom-xs{margin-bottom:20px!important}.m-bottom-half-xs{margin-bottom:10px!important}.m-bottom-quarter-xs{margin-bottom:5px!important}.m-bottom-none-xs{margin-bottom:0!important}.m-left-xs{margin-left:20px!important}.m-left-half-xs{margin-left:10px!important}.border-none-xs{border:0!important}.text-center-xs{text-align:center!important}.text-left-xs{text-align:left!important}.horizontal-container{overflow-y:hidden;overflow-x:scroll!important;margin:0}.horizontal-container::-webkit-scrollbar{width:1px!important;height:0!important}.horizontal-container::-webkit-scrollbar-track{background:0 0!important;border-radius:10px!important}.horizontal-container::-webkit-scrollbar-thumb{border-radius:1px!important}.horizontal-container ul,.horizontal-products-scroller{white-space:nowrap!important}.list-unstyled-spaced li{margin-bottom:10px}
}

8. Opcional: En el archivo de SASS relacionado a colores (en este caso main-color.scss.tpl) agregar lo siguiente:  

.radio-button {
    input[type="radio"]{
        & +  .radio-button-content .unchecked{
            border:2px solid $primary-color;
        }
        & +  .radio-button-content .checked{
            background-color: $primary-color;
        }
        &:checked{
            & + .radio-button-content .checked{
                color: $primary-color;
            }
        }
    }
}

9. Opcional: De tener el archivo checkout.scss.tpl dentro de la carpeta static, agregar:

btn-link,
.btn-link:hover {
  color: $primary-brand-color;
}

10. Si bien esta funcionalidad aplica al calculador, también debe reflejarse en el segundo paso del checkout. Como no se pueden hacer cambios en el código sobre esto mediante los archivos en el FTP, te pedimos que nos contactes a hola@tiendanube.com para que activemos la funcionalidad para el checkout.

¡Listo! Ya tenés el nuevo calculador de envíos funcionando en la tienda. :)

Sin compromiso de compra ni estadía mínima. No hay costo de registro o cancelación.