如果把招聘面试预约理解成“发候选人一个 Calendly 链接”,你会低估 Odoo 企业版这块的真正价值。enterprise/appointment_hr_recruitment/models/hr_applicant.py 和 enterprise/appointment_hr_recruitment/controllers/appointment.py 说明,它不是把 appointment 模块硬套到招聘上,而是把候选人身份、预约记录和招聘流程节点连在一起。
一、候选人不是匿名访客,而是带专属路由码进入预约链路
interview_invite_code 是这套机制的第一把钥匙。_compute_interview_invite_code() 会给 applicant 生成专属 code,_get_interview_invite_url() 则把这个 code 带入预约 URL。这样做有两个价值:
- 候选人的预约行为能准确回写到对应 applicant;
- 同一个 appointment 页面可以服务很多候选人,但系统知道每次 booking 属于谁。
这跟普通官网预约完全不是一回事。普通预约更关心“有人约上了”,招聘预约关心的是“这个人约的这场面试要回到哪条人才流程里”。
二、controller 扩展的重点,是把 booking 回写成招聘语义
AppointmentHrRecruitmentController._get_extra_calendar_event_params() 会从上下文拿 applicant_code,再找到对应 applicant,把额外参数塞进预约生成的 calendar event。这个点很关键:面试 booking 不是孤立日程,而是带着招聘上下文创建出来的业务记录。
这也是为什么你不能简单拿通用 appointment 去替代招聘预约。缺了这层回写,面试日历再漂亮,也只是“有人约了时间”,而不是“某个候选人推进到某个招聘节点”。
三、可用性控制不是只看 HR 日历,而是 appointment 资源模型整体在工作
真正的可用性计算主要还是落在企业版 appointment 自己的 booking 逻辑上。calendar_event.py 里的 booking_line_ids、appointment_resource_ids、total_capacity_reserved、total_capacity_used 说明一个预约可以对应资源、席位、容量等多个维度。
面试场景里这很有用:
- 一对一面试时,核心是 interviewer 是否空闲;
- panel interview 时,核心是多个资源是否同时可用;
- group assessment 时,甚至会涉及容量而不只是单一用户。
所以“面试官 availability”并不是一个 if/else 字段,而是 appointment booking 模型整体在兜底。
四、招聘阶段路由的真正意义
虽然 appointment_hr_recruitment 模块本身很轻,但它把面试预约稳稳绑到了 applicant 上,于是 stage route 就有了业务基础:某个候选人完成某次预约后,你才能在招聘流程里继续判断是否进入下一面、是否转 hired、是否发 offer。
也就是说,系统没有把招聘阶段硬编码进预约模块,而是通过 applicant 这个中间对象把两者连接起来。这种设计更稳,因为预约规则会变,招聘流程会变,但 applicant 始终是主锚点。
五、容易误解的地方
1. invite code 不是安全炫技,而是业务主键
没有它,controller 就很难把外部预约动作稳定回写到某位候选人。
2. booking 成功不等于招聘自动推进
预约只是产生了可信面试记录,后面仍要配合招聘阶段规则和人工判断。
3. 可用性问题通常不在招聘模块本身
大部分“为什么约不上”其实要回到 appointment 资源、容量、冲突检查去排查。
六、实战建议
- 先设计候选人预约 URL 生命周期,避免旧链接长期有效;
- 面试官是资源、用户还是容量资源,要在上线前统一口径;
- 面试 booking 与招聘阶段变更最好各自保留审计点,不要互相覆盖日志。
七、结论
Odoo 企业版招聘预约真正做对的事,是把“候选人约了个时间”升级成“这位候选人在这条招聘流程上产生了一次可追踪的 booking”。只有把 invite code、calendar event 和 applicant 主记录接起来,面试预约才配叫招聘流程的一部分。
主要源码锚点:
enterprise/appointment_hr_recruitment/models/hr_applicant.pyenterprise/appointment_hr_recruitment/controllers/appointment.pyenterprise/appointment/models/calendar_event.pyenterprise/appointment/models/appointment_booking_line.py
DISCUSSION
评论区