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

Odoo会计模块自动生成account.payment.term.line记录的方法问题

问题分析与解决方案

咱们来拆解你代码里导致自动生成付款条款行失败的几个核心问题,再一步步给出修正方案:

问题点梳理

  1. 缺失字段定义:你在方法里用到了self.number_of_slices,但AccountPaymentTerm模型里并没有声明这个字段,这会直接引发错误,导致方法执行中断。
  2. onchange触发条件不全:付款条款行数由how_much和fixed_amount共同决定,但你只监听了fixed_amount的变化,how_much改动时不会触发生成逻辑。
  3. 子记录关联错误:在onchange阶段,如果是新建的付款条款(还未保存到数据库),self._origin.id是不存在的;而且Odoo处理one2many关联时,会自动绑定子记录的payment_id,不需要手动指定。
  4. 未将生成的子记录赋值给line_ids:你生成了子记录,但最后没有把这些记录赋值给self.line_ids,所以界面上不会显示新行。
  5. 循环逻辑不符合需求:你写了固定循环10次,但实际应该基于number_of_slices的计算结果生成对应行数。
  6. 除零风险:如果fixed_amount为0,除法运算会直接报错,需要提前处理。

修正后的完整代码

1. 完善AccountPaymentTerm模型

from odoo import models, fields, api

class AccountPaymentTerm(models.Model):
    _name = "account.payment.term"
    _description = "Payment Term"
    
    line_ids = fields.One2many('account.payment.term.line', 'payment_id', string='Terms', copy=True)
    period = fields.Selection([('month', '1 Month'),], string='Period', required=True, default='month', help="Select here the period between payments")
    how_much = fields.Float(string='Total Amount')
    fixed_amount = fields.Float(string='Fixed Amount per Slice')
    # 添加缺失的切片数字段,自动计算
    number_of_slices = fields.Integer(string='Number of Slices', compute='_compute_number_of_slices', store=True, readonly=False)

    @api.depends('how_much', 'fixed_amount')
    def _compute_number_of_slices(self):
        for term in self:
            if term.fixed_amount == 0:
                term.number_of_slices = 0
            else:
                # 可根据需求调整取整逻辑,比如向上取整用math.ceil
                term.number_of_slices = int(term.how_much / term.fixed_amount)

    @api.onchange('how_much', 'fixed_amount')
    def automate_creation(self):
        # 可选:清空已有条款行,若需保留原有行可删除此行
        self.line_ids = self.env['account.payment.term.line']
        
        # 校验参数合法性,避免无效计算
        if self.fixed_amount <= 0 or self.how_much <= 0 or self.number_of_slices <= 0:
            return
        
        # 生成对应数量的付款条款行
        new_lines = []
        for i in range(self.number_of_slices):
            # 根据period动态计算天数,比如每月递增30天
            days = 30 * (i + 1) if self.period == 'month' else 0
            new_lines.append((0, 0, {
                'value': 'fixed',
                'value_amount': self.fixed_amount,
                'days': days,
                'option': 'day_after_invoice_date'
                # 无需手动设置payment_id,Odoo会自动关联父记录
            }))
        
        # 将新行赋值给one2many字段
        self.line_ids = new_lines

2. 完善AccountPaymentTermLine模型

你原来的子模型只定义了payment_id,但生成行时用到的value、value_amount等字段必须存在,补充如下:

class AccountPaymentTermLine(models.Model):
    _name = "account.payment.term.line"
    _description = "Payment Term Line"
    
    payment_id = fields.Many2one('account.payment.term', string='Payment Terms', required=True, index=True, ondelete='cascade')
    value = fields.Selection([
        ('fixed', 'Fixed Amount'),
        ('percent', 'Percentage'),
        ('balance', 'Balance')
    ], string='Type', required=True)
    value_amount = fields.Float(string='Amount/Percentage')
    days = fields.Integer(string='Number of Days')
    option = fields.Selection([
        ('day_after_invoice_date', 'Day(s) after invoice date'),
        ('after_invoice_month', 'Day(s) after the end of the invoice month')
    ], string='Option', default='day_after_invoice_date')

关键修正说明

  • 字段补全:添加number_of_slices字段并通过@api.depends自动计算,同时处理了除零的异常情况。
  • 触发条件优化:onchange同时监听how_much和fixed_amount,确保任何一个值变化都会重新生成条款行。
  • 标准子记录创建:使用Odoo one2many的标准三元组格式(0, 0, {values})创建新记录,无需手动绑定payment_id。
  • 动态天数计算:根据period字段自动计算每个条款行的到期天数,更贴合实际业务场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:35:09