大家好,
接着上一章讲,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挂件