制造截止期

Odoo 制造截止日期为什么会越传越深:date_deadline、原料 move 传播与 delayed 判定讲透

很多人把制造单 Deadline 当成提醒字段,但 Odoo 其实会把 date_deadline 传进成品 move、原料 move 甚至合并后的来源链路,还据此计算 is_delayed。本文结合源码讲清它的时间语义。

制造
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

很多团队把制造单上的 Deadline 只当看板上的提醒日期。

但在 Odoo 源码里,date_deadline 远不只是 UI 标记。

它同时承担三层语义:

  1. 这张 MO 最晚应在何时完成
  2. 相关 stock move 应该按什么时间节奏被拉动
  3. 系统何时要把这张单标成 delayed

所以 Deadline 不是一个孤零零的字段,而是一条会向下传导、向外联动的时间约束。

一句话记住:

Odoo 的 Deadline 不是“提醒你一下”,而是在给制造链和库存链同时施加时间压力。

默认日期为什么会优先围绕 deadline 展开

mrp.production.py 里,_get_default_date_start()_get_default_date_finished() 都先看 context 里有没有 default_date_deadline

如果有:

  • date_finished 默认就是这个 deadline
  • date_start 会默认回推一小时

这个细节很能说明问题。

Odoo 的初始思维不是“先有生产开始时间,再顺便算个 deadline”,而是:

如果上游已经告诉我最晚完成时间,那制造起止时间应该围着它来搭。

这就是典型的交付驱动型制造时间建模。

date_deadline 为什么来自 finished moves

字段定义上,date_deadline 是 compute 字段;在 _compute_date_deadline() 里,Odoo 会取:

  • move_finished_ids 上存在的 deadline
  • 选其中最早的一个作为 MO 的 date_deadline

这说明制造单的 deadline,并不是只靠 MO 自己关起门来定义,而是和成品去向链路连着。

从业务上理解也合理:

  • 制造为什么要赶这个时间
  • 往往不是因为车间自己想赶
  • 而是因为成品的后续 move、交付承诺、需求链已经给了时间压力

所以 MO deadline 更像是从需求端反推到制造端的最晚完成点

date_start 时,为什么原料 move 的日期和 deadline 也会一起改

write() 里,如果生产单的 date_start 被修改,Odoo 会把 move_raw_ids 写成:

  • date = production.date_start
  • date_deadline = production.date_start

这一步特别值得注意。

它意味着:

原料 move 的时间压力,默认是围绕开工时点组织的。

很符合现场逻辑:

  • 原料不是在完工时才需要
  • 而是在开工时就该准备好

所以你把 MO 开工日往前拉,系统也会把原料 move 的时间要求一起往前拉。

date_finished 时,为什么 finished move 也要跟着改

同一个 write() 逻辑里,如果改了 date_finished,系统会把 move_finished_ids.date 跟着更新。

这表示成品 move 的时间语义是围绕“预计或实际完工时间”来走的。

也就是说,Odoo 在内部已经把:

  • 原料 move 时间
  • 成品 move 时间
  • MO 起止时间

拆成不同口径去维护,而不是全部塞成一个统一时间戳。

is_delayed 到底是怎么判的

很多用户以为 delayed 只要看“今天过没过 deadline”。

源码不是这么简单。

_compute_is_delayed() 里,Odoo 会要求:

  • 生产单状态在 confirmedprogressto_close
  • 并且 date_deadline 存在
  • 且满足以下之一:
  • date_deadline < now
  • date_deadline < date_finished

这说明 delayed 有两种含义:

一种是“已经拖到现在还没做完”

即 deadline 早于当前时间。

另一种是“按排定完工时间看,已经注定晚交”

即 deadline 已经早于 date_finished

第二种特别关键,因为它说明 Odoo 不只是做事后报警,还会做计划层面的提前预警

合并制造单时,deadline 为什么还会往来源 move 传播

在合并生产单的链路里,源码会把:

  • 新生产单 raw moves 的 move_orig_ids
  • 写上 date_deadline = production.date_start

这句很有意思。

它说明 Odoo 不希望合并动作把原先上游需求链的时间约束丢掉。

也就是说,即使几张单合成一张,系统仍然尝试把新的开工要求继续传回来源 move。

从业务视角看,就是:

  • 单据形态可以变
  • 时间承诺不能凭空消失

新手最容易误解的点

1)Deadline 不是单纯备注字段

它会参与默认时间、move 时间和 delayed 状态的计算。

2)MO deadline 不一定是手工拍脑袋填的

它很多时候来自 finished move / 下游需求链。

3)delayed 不只是“已经超时”

如果计划完工时间已经晚于 deadline,系统也会认为有延误风险。

4)改 MO 日期可能同时改动库存链时间语义

尤其是 date_start 对 raw moves、date_finished 对 finished moves 的影响,很容易被忽略。

实施和开发注意点

一,不要把 deadline 培训成“看板备注”

如果用户只把它当提醒,他们会看不懂为什么改 MO 时间会影响原料或成品 move 的日期。

二,二开改时间时要想清楚影响面

如果你只改了 MO 上的一个日期字段,却没有意识到:

  • raw move 会跟着变
  • finished move 会跟着变
  • delayed 状态会重算

后续就容易出现计划报表、看板状态和库存日期互相打架。

三,排错时建议顺序

  1. 先看 date_deadline 来源是不是来自 finished moves
  2. 再看 date_start / date_finished 最近有没有被改写
  3. 检查 raw / finished move 日期有没有同步变化
  4. 最后再看 is_delayed 是因为当前已超期,还是因为计划完工时间已晚于 deadline

最后总结

Odoo 把制造 Deadline 设计成了一条真正参与运算的时间约束,而不是看板装饰。

它会:

  • 影响默认起止时间
  • 从 finished moves 反推到 MO
  • 再把开工/完工时间压回 raw / finished moves
  • 最后用于 delayed 风险判断

一句话记住:

在 Odoo 里,Deadline 不是显示给人看的日期,而是驱动制造与库存时间链的一根主线。

DISCUSSION

评论区

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