1. 程式人生 > >Odoo自定義Widgets

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掛件