先说结论
Odoo 的采购对账工作台,不是简单“列出几张账单让你选”。
它更像一个匹配中心:
- 从采购单或供应商入口触发
- 把符合条件的账单行拉到一个专门视图里
- 按伙伴、公司和采购单范围过滤
- 让 PO 行和账单行在同一个工作台里完成配对
所以它解决的不是“看账单”,而是“把应匹配的行找出来并拼到一起”。
action_bill_matching 在做什么
源码里的 action_bill_matching() 很直接:它返回一个窗口动作,指向 purchase.bill.line.match。
这个动作不是打开普通账单列表,而是带着一组过滤条件:
- 伙伴在当前供应商或其商业伙伴范围内
- 公司必须匹配当前公司
- 采购单可以是当前单据或未绑定采购单的候选行
这说明 Bill Matching 不是“全部账单通看”,而是专门为采购对账准备的聚合视图。
为什么要单独做一个工作台
采购账单匹配最麻烦的地方,不是数据少,而是关系复杂:
- 一张采购单可能对应多张账单
- 一张账单也可能来自多个采购来源
- 部分收货、部分开票、部分残差都需要人工判断
如果把这些都放在普通账单列表里处理,效率会很低。
所以 Odoo 选择把它们拉进一个专门的匹配界面,减少业务员来回切页面。
自动匹配和人工匹配的边界
工作台通常会先尽量自动匹配。
但只要出现下面这些情况,就还是要人工介入:
- 数量不完全一致
- 价格有残差
- 采购单和账单来源不一一对应
- 部分项需要保留为未匹配状态
这也是为什么“匹配视图”比“自动生成”更重要:它保留了业务判断空间。
残差边界为什么重要
采购账单经常不是整单 1:1 对应。
一旦有:
- 小数差
- 税差
- 运费分摊
- 部分收货
就会出现残差。
工作台存在的价值,就是把这些残差显式暴露出来,而不是偷偷塞进某个总额里,让后续对账更难查。
调试时该怎么想
如果匹配结果不对,先看这几个点:
- action 返回的过滤域对不对
- 当前公司和伙伴范围是否正确
- 是否已经把采购单和未绑定行都纳入候选
- 是否被残差或状态过滤挡住了
- 视图里是不是只看到了部分候选而不是全部
很多“为什么没出来”的问题,其实是域条件不对,不是匹配算法坏了。
实战建议
- 不要把 Bill Matching 当成普通账单列表
- 它本质上是一个工作台,不是一个明细报表
- 调试时先看过滤域,再看视图效果
- 残差不是错误,而是对账需要管理的边界
- 给业务解释时,可以说它是“采购到账单的拼装台”
一句好记的话
Bill Matching 不是“看账单”,而是把 PO 行和账单行放到同一个拼装台上完成对账。
这个视角一变,很多采购对账问题就很好理解了。
DISCUSSION
评论区