先说结论
如果你总记不住 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
评论区