你們好,前端
接着上一章講,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掛件