销售警告边界

Odoo 销售警告为什么不只是“弹个窗”:partner/product warnings、blocking 与 message 传播边界讲透

销售里最容易被低估的机制之一,就是 warning。很多人以为它只是给销售员看个提示,但官方源码显示,partner warning、product warning、阻塞策略和 chatter/message 的传播方式都带着明确边界。本文重点讲清 warning 到底是 UI 提示、业务阻断,还是可追溯消息。

销售
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 7 阅读

先说结论

Odoo 销售里的 warning,从来不只是“弹个窗提醒一下”。

它至少有三层不同语义:

  1. 提醒语义:告诉销售员这单有风险
  2. 阻断语义:在某些节点不允许继续推进
  3. 消息语义:把某次业务动作写进 chatter / message history,形成可追溯记录

而这三层语义,并不是自动混在一起的。

很多实施误解 warning,往往就是因为把三件事混成一件:

  • 以为看到提示就等于已经阻止业务
  • 以为阻止业务就一定会自动写 message
  • 以为 message 里有记录,就代表业务规则已经被执行

实际上,官方源码对这些边界划得非常清楚。


先分清两类对象:partner warning 和 product warning

sale 模块继承关系来看,销售单上的 warning 主要来自两种来源:

1. Partner 侧

例如客户、发票联系人、送货联系人带来的 warning / blocking 语义。

2. Product 侧

例如某个商品不适合卖给当前客户、需要额外提醒、或者应该阻止继续添加。

这和采购场景类似:warning 不是单一字段,而是主数据在交易单据上的风险投影

所以 warning 的第一重理解不是“订单表单上多了个红字”,而是:

客户与商品主数据里的风险规则,沿着销售录单链路向 sale.order / sale.order.line 传播。


warning 的第一层,是交互提示,不等于最终业务裁决

在绝大多数一线使用者眼里,warning 最明显的表现就是:

  • 选了客户,弹一个警告
  • 选了产品,弹一个警告

但从机制上说,这只是第一层:UI 反馈

UI 反馈解决的是:

  • 销售员是否被及时提醒
  • 风险是否在录单当下暴露

它没有天然保证:

  • 后续一定不能确认订单
  • 后续一定不能开票
  • 这次提示一定会形成可追溯历史

所以 warning 的一个基本边界是:

UI 提示 ≠ 阻断规则

你看到了 warning,只能说明系统把风险告诉了当前操作者;不代表这件事已经被制度化地拦住。


blocking 的关键,不在“文字更凶”,而在流程节点是否被拒绝

业务里常见两种误解:

  • 把“Warning”理解成软性提醒
  • 把“Blocking Message”理解成只是更强硬的提示文案

但从系统设计看,真正的 blocking 边界不在文案,而在:

某个动作是否被真正拒绝执行。

比如一个客户可能有销售警告;一个产品也可能有销售警告。

实施真正要关心的是:

  • 是在选 partner / product 时阻止继续录入
  • 还是允许录入、但在确认时阻止
  • 还是只提示、由销售自行判断是否继续

也就是说,阻塞不是“长得像提示框”,而是对业务流转动作产生硬结果

这也是为什么成熟实施要单独梳理:

  • 哪些 warning 只是信息提示
  • 哪些 warning 必须升级为 blocking
  • blocking 发生在哪个节点最合理

message 传播是另一条链:记录发生了什么,不等于决定能不能做

在销售主链里,很多关键动作都会额外 message_post(...)

例如预付款发票创建时,系统会在订单和发票上都写消息,记录:

  • 发票从哪个销售单创建
  • 某张 Down payment invoice 已生成

这给我们一个很重要的参照:

Odoo 的 message/chatter 语义通常是:

  • 记录业务事件
  • 让协作者看到上下文
  • 形成后续可追踪历史

所以把这个思路放回 warning 上,就很容易看清边界:

warning

偏“当前动作的风险判定”

message/chatter

偏“把发生过的事情沉淀下来”

两者经常一起出现,但本质不同。

如果你的实现只是弹 warning,不写 message,那么:

  • 当下操作者看到了
  • 但其他协作者未必知道
  • 事后也很难审计

反过来,如果只是写 message,不做 blocking 或 warning,也不代表当前操作被真正控制。


为什么“传播”二字很重要:谁该看到、在哪个对象上看到、看到多久

warning 机制最容易被低估的一点,是大家只盯着“有没有提示”,不盯“传播路径”。

真正重要的问题是:

1. 风险先附着在哪个对象上

  • partner
  • product
  • sale.order
  • sale.order.line

2. 它在什么时候被带到当前交易

  • 选客户时
  • 选商品时
  • 确认时
  • 开票时

3. 最终有没有沉淀成可共享消息

  • 只有当前用户看到了弹窗
  • 还是订单 chatter 里留下记录
  • 还是相关下游对象也能看到上下文

一旦你按“传播”去看 warning,就会发现这不是单点字段,而是一个协作设计问题。


实战里最危险的 4 个误区

1. 以为 warning 已经等于拦截

很多系统实际上只是提醒,没有阻断。结果销售员习惯性点掉继续走。

2. 以为 blocking 一定会留痕

并不一定。阻断了动作,不代表 chatter 已经记录了原因和上下文。

3. 以为 message 多了就代表风控做完了

message 只保证“有人记录过”,不保证规则在关键节点被执行。

4. 只设计当前操作者体验,不设计协作传播

订单交接、财务、客服、仓库可能都需要知道 warning 背景,但单次弹窗不会自动解决这个问题。


实施时最稳的拆法

如果你要把 sales warnings 设计清楚,最稳的方式不是只讨论字段,而是分三张表来想:

第一张:风险来源表

  • 客户风险
  • 商品风险
  • 组合销售风险

第二张:动作控制表

  • 录单时提示
  • 确认时阻断
  • 开票时阻断
  • 允许 override 还是完全禁止

第三张:传播留痕表

  • 是否写 chatter
  • 写到 sale.order 还是下游对象
  • 是否要求负责人/审批人被通知

一旦这么拆,warning、blocking、message 三者就不会再糊成一团。


一句话总结

Odoo 销售里的 warnings 真正要分开看的是三条链:

  • warning 链:把风险及时暴露给当前操作者
  • blocking 链:在关键节点真正阻止错误业务继续推进
  • message 链:把风险处理过程和结果沉淀为可追溯上下文

它们可以协作,但从来不是同一件事。

所以最稳的理解应该是:

sales warning 解决“现在该不该继续”,message 解决“后来谁还能看见发生过什么”,而 blocking 决定“系统最终放不放行”。

DISCUSSION

评论区

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