重复RFQ

Odoo 草稿采购单为什么会提示“疑似重复”:partner_ref、origin 与重复 RFQ 识别边界讲透

很多人以为 Odoo 采购重复检查会比对整张单的明细,但源码里它主要盯的是公司、供应商、partner_ref 和 origin/name 的关系,而且只对草稿单起作用。本文把这条去重边界讲透。

采购
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的采购去重提醒,不是在比“这两张单明细是不是一模一样”。

/home/ubuntu/odoo-temp/addons/purchase/models/purchase_order.py 里,_compute_duplicated_order_ids()_fetch_duplicate_orders() 关注的核心条件是:

  • 同公司
  • 同供应商
  • 非取消状态
  • 当前单有 partner_ref
  • 并且满足以下任一:
  • 当前单 origin = 另一张单.name
  • 当前单 partner_ref = 另一张单.partner_ref

换句话说,它识别的是:

业务引用关系上的疑似重复

而不是“采购行逐行完全相同”的重复。


为什么它只对 draft 单做这件事

源码里先把记录限定为:

  • state == 'draft'

这背后的意思很清楚:

  • 去重提醒的最佳时机,是你还没正式确认前
  • 一旦单据已进入正式流程,系统更倾向于保留事实,而不是继续强行怀疑它重复

这很合理。

因为草稿阶段的重复,通常意味着:

  • 录单员重复录了
  • 邮件导入重复生成了 RFQ
  • 供应商参考号被重复使用

而确认后的重复,往往已经变成需要业务判断和审计处理的问题,不适合再用“轻提醒”一把梭。


它为什么强依赖 partner_ref

_fetch_duplicate_orders() 里首先把当前单过滤成:

  • id
  • 且有 partner_ref

没有 partner_ref 的单据,直接不参与这条重复识别。

这说明 Odoo 设计者认为:

  • 采购内部编号 name 是自己生成的
  • 真正最容易反映“外部世界是不是同一笔业务”的,是供应商参考号

这在现实里非常成立。

因为重复 RFQ 最常见的线索,不是两个内部单号相似,而是:

  • 同一家供应商
  • 同一个 vendor quotation / acknowledgement / reference
  • 却被系统或人工录成两张草稿单

origin = duplicate_po.name 这一句为什么很值钱

这行条件看起来不起眼,其实很有意思。

它不是在比较两个 origin 是否相等,而是检查:

  • 当前单的 origin
  • 是否直接指向另一张采购单的 name

这能抓住一种很常见但容易漏掉的重复模式:

  • 某张新 RFQ 并不是完全独立创建
  • 而是从另一张采购单、补货链或整合流程衍生出来
  • 结果又被当成独立采购需求继续处理

也就是说,Odoo 在尝试识别“从别的采购单长出来的重复分支”。


为什么它不用采购行明细做比对

很多人第一次看到这个逻辑,会问:

  • 为什么不比产品、数量、价格?

答案其实很现实:

1. 明细级查重成本更高

不仅查询更重,误报率也高。

2. 采购重复往往先暴露在引用层

例如同一个 vendor reference 被录了两次,比“两张单正好买一样的东西”更有说服力。

3. Odoo 这里做的是提醒,不是法务级判定

它要的是高性价比地找出“值得你看一眼”的可疑草稿,而不是给你一个绝对判决。


最容易误解的 4 个点

1. 以为所有采购单都会被重复识别

不是,重点是草稿单。

2. 以为没提示就一定不重复

如果没有 partner_ref,这条链根本不会工作。

3. 以为提示重复是因为采购行完全一样

源码主判断不看明细。

4. 以为这是阻断逻辑

它更像风险提醒,不是绝对禁止你继续操作。


排错顺序

如果你想解释“为什么这张 RFQ 被判重复 / 为什么没被判重复”,建议按这个顺序看:

  1. 当前单是否仍为 draft
  2. 当前单是否有 partner_ref
  3. 同公司同供应商下,是否有别的非取消采购单共享同样 partner_ref
  4. 当前单 origin 是否等于另一张采购单的 name
  5. 如果仍不符合预期,再考虑是否需要你自己的明细级查重扩展

一句话记忆法

Odoo 采购重复识别查的不是“明细像不像”,而是“这张草稿单在业务引用上像不像另一张已存在的采购单”。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。