Search code examples
javascriptodoo

Override JavaScript function in Odoo


I have an issue with overriding a javascript function. I am working with Odoo POS and I want to override one of the POS JavaScript Function.

In Odoo point_of_sale -> models.js there is a function called set_quantity_by_lot. but it written extending Backbone.Collection. I can extend functions which are belongs to Backbone.Model but not the functions in Backbone.Collection.

This is a code of the function. (I want to extend the set_quantity_by_lot function):

    var PacklotlineCollection = Backbone.Collection.extend({
        model: exports.Packlotline,
        initialize: function(models, options) {
            this.order_line = options.order_line;
        },

        set_quantity_by_lot: function() {
            if (this.order_line.product.tracking == 'serial') {
                var valid_lots = this.get_valid_lots();
                this.order_line.set_quantity(valid_lots.length);

            }
        }
    });

Thank You,


Solution

  • That class is a private variable in module 'point_of_sale.models' if you check the return statement of that module its return exports;

    Export contains only this classes that you can override one there methods:

     exports = {
         PosModel: PosModel,
         NumpadState: NumpadState,
         load_fields: load_fields,
         load_models: load_models,
         Orderline: Orderline,
         Order: Order,
     };
    

    This means you cannot override it or access it. What you need to do Is define a new class PacklotlineCollection like in the original module and change the code of the method, override the only method that uses it witch is set_product_lot of class Orderline that is returned by the 'point_of_sale.models' module.

       odoo.define('techinca_name.models', function (require) {
            "use strict";
            // to access the classes
            var posModels = require('point_of_sale.models')
            // require any thing is used in the code too if there is
    
            // define a similar class with a little changes
            var PacklotlineCollection = Backbone.Collection.extend({
                // change this part 
                model: posModels.Packlotline,
                initialize: function(models, options) {
                    this.order_line = options.order_line;
                },
    
                get_empty_model: function(){
                    return this.findWhere({'lot_name': null});
                },
    
                remove_empty_model: function(){
                    this.remove(this.where({'lot_name': null}));
                },
    
                get_valid_lots: function(){
                    return this.filter(function(model){
                        return model.get('lot_name');
                    });
                },
    
                set_quantity_by_lot: function() {
                    // and this part 
                    if (this.order_line.product.tracking == 'serial') {
                        var valid_lots = this.get_valid_lots();
                        this.order_line.set_quantity(valid_lots.length);
    
                    }
                }
            });
    
            // override set_product_lot to use your class not the orignal class
            posModels.Orderline.inculde({
                // same code the only difference here it will use your own class
                set_product_lot: function(product){
                        this.has_product_lot = product.tracking !== 'none' && this.pos.config.use_existing_lots;
                        this.pack_lot_lines  = this.has_product_lot && new PacklotlineCollection(null, {'order_line': this});
                    },
            });
    
         });
    

    Note: to override a method of class use ClassName.include, extends just create a new class that inherit this ClassName.