规则动作边界

Odoo 里 Pull、Push、Pull & Push 到底怎么分工:库存规则三种动作边界讲透

很多人会配 route,却总在 pull、push、pull_push 上绕晕。本文从“需求驱动”和“到货驱动”的根本差异讲起,解释 Odoo 三种库存规则动作各自解决什么问题、什么时候该用、为什么一配错整条仓内流转都会乱。

Odoo 开发 库存
进阶 开发者 3 分钟阅读
0 评论 0 点赞 0 收藏 50 阅读

先说结论

如果你总记不住 Odoo 里的 Pull、Push、Pull & Push,到最后通常不是记忆力问题,而是底层驱动逻辑没分开

最实用的理解只有两句:

Pull 是“哪里有需求,就从上游把货补过去”。

Push 是“哪里一旦来货,就继续把货往下游推过去”。

pull_push 本质上不是第四种神秘逻辑,它只是:

同一条规则同时具备 pull 和 push 两种语义。

所以你可以先把它们拆成两个世界:

  • Pull:需求驱动
  • Push:到货驱动

只要这条线清楚了,多步仓、波次流转、中转区、收货区、质检区、打包区这些配置就会顺很多。


为什么这个点特别容易把人绕晕

因为前台看起来它们都像“调拨规则”。

你看到的结果也很像:

  • 都可能生成 move
  • 都可能牵涉多个库位
  • 都可能让货继续往后走

所以很多人就会误以为:

  • Pull = 从 A 到 B
  • Push = 也是从 A 到 B

看起来不都一样吗?

不一样。

真正的区别不在“货从哪到哪”,而在:

  • 是谁先触发了这一步动作

这是根。其余都是枝叶。


先把“触发者”讲清楚

Pull 的触发者是谁

Pull 的触发者是:

下游位置出现需求。

也就是说,系统先发现:

  • 客户位置需要货
  • 拣货区需要货
  • 打包区需要货
  • 某个中间位置需要货

然后才回头问:

  • 这批货应该从哪里补过来?

所以 pull 的出发点永远是:

  • 需求已经出现了

Push 的触发者是谁

Push 的触发者是:

某个位置收到了货。

也就是说,系统先看到:

  • 收货区来货了
  • 中转区来货了
  • 某个暂存位来货了

然后再决定:

  • 既然货已经到了这里,要不要继续往后推进?

所以 push 的出发点永远是:

  • 到货事件已经发生了

这两个时机完全不同。


用一句最短的话区分三者

Pull

缺货了,所以向上游要货。

Push

来货了,所以继续往下游送。

Pull & Push

既能因为下游缺货而触发,也能在本节点来货后继续向后推。

你只要记住这三句,基本就不会再把它们当成“只是名字不同的调拨规则”。


从源码视角看,为什么它们本来就不是一回事

addons/stock/models/stock_rule.py 里,Odoo 对 pull 和 push 是按两套不同入口处理的。

Pull 规则怎么找

_get_rule() 在找 pull rule 时,核心条件是:

  • location_dest_id 命中当前需求位置
  • action != 'push'

也就是说:

系统是按“需求出现在哪个目标位置”去找 pull 规则的。

这正说明 pull 是“面向需求位置”的逻辑。

Push 规则怎么找

_get_push_rule() 在找 push rule 时,核心条件是:

  • location_src_id = 当前到货位置
  • action in ('push', 'pull_push')

也就是说:

系统是按“货到达了哪个来源位置”去找 push 规则的。

这正说明 push 是“面向到货事件”的逻辑。

所以从源码入口上,它们本来就是两个方向:

  • 一个面向需求点
  • 一个面向到货点

这不是概念游戏,是代码就是这么写的。


Pull 最适合解决什么问题

Pull 最适合解决的问题是:

某个位置需要货,但这个位置本身不负责生产或持有全部库存,于是要向上游请求补货。

典型场景:

  • 客户位置需要货,于是仓库出库区开始准备发货
  • 包装区需要货,于是从拣货区拉货过去
  • 质检区需要货,于是从收货区拉一批待检货过去
  • 某个仓内中间位缺货,于是从主存储位补过去

Pull 的核心问题不是“货怎么动”

而是:

  • 谁在缺货
  • 缺货后应该从哪里补

所以 pull 更像“补位逻辑”。


Push 最适合解决什么问题

Push 最适合解决的问题是:

货已经到了某个节点,接下来应该沿既定流程继续流向下一个节点。

典型场景:

  • 收货区来货后,自动推向质检区
  • 质检区放行后,自动推向存储区
  • 生产完成后,成品先到暂存位,再推向成品区
  • 拣货区拣好的货,自动推向打包区

Push 的核心问题不是“哪里缺货”

而是:

  • 货既然已经到了这里,下一站应该去哪

所以 push 更像“流程推进逻辑”。


为什么很多人该用 Pull 却配成 Push

因为人会天然先看见“货从哪到哪”。

例如:

  • 从库存区到拣货区
  • 从收货区到质检区

于是就容易觉得:

  • 反正都是移动,那随便配 pull 或 push 不都行?

不行。

关键要看业务语义:

如果是因为拣货区需要货

那本质是:

  • 下游有需求
  • 上游补过来

这应该偏 pull

如果是因为收货区一来货就必须继续流转

那本质是:

  • 当前节点发生到货
  • 系统继续往后推

