先说结论
Odoo 招聘里的 stage 不是“看板列名配置”。
/home/ubuntu/odoo-temp/addons/hr_recruitment/models/hr_recruitment_stage.py 与 hr_applicant.py 放在一起看,你会发现阶段实际上控制了:
- 是否算作 hired
- Applicant 的
date_closed何时写入或清空 - 看板状态
kanban_state是否被重置 - 候选人多久会被判定为 stale / rotting
- 某岗位是否使用这个阶段
- 进阶段时是否触发模板邮件
所以 stage 真正的身份是:
招聘流程状态机里的语义节点,而不是 UI 装饰。
第一层:hired_stage 不只是绿色终点,它会改业务字段
hr.recruitment.stage 上的 hired_stage 最容易被低估。
在 hr.applicant 的 _compute_date_closed() 和 write() 逻辑里,一旦 applicant 进入 hired stage:
date_closed会写入当前时间- 岗位招聘需求计数也会跟着调整
如果从 hired stage 退回去:
date_closed会被清空- 相关计数也会反向修正
这说明 hired stage 不是“颜色更像录用”,而是系统认定“招聘流程在此达成录用结论”的开关。
第二层:为什么改 stage_id 时要顺带改 last_stage_id 和 kanban_state
write() 里对 stage_id 的处理很明确:
- 更新
date_last_stage_update - 记录
last_stage_id - 如果没手动传
kanban_state,默认重置为normal
这个设计非常合理,因为官方在区分两类信息:
- 流程位置:你在哪个阶段
- 当前阻塞状态:你在该阶段里是 waiting / blocked / done / normal
如果切阶段不重置看板状态,就会出现一种常见脏数据:
- 上一阶段是 blocked
- 拖到下一阶段后仍保持 blocked
- 但这个“blocked”其实只属于旧阶段语境
第三层:rotting_threshold_days 说明官方在意“卡住多久”
Stage 上有 rotting_threshold_days,Applicant 又继承了 tracking duration 相关逻辑。
这意味着招聘流程不是只关心“人在不在这个阶段”,还关心:
- 在这里待了多久
- 多久以后应被视为 stale
- 哪些岗位/阶段积压最严重
所以 rotting 不是花哨提醒,而是招聘运营中的 堵点预警机制。
第四层:为什么 stage 可以岗位专属
job_ids 表示某些阶段只对特定岗位开放。
这一步避免了一个很常见的问题:
- 技术岗和门店岗的流程完全不同
- 但团队硬想用一套统一阶段
- 最后所有岗位看板都出现一堆不适用列
Odoo 在模型层就承认:
- 招聘流程可以共享一部分主干阶段
- 也允许每个岗位有自己的特有节点
这比“全局统一流程神话”务实得多。
第五层:模板邮件为什么挂在阶段上
template_id 放在 stage 上,不是偶然。
这说明官方认定很多招聘通知不是“某条记录随时想发就发”,而是:
- 当候选人进入一个有明确语义的阶段
- 对应沟通动作也有稳定模板
例如:
- 进入面试邀约
- 进入 offer 沟通
- 进入资料补充
这让阶段从纯流程节点,进一步升级为“流程 + 沟通”联动节点。
第六层:招聘阶段最危险的不是太多,而是语义不清
真正让流程变乱的,通常不是阶段数量,而是阶段概念混杂:
- 把“流程位置”和“优先级”混在一起
- 把“录用结果”和“面试中”混在一起
- 把“候选人阻塞原因”和“阶段名称”混在一起
结果就是:
- 数据分析做不准
- rotting 提醒没意义
- hired 统计不准
- 邮件模板触发也变味
最容易踩的 4 个坑
1)把 hired stage 当 UI 标签
它会直接影响 date_closed 和岗位计数。
2)切阶段不重视 kanban_state 重置
状态很容易带脏。
3)所有岗位强行用一模一样的阶段
流程语义会被稀释。
4)把 rotting 只当提醒红点
它其实是流程堵塞指标。
排错顺序
- 先看该阶段是否勾了
hired_stage - 查 applicant 的
date_closed、last_stage_id、date_last_stage_update - 看是否因切阶段重置了
kanban_state - 查该阶段是否仅适用于特定 job
- 再看 rotting_threshold_days 与邮件模板是否配置合理
最后一句话
在 Odoo 招聘里,阶段不是列名,而是流程语义。只要把它当 UI 配色来管,后面的录用统计、卡滞分析和通知动作都会一起失真。
DISCUSSION
评论区