You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:25:27