这应该偏 push

如果这层语义搞反了,后面常见的问题就是:

  • move 触发时机不对
  • 仓内流转出现重复动作
  • 某些环节根本不自动走
  • 看起来像规则“失灵”或“乱跑”

其实不是系统坏了,是触发模型配反了。


pull_push 到底适合什么场景

很多人看到 pull_push 会下意识觉得:

  • 这个最全能
  • 配它应该最保险

恰恰相反。

它不是“万能版”,而是:

适合那些同一个节点既承担需求承接,又承担到货继续分发的场景。

也就是说,这个节点两边都要管:

  • 下游缺货时,要能从上游补进来
  • 本节点来货后,又要能继续往后推

这种场景常见于:

  • 中转区
  • 跨仓中间位
  • 某些多步拣配包装流程的中间节点

为什么它更容易把配置搞复杂

因为它同时带两种语义:

  • pull 面
  • push 面

所以一旦位置设计、操作类型、上下游关系没理顺,你会更难判断:

  • 当前这个 move 是被哪一边触发出来的

这就是为什么我通常不建议新手一上来就把中间节点全配成 pull_push

先把每一段链路是“需求驱动”还是“到货驱动”想清楚,再决定是否真的需要双语义。


一个仓内多步流程的直观例子

假设你的仓库流程是:

  • 主存储区 → 拣货区 → 打包区 → 出货口 → 客户

哪些地方更像 Pull

如果客户订单来了,最后客户位置先形成需求。

系统会往回追:

  • 客户要货
  • 出货口要补货
  • 打包区要补货
  • 拣货区要补货
  • 主存储区出货

这条逻辑整体上更偏 pull 思维

也就是:

  • 下游缺了,上游补。

哪些地方更像 Push

如果你的流程是:

  • 收货区来货
  • 自动推去质检区
  • 质检通过再推去存储区

这条逻辑整体上更偏 push 思维

也就是:

  • 当前点到了货,继续向下一站推进。

你会发现:

Pull 更常见于“从需求往回追”的履约链,Push 更常见于“从到货往前送”的流程链。


为什么销售到库存的主链路大多更像 Pull

因为销售的本质是:

  • 客户产生需求

这天然更接近 pull 的世界。

系统面对销售单时,先知道的是:

  • 有人要货了

而不是:

  • 某个节点先收到了货

所以你会看到 Odoo 在很多面向销售履约、补货、调拨的主链上,更偏向 pull + procure_method 的组合。

这也是为什么很多 route/rule 调试问题,最后都绕回:

  • _get_rule()
  • _run_pull()
  • move confirm 后继续传播 procurement

而不是先去看 push。


为什么收货、质检、上架这些流程更容易出现 Push

因为这类流程常常是:

  • 货先到了某个节点
  • 然后按流程继续流转

比如:

  • 供应商货到收货区
  • 收货区再推质检区
  • 质检通过再推存储区

这里的起点不是“下游谁缺货”,而是“货已经来了”。

所以 push 在这些流程里经常更贴切。


什么时候你应该优先怀疑自己把 Pull / Push 配反了

如果出现下面这些现象,十有八九要回头看规则语义:

1. 你明明想要“下游缺货时再补”,结果系统只有来货时才动

这常见于该用 pull 却配成 push。

2. 你明明想要“来货自动进入下一步”,结果系统总要等下游先有需求

这常见于该用 push 却配成 pull。

3. move 时机看起来滞后或提前

因为触发时机根本不在同一个点。

4. 仓内多步流程里重复生成 move

可能是 pull 和 push 语义叠加过头,或者 pull_push 用得太随意。

5. 你越看单据越乱,不知道“第一推动力”是什么

这时候最该做的不是继续翻单据,而是回头问:

  • 这一跳到底是需求驱动,还是到货驱动?

实战调试时最该看的 6 个点

1. 当前动作是被“需求”触发,还是被“到货”触发

这是总开关。

2. 命中的 rule 是按 location_dest_id 找到的,还是按 location_src_id 找到的

这能快速判断它更像 pull 还是 push。

3. 当前节点在业务上是“补位节点”还是“流转节点”

补位更偏 pull,流转更偏 push。

4. 这条规则是否还叠加了 make_to_order / mts_else_mto

否则你会误把供给传播和动作类型混成一件事。

5. 多步流程中间节点是否真的需要 pull_push

很多时候拆成更清楚的 pull / push 两段反而更好维护。

6. move confirm 之后是否又触发了后续动作

否则你会以为是当前规则干了所有事。


一个很实用的判断口诀

如果你在配规则时拿不准,我建议直接问自己三句话:

问题 1

是因为下面缺货了,所以要往上游要货吗?

如果是,优先想 pull

问题 2

是因为这里已经来货了,所以要继续送下一站吗?

如果是,优先想 push

问题 3

这个节点是不是两边都承担:既承接需求,又继续分发?

如果是,再考虑 pull_push

这比死记字段名有用得多。


一句话记忆法

把三者记成一句话:

Pull 是“下游缺了,上游补”;Push 是“这里到了,继续往后送”;Pull & Push 是“这个节点两边都管”。

理解这一句之后,你再看 Odoo 多步仓、收货、质检、上架、拣配出库这些链路,基本就不会再把三种规则动作混成一锅了。

DISCUSSION

评论区

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