Mejorando el carrito de Odoo

Edición: para clientes que vienen de otros eCommerce

Ignacio Buioli
- 01/30/2021 - 4 min. de lectura

En odoo es común tentarnos por querer usarlo para todo, y eso incluye el eCommerce. Y la verdad es que, por muy simple que sea, yo sostengo que el eCommerce de Odoo cumple para empezar a vender. No obstante, para clientes que ya usaron (o usan) otros eCommerce (Woocomerce, Shopify, TiendaNube, etc) el de Odoo puede resultarles muy simplón. Nuestros lectores mas frecuentes a lo mejor recuerden que escribí sobre la migración de un eCommerce de TiendaNube a Odoo con el caso de Puro Escabio que se nos acercaron con dicha inquietud (y que por supuesto recomendamos como negocio de bebidas). Recientemente, me pedieron algo que Odoo no posee y que no había visto en módulos: que al agregar productos al carrito se muestre de forma más evidente dicha acción. Esto es importante y es lo que ocurre con casos de negocios que ya trabajan en otros eCommerce y vienen a Odoo. Su propuesta fue similar a lo que hace TiendaNube, es decir, abrir un PopUp que muestre la lista de productos agregados en el carrito hasta ese punto, incluyendo el que acaban de agregar. De esa manera un comprador tiene control, puede elegir si seguir comprando o si ir a pagar. Lo dije varias veces, el eCommerce de Odoo sirve para comprar un solo artículo, si el promedio de compra es mayor (como el caso de un supermercado) se hace muy tedioso usar el carrito de Odoo. Bien, entonces, ¿cómo lo desarrollamos? Vamos con eso.

Módulo "Carrito Rápido"

Lo primero que hay que hacer es que el sistema funcione como un supermercado, entonces es inviable como lo hace Odoo. Para esto hay un módulo que he recomendado varias veces y que me tomé la libertad de migrar en su momento: website_sale_quick_cart

Verán que está para 12 y 13, yo creo que hasta funciona en 11. El punto es que este módulo elimina eso que hace Odoo de ir al checkout cada vez que se apreta en "agregar al carrito". Y lo que hace es agregar un boton de mas y menos para agregar cantidad, agregarlo automáticamente al carrito, pero con la comodidad de poder seguir comprando. Mi primer modificación fue hacer que el boton de más y menos no estén, crear un botón de "Agregar al Carrito" que simplemente replique la función del botón Más. Para esto se puede heredar la vista, o hacer las modificaciones sobre la propia vista de website_sale_quick_cart, así es como quedó:

<a t-attf-href="#"class="btn-pe-cart btn btn-secondary mb8 input-group-addon float_left js_add_cart_json" data-toggle="modal" data-target="#cartModal">
    <i class="fa fa-shopping-cart" /> Agregar al carrito
</a>

Esto es bastante sencillo, le damos los estilos que queramos mediante CSS (siempre dejando las clases por defecto como js_add_cart_json). Notarán que hay dos cosas agregadas a este botón que no dije, y son el data-toggle="modal" data-target="#cartModal". Básicamente, vamos a aprovechar bootstrap para crear un popup y mostrar en dicho popup la vista del carrito. Para eso vamos a tener que heredar la vista website_sale.products_item y en algun lugar poner el siguiente código:

<div class="modal" tabindex="-1" role="dialog" id="cartModal">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Agregado al Carrito</h5>
            </div>
            <div class="modal-body" id="contentCart">
            </div>
            <div class="modal-footer">
                <a href="/shop/cart" class="btn btn-primary">Finalizar Compra</a>
                <button type="button" class="btn btn-secondary" data-dismiss="modal" onClick="$('#contentCart').empty();">Seguir Comprando</button>
            </div>
        </div>
    </div>
</div>

Hago notar un par de cosas, el id del modal se llama cartModal igual que el data-target del botón que lo dispara; esto es de bootstrap. Por su parte, el botón de "Seguir Comprando" que es un data-dismiss (es decir, cierra el modal) también tiene un onClick que "limpia" el contenido de un div llamado "contentCart", el cual pueden encontrar como un div vacío dentro del modal. ¿Por qué no puse simplemente un t-call a la vista del carrito? Porque necesitamos actualizarla y Odoo la va a tomar como simple HTML, no va a cumplir su labor. Para eso, necesitamos JavaScript. Y por suerte el módulo de website_sale_quick_cart ya tiene un puntapié inicial para trabajar. Nos vamos a dirigir a static/src/js y dentro de dicha carpeta tendremos un archivo llamado website_sale_add_to_cart.js. Este archivo es el que dispara un controller para actualizar el carrito, eso pueden encontrarlo en esta función:

.jsonRpc("/shop/cart/update_json", "call", {

Esta parte es sumamente interesante, puesto que despues de ejecutar un then(function(data) va a devolver muchas vistas HTML actualizadas en esa variable data. Concretamente, para probar, podemos hacer esto:

console.log(data['website_sale.cart_lines'])

Si actualizamos el módulo y nos fijamos en la consola JavaScript al momento de agregar un nuevo producto al carrito podremos advertir que estará devolviendo un string que en verdad es un HTML del carrito completo. Queda solamente insertarlo en nuestro div convenientemente llamado "contentCart". El código completo:

.jsonRpc("/shop/cart/update_json", "call", {
    line_id: parseInt($input.data("line-id"), 10),
    product_id: parseInt($input.data("product-id") || $("input.product_id").val(),10),set_qty: value,})
.then(function(data) {
    if (!data.quantity) {
        location.reload();
        return;
    }
    var $q = $(".my_cart_quantity");
    $q.parent().parent().removeClass("hidden", !data.quantity);
    $q.html(data.cart_quantity).hide().fadeIn(600);
 
    $("#cart_total").replaceWith(data["website_sale.total"]);
    $("#contentCart").empty();
    if (data["warning"]) {
        $("#contentCart").append("<div class='alert alert-danger' role='alert'>" + data["warning"] + "</div>");
    }
    $("#contentCart").append(data["website_sale.cart_lines"])
});

Hago notar que gran parte de este código ya está en el módulo, lo que se hizo en este caso fue agregar los $("#contentCart").append con el HTML del carrito. También recuerden antes de hacer un append que en verdad es una actualización realizar un empty para vaciar el contenido que ya queda, sino obtendremos una repetición de carrito cada vez que se agregue un producto.


Acerca de:

Ignacio Buioli

Degree on Multimedia Arts. He has developed numerous Multimedia projects as well as written articles and translated texts of the mentioned subject. In Moldeo Interactive, He is a Partner and Programmer; also taking care of a large part of the online networks and courses.