先说结论
在 Odoo 里,业务单号通常不是“随手拼一个字符串”,而是由 ir.sequence 这套编号机制统一管理的。
它真正解决的问题不是好不好看,而是:
- 什么时候生成编号
- 编号是否唯一
- 编号是否可追溯
- 不同业务对象是否能按自己的规则出号
所以序列不是装饰层,它是业务对象身份管理的一部分。
为什么编号问题比看起来更重要
因为很多业务对象一旦进入正式流程,用户记住的往往不是数据库 id,而是业务单号。
比如:
- 销售单号
- 采购单号
- 发票号
- 库存单号
这些编号会进入:
- 沟通
- 对账
- 审计
- 打印件
- 下游系统对接
所以它不只是“页面显示文字”,而是业务识别符。
ir.sequence 本质上是什么
最实用的理解是:
一套受规则约束的业务编号生成器。
它通常会定义:
- 前缀
- 后缀
- 数字位数
- 当前序号
- 是否按日期范围拆分
也就是说,它不是只给你一个自增整数,而是在生成“有业务格式的唯一编号”。
为什么很多模型不会在一创建时就立刻有正式单号
因为“创建草稿”和“进入正式业务阶段”往往不是同一个时刻。
这很关键。
有些对象在草稿时可以先是:
/New- 临时占位值
等到真正确认、保存、过账或提交时,才拿正式序列。
这背后的设计逻辑是:
不是一出生就值得占用正式业务编号。
这样能避免草稿乱占号,也更符合真实业务边界。
为什么有时要按日期范围出号
因为很多业务编号不只是“越来越大”,还带有时间维度管理需求。
例如:
- 年度重置
- 月度重置
- 某会计期间单独编号
这时日期范围序列就很有用。
它解决的不是“格式花一点”,而是:
- 编号更可读
- 年/月归属更清楚
- 某些财务或运营规则更容易落实
为什么序列问题经常和并发、唯一性连在一起
因为编号一旦进入正式业务世界,通常就不能随便撞号。
所以序列机制真正难的地方往往不是“拼字符串”,而是:
- 高并发下别重复
- 多用户同时操作时别乱序到不可接受
- 回滚、草稿、确认时别把边界搞混
这也是为什么很多看似“简单的单号定制”,做深了就会碰到一致性问题。
实战里最容易踩的 5 个坑
1. 自己手搓编号,不走序列
后面唯一性和维护都会痛。
2. 草稿阶段就过早占正式号
会制造很多空洞编号和理解混乱。
3. 忽略日期范围需求
后来业务又要按年/月管理时很难补。
4. 把编号当成纯显示字段
结果没有把它当业务身份认真设计。
5. 定制时没考虑并发边界
这类问题平时不明显,量一上来就暴露。
一句话记忆法
把它记成一句话:
ir.sequence管的不是“字符串怎么拼”,而是业务对象在正式流程里如何稳定、唯一、按规则地拿到自己的身份编号。
理解这一句,Odoo 单号机制就会清楚很多。
DISCUSSION
评论区