Odoo自定義Widgets
阿新 • • 發佈:2018-12-04
大家好,
接著上一章講,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掛件