先说结论
很多人看到 Odoo 的 milestone,会把它理解成“项目里的几个检查点”。
但从 project.milestone 和 project.project 的源码看,它远不只是一个清单字段。
它至少同时承担三层职责:
- 任务归档点:任务可以挂到具体 milestone
- 项目节奏判断点:系统会算哪些 milestone 已达成、哪些逾期
- 管理视图入口:项目会给出
next_milestone_id、是否逾期、是否可标记完成等信号
一句话说:
Odoo 里程碑不是“给经理看着舒服”的标签,而是项目进度与风险提示的中间层对象。
第一层:milestone 不是任务字段,而是独立模型
Odoo 专门有一个模型:
project.milestone
里面有这些关键字段:
deadlineis_reachedreached_datetask_idscan_be_marked_as_doneis_deadline_exceeded
这说明 milestone 不是从任务里“凑出来”的统计结果,而是一个有自己生命周期的业务对象。
也正因为它是独立对象,任务、项目和销售都能围绕它继续挂语义。
第二层:里程碑完成,不等于“有任务完成”
很多人会误以为:只要 milestone 下面有一张任务 done,这个 milestone 就算完成。
源码不是这么设计的。
_compute_can_be_marked_as_done() 的判断更细:
- 必须是尚未 reached 的里程碑
- 必须至少有已关闭任务
- 且不能还有未关闭任务
也就是说,Odoo 想表达的是:
这个里程碑不是“已经开始有成果”,而是“挂在这个节点下的任务已经收口”。
这和很多团队的真实管理习惯更一致。
因为 milestone 往往不是成果出现的第一刻,而是该阶段可以正式盖章的时刻。
第三层:逾期判断为什么不是看里程碑自己,而是看里程碑 + 任务状态
project.milestone 自己会算 is_deadline_exceeded:
- milestone 尚未 reached
- 且 deadline 早于今天
这是 milestone 自身层面的“逾期”。
但在 project.project._compute_next_milestone_id() 里,逻辑更进一步。
项目在判断“当前最该关注的 milestone”时,不只是看 deadline,还会看这个 milestone 下面:
- 是否还有打开中的任务
- 是否已经有关闭任务
源码里的意思很明确:
场景 A:deadline 已过,但下面根本还没真正开始
这是一种问题。
场景 B:deadline 已过,而且还有打开任务
这更是一种问题。
场景 C:没有打开任务,但已经有关闭任务
这代表它其实已经具备“可标记完成”的条件。
也就是说,项目层在看里程碑时,不是只看时间,还看执行落点。
第四层:next milestone 为什么不是“最早 deadline”那么简单
很多系统会直接取最早未完成里程碑作为 next milestone。
Odoo 源码更谨慎。
在 _compute_next_milestone_id() 里,它会先把未 reached 的里程碑读出来,再结合任务状态做辅助判断,然后同时生成:
next_milestone_idis_milestone_deadline_exceededcan_mark_milestone_as_done
这说明 next milestone 的意义,不只是“下一个日期最近的点”,而是:
当前项目右侧面板最值得提醒管理者的节点。
它既是排序结果,也是风险提示入口。
第五层:项目进度条为什么按 milestone 数量算,而不是按任务工时算
在 project.project 里,里程碑进度是通过:
milestone_countmilestone_count_reachedmilestone_progress
来算的。
而且 milestone_progress = reached / total,本质是节点完成率,不是工时完成率,也不是任务张数完成率。
这说明 Odoo 在 milestone 视角下,更想回答的是:
- 关键节点推进了多少
而不是:
- 做了多少零碎任务
所以 milestone 进度天然更适合给客户、管理层和周报场景看。
第六层:为什么 reached_date 是 compute/store,不是普通手填字段
源码里 reached_date 是根据 is_reached 自动算出来的。
这背后的设计很克制:
- milestone 的事实状态是
is_reached - 达成日期是对这个事实的派生记录
也就是说,Odoo 不鼓励“单独改一个达成日期制造完成感”,而是要求先有明确的 reached 语义。
这是很典型的业务系统思路:
先确认状态,再记录状态发生的日期。
新手最容易误解的 4 件事
1. 以为 milestone 就是标签分组
不对。它有独立模型、独立 deadline、独立完成逻辑。
2. 以为有一个任务 done,里程碑就该自动算完成
不对。Odoo 更接近“该节点下任务已经收口”。
3. 以为 next milestone 只是最早 deadline
不对。项目层会结合 milestone 下任务开闭状态一起判断。
4. 以为 milestone progress 是任务进度
不对。它是关键节点进度,不是任务/工时进度。
实战上最该注意什么
1. 不要把 milestone 当任务阶段的别名
阶段解决“任务现在在哪列”,里程碑解决“项目现在推进到哪个关键节点”。两者不是一个维度。
2. 给 milestone 绑定任务时,要控制颗粒度
如果一个 milestone 下挂几十张松散任务,can_be_marked_as_done 的管理意义会变差。
3. 对外汇报时,优先讲 milestone progress,不要只讲任务数量
因为 milestone 更接近业务里程碑,而不是执行碎片。
一句话记忆法
Odoo 里程碑不是“勾一下完成”的清单项,而是“带 deadline、带收口条件、还能驱动项目 next milestone 提示”的项目节点模型。
DISCUSSION
评论区