协同办公

Odoo 周期任务为什么常在“关单那一刻”生成下一条:关闭触发、规则继承与边界讲透

很多人以为 Odoo 周期任务会像日历那样一次性展开很多条,其实 project.task 的实现更克制:最后一个未完成实例在被关掉时,才按 recurrence 规则生成下一次任务。

协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的周期任务不是“先复制一长串未来任务”。

project.task_inverse_state() 可以直接看出,官方核心动作是:

  • 找到某条 recurrence 下最后一个任务
  • 当它被关到 closed state 时
  • 才调用 project.task.recurrence._create_next_occurrences() 生成下一次

也就是说:

项目里的周期任务更像“完成一轮,再续下一轮”,而不是“提前铺满整条时间线”。


为什么官方不喜欢预先复制很多未来任务

预先复制听起来省事,但会带来大量现实问题:

  • 未来半年任务全出现在列表里,噪音极大
  • 规则一改,历史和未来副本很难一起修正
  • 依赖、负责人、截止日很容易一起失真

Odoo 选择在关闭时再生成下一次,本质上是在降低未来任务的“提前承诺量”。

这很符合项目协作现实:

  • 本周例行复盘今天先做完
  • 下周要不要继续,规则可能会变
  • 未来实例不应该比当前实例更重

_inverse_state() 为什么是关键入口

任务状态被改为关闭时,_inverse_state() 会检查:

  • 这条任务是不是该 recurrence 的最后一个实例
  • 如果是,才继续创建下一次

这里有两个重要含义。

第一,不是随便一条历史实例关闭都会触发续期

第二,系统明确避免同一 recurrence 同时往前乱长多条后续任务

这说明 Odoo 把周期任务当成“串行接力”,而不是“无限复制”。


为什么“最后一个实例”这个判断很重要

如果不判断 last task,最容易出现两个坏结果:

  • 旧实例补关一次,又多生出一条未来任务
  • 并行编辑时,多个实例重复生成后续任务

官方先通过 recurrence 维度确定“谁是当前链尾”,再决定是否生成下一次,就是为了防止重复生长。

这一步虽然不显眼,但它决定了周期任务是否会失控。


周期任务更像业务节奏,而不是排班日历

和 calendar.event 相比,project.task 的周期逻辑更偏业务循环:

  • 周报整理
  • 月度复盘
  • 每周跟进客户
  • 每月结算检查

这些工作常常需要“上一轮真的完成”,下一轮才有意义。

所以 project 模块的 recurrence 设计天然更适合:

  • 任务驱动
  • 结果驱动
  • 完成后再延续

而不是纯时间到点就平铺一堆实例。


周期任务最容易踩的误区

误区一:把它当日历 recurrence 理解

项目任务不是会议;很多任务下一次何时出现,应该依赖本次是否完成。

误区二:手工复制很多未来任务,以为更稳

短期看有安全感,长期看会制造大量脏任务和假负载。

误区三:不区分“关闭任务”和“只是改阶段”

真正触发下一次生成的是进入 closed states,而不是任意拖进某一列。


排错顺序

如果用户说“为什么没生成下一次”或“为什么多生成了”,建议查:

  1. 这条任务是否真的挂了 recurrence_id
  2. 当前状态是否属于 closed states
  3. 它是不是该 recurrence 的最后一个实例
  4. 是否有自定义流程绕开了正常的状态反写逻辑
  5. 是否手工复制过历史实例,干扰了 recurrence 链条判断

一句话记忆

Odoo 周期任务不是提前排满未来,而是在你真正完成这一轮之后,谨慎地续出下一轮。

DISCUSSION

评论区

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