Odoo会计模块自动生成account.payment.term.line记录的方法问题
问题分析与解决方案
咱们来拆解你代码里导致自动生成付款条款行失败的几个核心问题,再一步步给出修正方案:
问题点梳理
- 缺失字段定义:你在方法里用到了
self.number_of_slices,但AccountPaymentTerm模型里并没有声明这个字段,这会直接引发错误,导致方法执行中断。 - onchange触发条件不全:付款条款行数由
how_much和fixed_amount共同决定,但你只监听了fixed_amount的变化,how_much改动时不会触发生成逻辑。 - 子记录关联错误:在onchange阶段,如果是新建的付款条款(还未保存到数据库),
self._origin.id是不存在的;而且Odoo处理one2many关联时,会自动绑定子记录的payment_id,不需要手动指定。 - 未将生成的子记录赋值给line_ids:你生成了子记录,但最后没有把这些记录赋值给
self.line_ids,所以界面上不会显示新行。 - 循环逻辑不符合需求:你写了固定循环10次,但实际应该基于
number_of_slices的计算结果生成对应行数。 - 除零风险:如果
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
相关产品推荐
相关产品推荐

