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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 21:15:08