Mensaje de descuento por medio de pago no combinable

En este tutorial, vamos a agregar 2 mensajes para comunicar que un descuento ofrecido por un medio de pago no es combinable con otras promociones cuando esté apagada la siguiente opción desde el medio de pago en el administrador:

Mostrándose en dos lugares dentro del detalle del producto: el formulario de producto y el popup de detalles del medio de pago.

Además se ocultará el descuento y precio con el descuento aplicado dentro del popup cuando el producto o la variante tenga un precio promocional o envío gratis. 

HTML

1. En el snipplet product-form.tpl o donde tengas tu formulario de producto buscar el lugar donde esté el mensaje del porcentaje de descuento por un medio de pago y reemplazarlo por lo siguiente:

{# Max Payment Discount #}

{% set hideDiscountContainer = not (hasDiscount and product.showMaxPaymentDiscount) %}
{% set hideDiscountDisclaimer = not product.showMaxPaymentDiscountNotCombinableDisclaimer %}

<div class="js-product-discount-container text-center text-md-left mb-2" {% if hideDiscountContainer %}style="display: none;"{% endif %}>
    <span><strong class="text-accent">{{ product.maxPaymentDiscount.value }}% {{'de descuento' | translate }}</strong> {{'pagando con' | translate }} {{ product.maxPaymentDiscount.paymentProviderName }}</span>
    <div class="js-product-discount-disclaimer font-small mt-1" {% if hideDiscountDisclaimer %}style="display: none;"{% endif %}>
        {{ "No acumulable con otras promociones" | translate }}
    </div>
</div>

Si no tenés la variable hasDiscount, podes crearla arriba del código anterior:

{% set hasDiscount = product.maxPaymentDiscount.value > 0 %}

2. En este paso vamos a sumar un parámetro para mostrar el mensaje en el componente privado de medios de pago. En caso que no tengas este componente, te recomendamos haber hecho este tutorial sobre medios de pago y haber leído este artículo sobre componentes privados.

Ahora sí, solo tenemos que sumar 2 parámetros en el componente payments/payments-details dentro del snipplet product-payment-details.tpl. Los parámetros son:

  • opacity: "opacity-60"
  • discounts_conditional_visibility: true

Quedando todo el componente de la siguiente forma:

{{ component('payments/payments-details',
    {
        text_classes: {
            text_accent: "label label-accent ml-1",
            subtitles: "h6 mb-3",
            text_big: "font-big",
            text_small: "font-small",
            align_right: "text-right",
            opacity: "opacity-60"
        },
        spacing_classes: {
            top_1x: "mt-1",
            top_2x: "mt-2",
            top_3x: "mt-3",
            right_1x: "mr-1",
            right_2x: "mr-2",
            right_3x: "mr-3",
            bottom_1x: "mb-1",
            bottom_2x: "mb-2",
            bottom_3x: "mb-3",
            left_3x: "ml-3",
        },
        container_classes : {
            payment_method: "card p-3"
        },
        discounts_conditional_visibility: true
    })
}}

CSS

Requisito:

Tener agregados en tu diseño las clases helpers. Podés seguir este este pequeño tutorial para hacerlo (simplemente es copiar y pegar algunas clases, no toma más de 1 minuto).

JS

Necesitamos aplicar las funciones en el archivo store.js.tpl (o donde tengas tus funciones de JS) para contemplar los cambios entre variantes que puedan tener o no un precio promocional.

Primero necesitamos ubicar la function changeVariant y arriba agregar el siguiente código:

{% set should_show_discount = product.maxPaymentDiscount.value > 0 %}
{% if should_show_discount %}

    {# Shows/hides price with discount and strikethrough original price for every payment method #}

    function togglePaymentDiscounts(variant){
        jQueryNuvem(".js-payment-method-total").each(function( paymentMethodTotalElement ){
            const priceComparerElement = jQueryNuvem(paymentMethodTotalElement).find(".js-compare-price-display");
            const installmentsOnePaymentElement = jQueryNuvem(paymentMethodTotalElement).find('.js-installments-no-discount');
            const priceWithDiscountElement = jQueryNuvem(paymentMethodTotalElement).find('.js-price-with-discount');

            priceComparerElement.hide();
            installmentsOnePaymentElement.hide();
            priceWithDiscountElement.hide();

            const discount = priceWithDiscountElement.data('paymentDiscount');

            if (discount > 0 && showMaxPaymentDiscount(variant)){
                priceComparerElement.show();
                priceWithDiscountElement.show()
            } else {
                installmentsOnePaymentElement.show();
            }
        })
    }

    {# Toggle discount and discount disclaimer both on product details and popup #}

    function updateDiscountDisclaimers(variant){
        updateProductDiscountDisclaimer(variant);
        updatePopupDiscountDisclaimers(variant);
    }

    {# Toggle discount and discount disclaimer in product details #}

    function updateProductDiscountDisclaimer(variant){
        jQueryNuvem(".js-product-discount-container, .js-product-discount-disclaimer").hide();

        if (showMaxPaymentDiscount(variant)){
            jQueryNuvem(".js-product-discount-container").show();
        }

        if (showMaxPaymentDiscountNotCombinableDisclaimer(variant)){
            jQueryNuvem(".js-product-discount-disclaimer").show();
        }
    }

    {# Shows/hides discount message for payment method and discount disclaimer in popup, for every payment method #}

    function updatePopupDiscountDisclaimers(variant){
        jQueryNuvem(".js-modal-tab-discount, .js-payment-method-discount").hide();

        {% if product.maxPaymentDiscount.value > 0 %}
            if (showMaxPaymentDiscount(variant)){
                {% for key, method in product.payment_methods_config %}
                    {% if method.max_discount > 0 %}
                        {% if method.allows_discount_combination %}
                            jQueryNuvem("#method_{{ key | sanitize }} .js-modal-tab-discount").show();
                        {% elseif not product.free_shipping %}
                            if (!variantHasPromotionalPrice(variant)){
                                jQueryNuvem("#method_{{ key | sanitize }} .js-modal-tab-discount").show();
                            }
                        {% endif %}
                    {% endif %}
                {% endfor %}
            }
        {% endif %}

        jQueryNuvem(".js-info-payment-method-container").each(function(infoPaymentMethodElement){
            {# For each payment method this will show the payment method discount and discount explanation #}

            const infoPaymentMethod = jQueryNuvem(infoPaymentMethodElement)
            infoPaymentMethod.find(".js-discount-explanation").hide();
            infoPaymentMethod.find(".js-discount-disclaimer").hide();

            const priceWithDiscountElement = infoPaymentMethod.find('.js-price-with-discount');
            const discount = priceWithDiscountElement.data('paymentDiscount');

            if (discount > 0 && showMaxPaymentDiscount(variant)){
                infoPaymentMethod.find(".js-discount-explanation").show();
                infoPaymentMethod.find(".js-payment-method-discount").show();
            }

            if (discount > 0 && showMaxPaymentDiscountNotCombinableDisclaimer(variant)){
                infoPaymentMethod.find(".js-discount-disclaimer").show();
            }
        })
    }

    function variantHasPromotionalPrice(variant) { return variant.compare_at_price_number > variant.price_number }

    function showMaxPaymentDiscount(variant) {
        {% if product.maxPaymentDiscount()["allowsDiscountCombination"] %}
            return true;
        {% elseif product.free_shipping %}
            return false;
        {% else %}
            return !variantHasPromotionalPrice(variant);
        {% endif %}
    }

    function showMaxPaymentDiscountNotCombinableDisclaimer(variant) {
        {% if product.maxPaymentDiscount()["allowsDiscountCombination"] or product.free_shipping %}
            return false
        {% else %}
            return !variantHasPromotionalPrice(variant)
        {% endif %}
    }
{% endif %}

Por último dentro de la función changeVariant buscar el condicional {% if template == 'product' %} y sumar lo que está dentro del condicional {% if should_show_discount %} en el ejemplo debajo :

{% if template == 'product' %}
    const base_price = Number(jQueryNuvem("#price_display").attr("content"));
    refreshInstallmentv2(base_price);
    refreshPaymentDiscount(variant.price_number);
    {% if should_show_discount %}
        togglePaymentDiscounts(variant);
        updateDiscountDisclaimers(variant);
    {% endif %}

    {% if settings.last_product and product.variations %}
        if(variant.stock == 1) {
            jQueryNuvem('.js-last-product').show();
        } else {
            jQueryNuvem('.js-last-product').hide();
        }
    {% endif %}
{% endif %}

Traducciones

En este paso agregamos los textos para las traducciones en el archivo config/translations.txt

es "No acumulable con otras promociones"
pt "Não acumulável com outras promoções"
en "Not combinable with other promotions"
es_mx "No acumulable con otras promociones"

Activación

Una vez aplicados todos los cambios en tu código, sólo tendrás que desactivar la opción de combinar los descuentos desde los detalles de cada medio de pago.

¡Listo! ya podés comunicar mejor tus descuentos por medio de pago.