你们好,前端
接着上一章讲,odoo 中的Widgets使用方法。web
上一次,咱们讲到是利用了odoo中widget的继承机制,继承了fieldminxin 类,而后在其上面进行新的方法添加。数据库
但这里注意,原始方法是没有被修改的。那么,这里就出现了一个问题,之前不少fields已经使用某个widget,若是要更新这个widgets ,但又但愿是经过安装插件的方式来更新某个widgets,咱们应该如何处理呐?这个时候,就须要用到odoo widgets中的继承方法。api
这里,咱们仍是经过一个实例来说解。app
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方法,是能够将原始值进行覆盖 }, });
跟着这个事例,咱们有这样一个需求:ui
在销售订单中,咱们但愿经过 扫条码 来添加销售订单SO中的商品。this
步骤一:(经过继承,在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)code
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挂件