Odoo自定义Widgets (三)

大家好,

接着上一章讲,odoo 中的Widgets使用方法。

上一次,我们讲到是利用了odoo中widget的继承机制,继承了fieldminxin 类,然后在其上面进行新的方法添加。

但这里注意,原始方法是没有被修改的。那么,这里就出现了一个问题,以前很多fields已经使用某个widget,如果要更新这个widgets ,但又希望是通过安装插件的方式来更新某个widgets,我们应该如何处理呐?这个时候,就需要用到odoo widgets中的继承方法。

这里,我们还是通过一个实例来讲解。

odoo.define('web_widget_float_formula', function(require) {
    "use strict";

    var form_view = require('web.FormView');
form_view.include({

     // 注意看,这里用了一个 include 方法,之前一直用的是extend
     // 其含义,是在现有挂件对象中,包含新方法
   
        _process_save: function(save_obj) {
            for (var f in this.fields) {
                if (!this.fields.hasOwnProperty(f)) { continue; }
                f = this.fields[f];
                if (f.hasOwnProperty('_formula_text') && f.$el.find('input').length > 0) {
                    f._compute_result();
                    f._clean_formula_text();
                }
            }

            return this._super(save_obj);

            //_super方法,是可以将原始值进行覆盖
        },
    });

跟着这个事例,我们有这样一个需求:

在销售订单中,我们希望通过 扫条码 来添加销售订单SO中的商品。

步骤一:(通过继承,在sale.order 模型中,添加新的方法,叫so_barcode)

class SaleOrder(models.Model):
    _inherit = 'sale.order'
_barcode_scanned = fields.Char("Barcode Scanned", help="Value of the last barcode scanned.", store=False)
 //字段,存储最后被扫描的条码值

    @api.model
    def so_barcode(self, barcode, so_id):
        sale_order = self.env['sale.order'].search([('id', '=', so_id)])
        if not sale_order:
            # 判断销售订单是否已经创建
            raise UserError(_('Please Choose Your Customer And Fix Your Sale Order'))
        product_id = self.env['product.product'].search([('barcode', '=', barcode)])
        //产品id,通过将条码与产品数据库中的条码进行匹配
        sale_order_line = sale_order.order_line.search([('product_id', '=', product_id.id)], limit=1)
        //在销售订单行中,查看 产品 是否已经存在
        if sale_order_line:
            sale_order_line.product_uom_qty = sale_order_line.product_uom_qty + 1
//若已经存在,直接总量添加1
        else:
//若没有存在,在行中添加新的商品
            line_values = {
                'name': product_id.name,
                'product_id': product_id.id,
                'product_qty': 1,
                'product_uom': product_id.product_tmpl_id.uom_id.id,
                'price_unit': product_id.product_tmpl_id.list_price,
                'order_id': sale_order.id,
                'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            }
            sale_order.update({'order_line': [(0, 0, line_values)]})

步骤二:(构建前端挂件,SaleBarcodeHandler)

odoo.define('sale_order_barcode.SaleBarcodeHandler', function (require) {
    "use strict";
    var core = require('web.core');
    var Model = require('web.Model');
    var FormViewBarcodeHandler = require('barcodes.FormViewBarcodeHandler');
var _t = core._t;
//基础方法集的引入
var SaleBarcodeHandler = FormViewBarcodeHandler.extend({
   //继承并拓展原始FormViewBarcodeHandler
 init: function (parent, context) {
         if (parent.ViewManager.action) {
             this.form_view_initial_mode= parent.ViewManager.action.context.form_view_initial_mode;
   //这里的主要目的是让新打开的视图中,是否为可编辑根据父级定义而定
         } else if (parent.ViewManager.view_form) {
             this.form_view_initial_mode= parent.ViewManager.view_form.options.initial_mode;
   //这里的主要目的是让新打开的视图中,是否为可编辑根据父级定义而定
         }
         return this._super.apply(this, arguments);
     },
     start: function () {
         this._super();
         this.so_model = new Model("sale.order");
         this.form_view.options.disable_autofocus = 'true';
         if (this.form_view_initial_mode) {
             this.form_view.options.initial_mode = this.form_view_initial_mode;
         }
     },
   //增加这些方法的目的是什么? - 这个问题是思考题,大家可以回去思考。我们会在下一章节中进行解答
on_barcode_scanned: function(barcode) {
            var self = this;
            var so_id = self.view.datarecord.id
            self.so_model.call('so_barcode',[barcode, so_id]).then(function () {
                self.getParent().reload();
            });
        //一旦,条码被扫描,就将barcode 和so_id传入 so_barcode 实例,并重新执行其父类的刷新;更新订单行。

        },
    });
    core.form_widget_registry.add('sale_barcode_handler', SaleBarcodeHandler);
    return SaleBarcodeHandler;
});
var core = require('web.core');
    core.bus.on('web_client_ready', null, function () {
        //注意,这里的bus 是用于挂件间传递信息,只有当web_client_ready 时,才会把数据传入当前widgets挂件
上一篇:Unity与安卓交互 之 ✨ 在Android Studio中写代码导出aar包,在Unity中使用交互(小白完整篇)


下一篇:Odoo 自定义Widgets 基础教程(章节2)