Odoo15使用首付款时如何将销售订单行新字段值传递至发票行
Odoo 15 销售订单行自定义字段传递至发票行(适配首付款场景)实现方案
Odoo15 中普通销售开票和首付款开票走两套独立的发票行生成逻辑,仅覆盖常规的_prepare_invoice_line方法无法覆盖首付款场景,需同时适配两套逻辑,具体操作如下:
1. 前置:在两个模型定义一致的自定义字段
首先新建自定义模块,分别在销售订单行(sale.order.line)、发票行(account.move.line)定义类型、字段名完全一致的自定义字段,示例代码如下(以文本类型的业务备注字段为例,其他字段类型逻辑一致):
from odoo import models, fields # 销售订单行添加自定义字段 class SaleOrderLine(models.Model): _inherit = 'sale.order.line' x_custom_business_remark = fields.Char(string='业务备注') # 发票行添加同名字段 class AccountMoveLine(models.Model): _inherit = 'account.move.line' x_custom_business_remark = fields.Char(string='业务备注')
2. 适配普通销售开票场景的字段传递
继承销售订单行模型,重写发票行值准备方法,将自定义字段追加到映射字典中,该逻辑会覆盖非首付款的正常开票场景:
class SaleOrderLine(models.Model): _inherit = 'sale.order.line' def _prepare_invoice_line(self, **optional_values): res = super()._prepare_invoice_line(**optional_values) # 追加自定义字段映射 res['x_custom_business_remark'] = self.x_custom_business_remark return res
3. 核心:适配首付款场景的特殊字段传递
首付款发票行由首付款向导(sale.advance.payment.wizard)直接生成,不会调用上述_prepare_invoice_line方法,需单独继承向导的首付款行值准备方法做映射:
class SaleAdvancePaymentWizard(models.TransientModel): _inherit = 'sale.advance.payment.wizard' def _prepare_down_payment_invoice_line_values(self, order, so_line, amount): res = super()._prepare_down_payment_invoice_line_values(order, so_line, amount) # so_line为系统自动生成的首付款销售订单行,直接取该行的自定义字段值传入发票行 res['x_custom_business_remark'] = so_line.x_custom_business_remark return res
如果你需要把原SO非首付款行的字段值同步到首付款发票行,只需要在上述方法中从order.order_line对应行取值,替换
so_line.x_custom_business_remark为你需要的取值逻辑即可。
4. 操作验证步骤
- 将上述代码写入自定义模块的对应py文件,更新模块依赖清单(
__manifest__.py)中需依赖sale、account模块 - 升级自定义模块,确认销售订单行、发票行上均可看到新增的自定义字段
- 新建测试销售订单,添加订单行并填写自定义字段值,点击「首付款」按钮输入金额生成首付款发票
- 查看生成的首付款发票行,确认自定义字段值已自动携带
- 后续开具该SO剩余金额的全额发票,检查正式发票行的自定义字段值同步正常
注意事项
- 两个模型的自定义字段名称、字段类型必须完全匹配,避免出现类型不匹配的报错
- 所有逻辑均通过继承实现,禁止直接修改Odoo原生源码,避免版本升级或模块更新时覆盖自定义逻辑
- 如果自定义字段为Many2one/ Many2many类型,需确保发票行对应字段关联的模型权限对开票用户开放,否则会触发权限异常
- 多个自定义字段需要传递时,只需要在上述两个prepare方法中按相同格式追加字段键值对即可
内容的提问来源于stack exchange,提问作者Amr Wahba
相关产品推荐
相关产品推荐

