前一篇介紹了如何在視圖和表單中添加字段。本節內容,我們討論下如何在明細中加字段。
我想在銷售頁面明細中增加稅額字段,這在表sale.order.line中已經存在,在此僅用來演示。
odoo的明細一般都是One2many字段,通過Tab頁或直接以列表形式展示在表單視圖中,如下:
主要關注的是字段名order_line,屬於模型sale.order,是一個one2many字段,關聯的是sale.order.line模型。展示的列表如下:
訂單行如圖所示,列表中所展示的字段,都是sale.order.line模型中的字段。
因此,我們要想在訂單行(以下簡稱明細)中增加字段,就需要在對應的sale.order.line模型中添加字段。
在models目錄中創建sale_order_line_extension.py文件,在__init__.py文件中引用。
sale_order_line_extension.py中代碼如下:
1 # -*- coding:utf-8 -*-
2 """銷售訂單行擴展"""
3
4 from odoo import models, fields, api 5
6 # 銷售訂單行擴展
7 class SaleOrderLineExtension(models.Model): 8 """銷售訂單行擴展"""
9 _inherit = 'sale.order.line'
10
11 # 稅額
12 x_price_tax = fields.Monetary(string='稅額', compute='_get_line_price_tax') 13
14 # 獲取訂單行稅額
15 @api.multi 16 def _get_line_price_tax(self): 17 """
18 獲取訂單行稅額 19 :return: None 20 """
21 if self: 22 # self是訂單行對象數據集
23 # 遍歷數據集
24 for line in self: 25 # 稅率
26 tax = sum(line.tax_id.mapped('amount')) / 100
27 # 單價
28 price = line.price_unit 29 # 數量
30 number = line.product_uom_qty 31 # 稅額 = 不含稅銷售額 × 稅率
32 # 不含稅銷售額 = 含稅價 / (1 + 稅率)
33 line.x_price_tax = (price / (1 + tax) * tax) * number
增加的稅額字段x_price_tax是一個Monetary字段,在odoo中主要用於貨幣問題,需要定義一個currency_id字段,並在xml中引用。
currency_id = fields.Many2one('res.currency', 'Currency')
<tree>
<field name="currency_id" invisible="1" />
<field name="x_price_tax" />
</tree>
在xml中增加currency_id字段后,主要效果是出現了貨幣符號。(個人觀點,不知是否正確,供參考)
在源碼的tree中已經存在該字段,不需要添加,上面僅用於演示。
另外,x_price_tax字段是一個計算字段,這種類型的字段不會存儲到數據庫中,如果需要存儲,可以增加stroe=True屬性。
x_price_tax = fields.Monetary(string='稅額', store=True, compute='_get_line_price_tax')
在代碼中,我使用了mapped()函數處理了一個many2many字段tax_id。這個函數是odoo提供的,能夠直接提取出某個字段的列表,或使用一個lambda表達式,對要獲取的值進行加工處理。這個方法在實際開發中,是很常用的,主要用於2many字段。
打開銷售頁面,self對應的是一個sale.order.line數據集,可以通過遍歷的方式,獲取每一個數據集,對每個數據集的數據進行處理。這在處理明細邏輯時要注意,很容易出現的錯誤是:
sale.order.line(1, 2) /home/sam/odoo12/odoo/odoo/models.py(4692)ensure_one() raise ValueError("Expected singleton: %s" % self)
我只是在代碼中增加了:
self.x_price_tax = 0
報錯的原因就是self是一個多訂單行的數據集,對於數據集的處理要確保是單一對象。
注意:如果你加了store=True,只會在第一次加載時進行計算,當第二次加載時就從數據庫中直接查詢了。
下面是xml中的內容:
<record id="view_order_form_modify" model="ir.ui.view">
<field name="name">view.order.form.modify</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<!-- 增加``銷售員``字段 -->
<xpath expr="//group/group/field[@name='partner_id']" position="after"
>
<field name="x_salesman" />
</xpath>
<!-- 在訂單行中,增加``稅額``字段 -->
<xpath expr="//tree/field[@name='tax_id']" position="after"
>
<field name="x_price_tax" />
</xpath>
</field>
</record>
可能會有疑惑,為什么sale.order.line中的字段可以直接加在sale.order模型的視圖中。我們來看一下源碼:
<page string="Order Lines" name="order_lines">
<field name="order_line">
<tree string="Sales Order Lines">
<field name="tax_id" />
</tree>
由於源碼太多,我不得不對它進行刪減,說明問題足夠了,源碼是開發過程中最好的老師。
在page標簽內,有一個字段,該字段就是訂單行order_line。
能夠看到tree標簽是添加在order_line字段內部的,我們新增的字段是增加到tree標簽內的。實際上,我們是在定義的sale.order.line的列表中增加了一個稅額字段。因此,odoo並沒有提示錯誤。
如果,我們在銷售員字段所在的視圖中添加稅額,則會報如下錯誤:
字段`x_price_tax`不存在
1 <xpath expr="//group/group/field[@name='partner_id']" position="after">
4 <field name="x_salesman" />
5 <field name="x_price_tax" />
6 </xpath>
添加成功后顯示如下:
在明細中添加字段的介紹,就介紹到這,下一篇我們來討論下如何添加按鈕。