如何基于decimal_digit字段修改quantity字段的小数位数
解决方案:基于AccountInvoice的decimal_digit动态调整AccountAnalyticInvoiceLine的quantity小数位数
原代码存在的问题
- 字段名错误:onchange方法监听的
decimal_digits不存在,AccountInvoice中定义的字段是decimal_digit - 触发源错误:AccountAnalyticInvoiceLine本身没有
decimal_digit字段,应该监听关联的invoice_id.decimal_digit变化 - Float字段的
digits参数是静态硬编码,无法动态跟随发票的decimal_digit值变化
具体实现代码
1. 修改AccountAnalyticInvoiceLine模型
from odoo import models, fields, api class AccountAnalyticInvoiceLine(models.Model): _inherit = 'account.analytic.invoice.line' # 动态绑定小数位数,关联发票的decimal_digit配置 quantity = fields.Float( digits='_get_quantity_digits', help="待开票数量" ) @api.model def _get_quantity_digits(self): # 优先取关联发票的小数位,默认保留2位 for line in self: if line.invoice_id and line.invoice_id.decimal_digit: return (16, line.invoice_id.decimal_digit) return (16, 2) @api.onchange('invoice_id', 'invoice_id.decimal_digit') def _onchange_invoice_decimal_digit(self): # 发票或其小数位变化时,实时按指定位数四舍五入 if self.invoice_id and self.invoice_id.decimal_digit is not None: self.quantity = round(self.quantity or 0.0, self.invoice_id.decimal_digit) @api.model_create_multi def create(self, vals_list): # 创建记录时强制按发票配置处理小数位 for vals in vals_list: invoice = self.env['account.invoice'].browse(vals.get('invoice_id')) if invoice and invoice.decimal_digit is not None and 'quantity' in vals: vals['quantity'] = round(vals['quantity'], invoice.decimal_digit) return super().create(vals_list) def write(self, vals): # 更新记录时强制按发票配置处理小数位 if 'quantity' in vals or 'invoice_id' in vals: for line in self: decimal_digit = line.invoice_id.decimal_digit if line.invoice_id else 2 qty = vals.get('quantity', line.quantity) vals['quantity'] = round(qty, decimal_digit) return super().write(vals)
2. 视图调整(可选,确保前端显示匹配)
如果动态digits在前端视图中未生效,可以在AccountAnalyticInvoiceLine的表单视图中,为quantity字段指定动态显示位数:
<field name="quantity" widget="float" digits="[16, invoice_id.decimal_digit]"/>
关键说明
- 动态小数位数方法
_get_quantity_digits会根据每条记录关联的发票返回对应的位数配置 onchange方法实时响应发票关联关系或decimal_digit的变化,自动调整quantity数值create和write方法确保数据保存时严格按指定小数位四舍五入,避免数据不一致- 若使用Odoo 10及以下版本,动态digits方法可能不支持,可仅通过视图指定显示位数,同时保留业务逻辑中的数值处理逻辑
内容的提问来源于stack exchange,提问作者Alwaysstuck
相关产品推荐
相关产品推荐

