自动采购

Odoo 自动采购为什么有时会报“找不到供应商”,有时又偷偷继续:orderpoint 优先级与 fallback 供应商链讲透

很多团队以为自动补货找不到供应商就一定失败,但 Odoo 在 buy rule 里其实分 orderpoint 场景与普通场景,还可能回退到“没有价格但能用”的供应商。本文把这条供应商决策链讲透。

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

先说结论

Odoo 自动采购“找供应商”的逻辑,不是单一步骤,也不是永远找不到就报错。

/home/ubuntu/odoo-temp/addons/purchase_stock/models/stock_rule.py_get_matching_supplier()_run_buy() 里,顺序大致是:

  1. 如果上下文明确给了 supplierinfo_id,优先用它
  2. 否则,如果来自补货规则且 orderpoint 上指定了供应商,优先用 orderpoint 供应商
  3. 再不行,走产品的 _select_seller() 正常筛选
  4. 如果还没有,尝试从当前公司可见 supplier 里拿第一条做 fallback
  5. 但在某些 from_orderpoint 场景下,又会直接抛异常阻止生成采购单

所以看起来“有时失败、有时又继续”的根因,不是系统随机,而是场景分叉不同。


第一优先级:显式指定永远比自动猜测更强

源码把 supplierinfo_id 放在最前面,这其实很合理。

因为一旦上游已经明确告诉系统:

  • 就用这条 supplierinfo

那后面的日期、优先级、默认选择都不该再争权。

这代表 Odoo 在自动采购上采用了一个很稳的原则:

显式业务决定 > 自动选择算法。


第二优先级:orderpoint 指定供应商,不只是“建议”

如果值来自 orderpoint_id,而且补货规则上挂了 supplier_id,源码会直接选它。

这说明在自动补货语境下,orderpoint 的供应商不是轻飘飘的推荐项,而是会真正改变采购去向。

这也解释了很多现场现象:

  • 产品本身有多个供应商
  • 但补货时总走固定那一家

不是 _select_seller() 失灵,而是 orderpoint 在更上层先把结果锁定了。


第三层:正常自动选择,才轮到 _select_seller()

只有前两层都没有明确答案时,系统才会走标准供应商选择链。

这时才会综合考虑:

  • 供应商有效期
  • 最小起订量
  • 单位
  • 数量
  • 公司边界

所以很多人把自动采购问题直接归咎于 _select_seller(),其实常常是错位排查。

你得先确定是不是早在 supplierinfo_id 或 orderpoint 阶段就已经决定好了。


最容易误解的一层:fallback 供应商并不等于“合理报价供应商”

源码有一句注释写得很坦白:

  • 如果正常没找到 supplier
  • 就退回到当前公司可见的第一条 seller
  • 这不理想,但总比完全阻塞用户更好

这意味着 fallback 的语义不是:

  • 找到一个正确供应商

而是:

  • 先找一个还能继续走下去的供应商

因此你看到系统“明明没有有效供应商条件,却还是建出了采购单”,不要急着夸它聪明。

它可能只是选择了一个可用但并不精确的兜底答案。


为什么 from_orderpoint 场景反而会报错更硬

_run_buy() 里,如果:

  • 没找到 supplier
  • 并且上下文里是 from_orderpoint

系统会抛出一个明确异常,提示你去产品上补全 vendor 列表。

这看似和前面的 fallback 有矛盾,其实不矛盾。

因为补货规则场景下,系统更强调:

  • 自动化补货需要可预期、可维护的供应商条件

如果在 orderpoint 自动补货里也大量使用模糊 fallback,长期会把计划体系带偏。

所以这里宁可失败得更明确。


最容易误解的 5 个点

1. 以为自动采购总是直接 _select_seller()

其实前面还有显式 supplierinfo 与 orderpoint 优先级。

2. 以为 orderpoint 供应商只是建议

源码里它是真优先项。

3. 以为 fallback 说明系统找到了合理供应商

很多时候只是找到了一个能继续跑的兜底候选。

4. 以为找不到供应商时永远同样报错

from_orderpoint 和普通场景处理并不一样。

5. 以为自动采购错供应商一定是价格问题

根因可能在更前面的优先级覆盖。


排错顺序

如果你想查“自动采购为什么选了这个供应商 / 为什么没生成采购单”,建议按这个顺序:

  1. 是否传入了 supplierinfo_id
  2. 是否来自 orderpoint,且 orderpoint 上有 supplier_id
  3. 正常 _select_seller() 会选谁
  4. 有没有触发 fallback supplier
  5. 当前上下文是否是 from_orderpoint,从而改成硬报错
  6. 如果没供应商,相关 move 是被取消了,还是被回退成 MTS

一句话记忆法

Odoo 自动采购选供应商,顺序不是“直接比价”,而是“显式指定 → 补货规则指定 → 正常选择 → 模糊兜底 → 某些场景硬失败”。

DISCUSSION

评论区

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