OdooV14通过布尔字段控制报价单序列自定义前缀失效问题
Odoo报价单序列前缀动态切换问题排查
现有代码的核心问题
- 格式化语法错误:最终返回字符串时使用了3个占位符
%s-%s-%s,但仅传入了prefix、suffix两个参数,运行时会直接抛出参数不匹配异常,导致生成失败。 - 方法调用逻辑缺失:Odoo原生
sale.order的名称生成逻辑默认不会调用你自定义的_get_sequence方法,你没有覆盖create方法关联自定义序列生成逻辑,修改后的规则根本没有生效入口。 - 序列拆分逻辑鲁棒性差:假设你的
quotation.seq序列原生结构不是严格的前缀-后缀两段式(比如带年份、月份标识),split('-')会返回超过2个元素,直接赋值给两个变量会触发异常,导致返回New而不是预期的编号。 - 序列消耗不合理:你调用
next_by_code时已经消耗了一个原生序列号,仅修改前缀的逻辑会浪费序列资源,且如果多用户同时创建单据时容易出现编号冲突。
修正后的实现方案
import logging from odoo import models, fields, _ class SaleOrder(models.Model): _inherit = 'sale.order' prefix_choice = fields.Boolean(string="Set to OL", default=False) def create(self, vals): # 新建单据时优先根据布尔值生成对应前缀的编号 if vals.get('name', _('New')) == _('New'): prefix = 'OL' if vals.get('prefix_choice', False) else 'BE' # 建议提前在系统中创建两个分别对应BE、OL前缀的销售序列 seq_xml_id = 'sale.quotation_seq_ol' if prefix == 'OL' else 'sale.quotation_seq_be' vals['name'] = self.env['ir.sequence'].next_by_code(seq_xml_id) or _('New') return super(SaleOrder, self).create(vals) def write(self, vals): # 如果修改了prefix_choice字段,同步更新单据编号前缀 if 'prefix_choice' in vals: for order in self: if order.name != _('New'): # 拆分原有编号的后缀部分(适配多段式编号取最后一段为流水号) name_parts = order.name.split('-') suffix = name_parts[-1] new_prefix = 'OL' if vals['prefix_choice'] else 'BE' order.name = f"{new_prefix}-{suffix}" return super(SaleOrder, self).write(vals)
额外注意事项
- 提前在Odoo后台设置-技术-序列与标识符-序列中创建两个对应前缀的销售报价单序列,分别设置好前缀、流水号位数、步长等参数,避免编号冲突。
- 如果不需要支持修改已有单据的前缀,可以删掉
write方法里的相关逻辑,仅保留create方法的生成规则即可。
内容的提问来源于stack exchange,提问作者Gbn
相关产品推荐
相关产品推荐

