建议补货

Odoo 采购建议补货为什么不是看缺货就下单:月需求、在途量与设供应商按钮背后的算法讲透

Odoo 的采购建议数量不是一个简单的“低于安全库存就补满”的结果。`purchase_stock` 会按 actual demand 或历史月需求估算未来消耗,再扣除现货和 incoming,同时把草稿 RFQ、待审批采购也算进 in progress。本文把建议补货与设供应商动作背后的真实算法拆开讲清。

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

先说结论

Odoo 的采购建议补货不是“库存负了就补一点”那么简单。

purchase_stock 里,系统会综合看:

  • 你用哪种建议模式;
  • 最近一段时间的真实需求;
  • 当前现货;
  • 已在途数量;
  • 甚至草稿、已发送、待审批 RFQ 里的采购量。

所以建议值的本质不是一个静态库存规则,而是:

在当前仓库和供应商语境下,对“未来缺口”做的一次近似预算。


第一步:suggested_qty 有两套完全不同的思维模式

_compute_suggested_quantity() 先看 context 里的 suggest_based_on

模式一:actual_demand

这时系统主要盯着 virtual_available

如果虚拟可用量已经小于 0,就把缺口按 suggest_percent 放大或缩小,然后向上取整。

它更像一种“立刻补洞”的思路:

  • 你现在就不够;
  • 那先把眼前缺口补上。

模式二:按周 / 月 / 季 / 年历史需求估算

如果不是 actual_demand,系统会先算 monthly_demand,然后:

  • suggest_days 算出要覆盖多少月份比例;
  • 再乘 suggest_percent
  • 最后扣掉 qty_available + incoming_qty

这是一种“需求覆盖天数”思路,不再只是盯当前缺货,而是问:

  • 未来一段时间可能要消耗多少;
  • 现有库存和在途能覆盖多少;
  • 剩下的缺口值不值得补。

这两种模式差别很大。

一个偏救火,一个偏预算。


第二步:月需求不是凭空猜,而是从 stock move 历史读出来的

_compute_monthly_demand() 会根据 suggest_based_on 先决定时间窗,比如:

  • 最近 30 天;
  • 最近 1 周;
  • 最近 3 个月;
  • 最近 1 年;
  • 去年同期 / 去年季度。

然后用 stock.move._read_group() 汇总在这段时间里发生的出货 / 生产消耗相关移动。

默认 location domain 也很有意思,它会把需求理解成:

  • 去 customer;
  • 去 production;
  • 或从一个仓库流向别的仓库。

同时,它明确排除某些回库和 scrap 干扰。

也就是说,Odoo 想估的是“真正把货往外消耗掉的流量”,而不是所有库存变动。

这就是为什么建议补货经常和你肉眼看的单纯出库数不完全一样。

它在刻意逼近“消耗”,不是所有 movement。


第三步:在途量不只看 incoming picking,还把未落单完成的采购承诺算进来

很多人会以为“in progress”只等于已生成入库单。

_get_quantity_in_progress() 不是这么算的。

它先调用父类拿基础在途,再额外把采购单行聚合进来。筛选域来自 _get_lines_domain(),会把这些状态纳入:

  • draft
  • sent
  • to approve

也就是说,只要采购承诺已经形成,即便还没正式变成完成中的收货,也会被视为一种在途信号。

这非常符合采购管理现实。

因为补货决策不该只看“已经发车的货”,还要看:

  • 已发 RFQ;
  • 正在审批;
  • 其实已经有人准备下单。

否则多个采购员很容易在同一个缺口上重复补货。


第四步:为什么同一个产品在不同仓库里建议值会不一样

_get_monthly_demand_moves_location_domain()_get_lines_domain() 都支持 warehouse / location 语境。

所以系统不是在算一个公司级的全局数字,而是在尽量贴近:

  • 这个仓;
  • 这个补货点;
  • 这个最终目的地。

这点尤其重要,因为现实里最容易踩坑的是:

  • 总库存看着够;
  • 但某个仓其实已经断货;
  • 另一个仓的在途不一定能及时支援;
  • 同产品在不同仓库的需求曲线完全不一样。

如果你不带仓库语境理解 suggested_qty,就很容易觉得系统“算错了”。

实际上它通常是在算另一个粒度


第五步:action_set_supplier() 不只是选个 vendor,还会顺手修补采购路线和最小起订量

很多人把“Set Supplier”理解成给补货规则换个供应商。

但源码里它顺手做了两件很关键的事:

1. 如果 orderpoint 当前 route 不是 buy,会自动补一条 buy route

也就是说,系统不只改主数据,还会顺手把“能不能按采购补货”这条路径接上。

2. 如果建议补货量低于供应商最小起订量,会把 qty_to_order 抬到供应商门槛

这说明 Odoo 的立场很明确:

补货建议不是纯库存学问题,它必须尊重供应商交易条件。

所以你看到点了 Set Supplier 之后建议数量突然变大,不一定是 bug,而是供应商 min_qty 被真正纳入了补货结果。


最容易误解的 5 个点

1. 以为 suggested_qty 只由当前缺货决定

错。很多模式下它是按历史需求窗口推算的。

2. 以为 incoming_qty 已经足够代表“在途”

错。采购草稿、已发送 RFQ、待审批采购也可能被算进 in progress。

3. 以为月需求就是最近出库总数

不完全是。系统会按 location 语义过滤,只抓它认为代表真实需求的流量。

4. 以为 Set Supplier 只改供应商字段

错。它还可能自动补 buy route,并把数量抬到最小起订量。

5. 以为 suggested_qty 在所有仓库都应该一样

错。仓库 / 补货点上下文本来就会改结果。


实战排错顺序

如果补货建议看起来“不合理”,建议按这个顺序看:

  1. 当前 suggest_based_on 是 actual demand 还是历史窗口;
  2. suggest_dayssuggest_percent 设置了什么;
  3. 有没有 warehouse / location context;
  4. 草稿 RFQ、待审批采购是否已被算进 in progress;
  5. Set Supplier 后是不是触发了 min_qty 或 buy route 补全。

一句话记忆法

Odoo 的采购建议补货不是“看库存”,而是“按需求窗口、在途承诺和供应商约束一起估缺口”。

DISCUSSION

评论区

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