Odoo v8中基于条件在其他模型增删记录的实现问题
问题分析与解决方案
先明确你现有代码的几个核心问题:
- 错误地在
create方法上使用@api.depends装饰器,这个装饰器仅用于计算字段,不能用来重写ORM的创建/写入方法。 - 重写
create时未调用super(),直接覆盖了Odoo原生的索赔记录创建逻辑,导致索赔本身无法正常生成。 - 没有建立索赔与发票的关联字段,后续无法定位需要删除的对应发票。
- 未处理
needs_credit_note从True改为False的删除场景,也没考虑合作伙伴变更时的发票更新逻辑。 - 创建发票时缺少必填字段(比如信用贷项单的类型、日记账ID),Odoo会因必填项缺失拒绝创建。
修正后的完整代码
1. 完善CRM索赔模型(添加关联字段)
from odoo import models, fields, api class crm_claim(models.Model): _inherit = 'crm.claim' needs_credit_note = fields.Boolean(string="Needs Credit Note?") partner_id = fields.Many2one('res.partner', string='Partner') # 添加关联字段,用于绑定生成的信用贷项通知单 invoice_id = fields.Many2one('account.invoice', string='Credit Note', readonly=True)
2. 实现创建/写入时的发票逻辑
@api.model def create(self, vals): # 先调用原生逻辑创建索赔记录 claim = super(crm_claim, self).create(vals) # 如果需要生成信用贷项单且已指定合作伙伴 if claim.needs_credit_note and claim.partner_id: # 创建信用贷项通知单(注意Odoo版本:旧版用type='out_refund',新版用move_type='out_refund') invoice = self.env['account.invoice'].create({ 'partner_id': claim.partner_id.id, 'type': 'out_refund', # 销售退款类型,对应信用贷项单 # 自动匹配销售退款日记账,可根据实际业务调整 'journal_id': self.env['account.journal'].search( [('type', '=', 'sale'), ('company_id', '=', claim.company_id.id)], limit=1 ).id, }) # 将发票与索赔关联 claim.write({'invoice_id': invoice.id}) return claim def write(self, vals): # 先执行原生写入逻辑 res = super(crm_claim, self).write(vals) # 仅当needs_credit_note或partner_id变更时处理发票逻辑 if 'needs_credit_note' in vals or 'partner_id' in vals: for claim in self: if claim.needs_credit_note: # 需生成发票但尚未生成,且已指定合作伙伴 if not claim.invoice_id and claim.partner_id: invoice = self.env['account.invoice'].create({ 'partner_id': claim.partner_id.id, 'type': 'out_refund', 'journal_id': self.env['account.journal'].search( [('type', '=', 'sale'), ('company_id', '=', claim.company_id.id)], limit=1 ).id, }) claim.invoice_id = invoice.id # 合作伙伴变更时同步更新发票的合作伙伴 elif claim.invoice_id and claim.invoice_id.partner_id != claim.partner_id: claim.invoice_id.write({'partner_id': claim.partner_id.id}) else: # 不需要信用贷项单时,删除关联发票并清空字段 if claim.invoice_id: claim.invoice_id.unlink() claim.invoice_id = False return res
关键说明
- 新增
invoice_id字段绑定索赔与发票,确保后续能精准找到对应记录进行删除/更新。 - 所有重写的ORM方法都先调用
super()保留原生逻辑,避免破坏Odoo原有功能。 - 针对
needs_credit_note状态变更、合作伙伴变更两种场景分别处理,覆盖所有业务情况。 - 创建发票时补充了必填的
type和journal_id字段,避免Odoo抛出创建错误(若使用Odoo 13+版本,需将type改为move_type)。
内容的提问来源于stack exchange,提问作者odoo newbie
相关产品推荐
相关产品推荐

