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

Odoo开发:如何跨模型获取InvoiceLine的ans值赋值给主模型total字段

实现方案

你原有代码存在多处设计和逻辑错误,先修正模型结构,再采用Odoo标准的计算字段逻辑做金额同步,是最稳妥可落地的方案,不会出现数据不一致问题。

原有代码的问题点

  • 模型继承逻辑完全错误:myinvoice.invoice.line 继承myinvoice.invoice会导致每新建一条明细就生成一条独立的发票主记录,完全违背发票头-明细行的一对多关系设计
  • 关联字段定义错误:明细行关联主表的字段命名为customer_id属于语义错误,且主表没有定义反向关联明细的字段,无法定位某张发票对应的所有明细
  • 计算逻辑存在bug:合计变量check定义在记录循环外,遍历结束后仅会给最后一条明细记录赋值,且跨发票遍历明细时会把不同发票的金额累加,结果完全错误
  • 依赖项缺失:行金额计算方法仅依赖数量字段,产品单价变动时不会自动重算行金额
  • 非法赋值:计算方法中直接给依赖字段quantity赋值,会触发递归重算问题
  • 字段拼写错误:数量字段quanitity拼写错误,正确拼写为quantity

修正后可直接运行的实现代码

1. 发票主表(myinvoice.invoice)修正

主表增加反向关联明细的One2many字段,total字段改为依赖明细行金额的计算存储字段,自动汇总所有明细的合计值,不需要额外做赋值传递:

from odoo import models, fields, api

class MyinvoiceInvoice(models.Model):
    _name = "myinvoice.invoice"
    _description = "发票主记录"

    # 反向关联所有发票明细行
    line_ids = fields.One2many(
        comodel_name='myinvoice.invoice.line',
        inverse_name='invoice_id',
        string='发票明细'
    )
    # 总金额:自动汇总明细行小计,开启数据库存储
    total = fields.Integer(string="发票总金额", store=True, compute='_compute_invoice_total')

    @api.depends('line_ids.line_total')
    def _compute_invoice_total(self):
        for record in self:
            # 汇总当前发票下所有明细行的小计值
            record.total = sum(record.line_ids.mapped('line_total'))

2. 发票明细表(myinvoice.invoice.line)修正

移除错误的主表继承,修正关联主表的字段,调整行金额计算逻辑:

class MyinvoiceInvoiceLine(models.Model):
    _name = "myinvoice.invoice.line"
    _description = "发票明细行"

    # 关联所属发票主记录,删除主记录时自动删除关联明细
    invoice_id = fields.Many2one(
        comodel_name='myinvoice.invoice',
        string='所属发票',
        required=True,
        ondelete='cascade'
    )
    product_id = fields.Many2one('myinvoice.product', string='关联产品')
    quantity = fields.Integer(string="数量", default=1)
    unit_price = fields.Integer(string="产品单价", related='product_id.price', readonly=False)
    line_total = fields.Integer(string="行小计", store=True, compute='_compute_line_total')

    @api.depends('quantity', 'unit_price')
    def _compute_line_total(self):
        for line in self:
            # 计算单行金额,空值时按0处理
            line.line_total = line.quantity * line.unit_price if line.quantity and line.unit_price else 0

方案说明

  • 该实现是Odoo官方标准的单据金额汇总方案,不需要额外定义中转字段ans,也不需要编写额外的赋值传递逻辑
  • 明细行新增、删除、数量/单价修改时,主表的total字段会自动触发重算并持久化到数据库,查询效率和普通字段一致,不会出现数据不一致问题
  • 如果你确实需要保留ans字段做中转,只需要在明细行计算完ans后,通过line.invoice_id.total = ans的方式赋值即可,但这种方式需要额外处理明细删除、修改关联发票等边界场景,不推荐使用

内容的提问来源于stack exchange,提问作者Krishna Chavda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:09:20