采购警告

Odoo 采购警告为什么不是“弹个提示而已”:供应商、父级伙伴与产品警告的叠加边界讲透

很多人把 Odoo 的采购警告当成一个温和提示框,但源码里它其实是一套会按用户权限、伙伴层级与产品维度聚合的提示机制。本文把它真正的触发与展示边界讲透。

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

先说结论

Odoo 的采购警告不是“谁写了提示,界面就原样弹出来”这么简单。

/home/ubuntu/odoo-temp/addons/purchase/models/purchase_order.pyaccount_invoice.py 里,这套机制至少包含三层语义:

  1. 先看当前用户有没有采购警告权限组
  2. 再把供应商本人、父级伙伴、产品行警告合并起来
  3. 最后以聚合文本形式展示在采购单或供应商账单上

所以现场里常见的“同一张单,我能看到警告,采购员却看不到”“明明供应商没写警告,为什么页面还是有提示”,往往都不是 bug,而是这三层逻辑叠加出来的结果。


源码主链路:不是单字段显示,而是先聚合再输出

采购单的核心在:

  • purchase.order._compute_purchase_warning_text()
  • purchase.order.line.purchase_line_warn_msg

供应商账单侧还有一条对应链路:

  • account.move._compute_purchase_warning_text()

也就是说,Odoo 不是把一条 warning 字段直接塞到界面,而是先把多个来源整理成一段 purchase_warning_text

这决定了它更像“面向采购决策的风险摘要”,而不是“某个字段的原样展示”。


第一层边界:没有权限组,系统直接当没这回事

源码第一句就很直接:

  • 如果当前用户 不在 purchase.group_warning_purchase
  • purchase_warning_text 就直接置空

这意味着:

  • 警告数据可能真实存在
  • 但没有权限的用户,会像系统里根本没有警告一样

很多团队会误以为:

  • 警告字段坏了
  • 视图没继承好
  • 数据没保存成功

其实第一步应该先查用户组。

看不见,不代表没有;经常只是没有被允许看。


第二层边界:系统不只看供应商本人,还会看父级伙伴

在采购单与账单的聚合逻辑里,Odoo 都会同时检查:

  • partner_id.purchase_warn_msg
  • partner_id.parent_id.purchase_warn_msg

这背后的业务假设很现实:

  • 采购单上选中的,可能是某个联系人或分支机构
  • 但风险提醒,往往维护在供应商主体公司上

所以你界面上选的是联系人 A,不代表系统只看联系人 A。

如果它的父公司有采购警告,照样会进聚合结果。

这就是为什么很多人会说:

我明明没给这个联系人写 warning,为什么采购单上还有?

答案通常是:父级伙伴有。


第三层边界:产品警告不是订单级字段,而是逐行收集后再拼起来

采购单不会只看供应商,还会遍历每一条订单行。

如果某个产品有 purchase_line_warn_msg,它就会把:

  • 产品显示名
  • 产品警告文本

一起加入聚合结果。

这意味着订单级警告和行级警告并不是互斥关系,而是会同时存在。

于是现场上就会出现一种非常典型的情况:

  • 供应商没问题
  • 但某个受限物料、替代料、试用品有采购风险提示
  • 最终整张单依然出现一大段 warning

对业务来说,这反而更合理,因为采购决策本来就不只看“向谁买”,还要看“买什么”。


为什么它要用 OrderedSet,而不是简单字符串拼接

源码里用了 OrderedSet() 来收集警告。

这说明设计目标不只是“把内容都显示出来”,还包括:

  • 去重
  • 保留相对稳定的顺序
  • 避免同一条提示反复出现

这点很重要。

如果一个产品在多行重复出现,或者供应商与父级伙伴存在重复文本,系统不希望把同一句风险说明刷满整个页面。

也就是说,Odoo 想表达的是:

让采购员知道有哪些风险点,而不是制造阅读噪音。


它为什么还会出现在 Vendor Bill 上

很多人以为采购警告只属于 RFQ/PO 阶段,但 account_invoice.py 里也做了同样的聚合。

这代表 Odoo 的设计不是“下单时提醒一次就完了”,而是把采购风险继续延续到:

  • 供应商账单录入
  • 对账与入账判断

这很有实际意义。

因为很多风险并不会在下单那一刻消失,例如:

  • 该供应商需先核对资质
  • 某产品需要补齐检验资料
  • 某类账单需要人工复核

如果只在 PO 看得到,到 Bill 阶段反而容易遗漏。


最容易误解的 4 个点

1. 以为 warning 是“阻断逻辑”

默认这套机制更多是提示,不等于自动禁止确认或过账。

2. 以为只要 partner 没写警告,就不会有提示

父级伙伴和产品行同样会参与聚合。

3. 以为数据有了,所有人都看得到

权限组先行,没组就直接清空。

4. 以为这只是采购单界面的小功能

其实它已经延伸到 Vendor Bill,说明它是采购风险提示链的一部分。


实战排错顺序

如果你遇到“为什么这里有警告 / 为什么这里没有警告”,建议按这个顺序排:

  1. 先查用户是否具备 purchase.group_warning_purchase
  2. 再查供应商本人 purchase_warn_msg
  3. 再查父级伙伴 purchase_warn_msg
  4. 逐行检查产品的 purchase_line_warn_msg
  5. 确认是不是重复内容被 OrderedSet 去重了
  6. 如果是账单页,再确认 invoice line 是否已经正确关联到采购行/产品

这样排,比在视图里盲找字段快得多。


对实施和开发的提醒

如果你要做采购风控定制,不要急着改前端提示框。

更值得先想清楚的是:

  • 你要把 warning 当提示,还是当阻断?
  • 你要不要把公司级、品类级风险也纳入聚合?
  • 你要不要让不同角色看不同层级的 warning?

因为 Odoo 现成这套实现,本质上已经是一个“轻量级采购风险汇总器”。

很多团队做二开失败,不是技术写不出来,而是一上来就把它简化成“某字段弹窗”。


一句话记忆法

Odoo 采购警告不是单点提示,而是按权限、伙伴层级和产品行聚合出来的一段采购风险摘要。

DISCUSSION

评论区

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