人力资源

员工技能为什么不该直接改等级:Odoo Skills 与 Certification 的有效期、历史与到期提醒

很多团队把员工技能当成一组静态标签,觉得会 Python 就把等级改成高级。Odoo 的 hr_skills 源码却在强调另一件事:技能和认证都带时间语义,修改不该覆盖历史,到期还可能触发活动提醒。

Odoo 开发 人力资源
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 29 阅读

先说结论

很多人做 HR 系统时,会把员工技能理解成一串当前标签:

  • 英语:高级
  • Python:中级
  • 项目管理:初级

看起来很简单,但 Odoo 的 hr_skills 源码明显不想这么做。

它更接近这个思路:

  • 技能是会演化的历史记录
  • 认证是带有效期的资格记录
  • 修改不应该直接覆盖旧值
  • 过期风险还会触发后续提醒

所以员工技能不是“当前画像的一张截图”,而是“能力与资质随时间变化的轨迹”。


为什么源码里一上来就强调“不要直接改旧记录”

hr.individual.skill.mixin 里的注释写得非常直白。

它区分了两类对象:

普通技能

  • 同一个技能通常只应有一个当前有效版本
  • 不应直接覆盖旧记录
  • 更推荐归档旧技能,再创建新技能,保留历史

认证技能

  • 同一个技能、同一个等级可以有多条记录
  • 前提是有效期不同
  • 它们代表的是不同时间段的证书有效性

这意味着 Odoo 从模型层就在反对一种偷懒做法:

员工升级了,就把 skill level 直接改掉。

因为一旦直接改掉,你就失去了“他以前是什么水平、这次变化何时生效”的时间语义。


为什么技能和认证要分开看

源码里 is_certification 是关键开关。

如果它是普通技能,系统更关注“当前有效能力”; 如果它是认证,系统更关注“资格在什么时间段有效”。

这两者听起来很像,实际上业务差别很大:

  • 会不会 Python,偏能力
  • Odoo 认证顾问证书有效到哪天,偏资格

能力可以逐步成长,资格则往往有明确起止日、续期、失效和到期提醒。

所以 Odoo 没有把它们粗暴混成同一张“技能标签表”。


valid_from / valid_to 为什么是核心,而不是补充字段

hr.individual.skill.mixin 里:

  • valid_from
  • valid_to

不是随手加的两个日期,而是整个重叠校验和“当前技能”判断的基础。

比如:

  • 普通技能不能和同技能的另一条有效记录重叠
  • 认证如果允许编辑有效期,则只禁止“完全相同”的重复项
  • 如果 valid_to 早于 valid_from,直接报错

这说明 Odoo 在建模上已经假设:

技能从来不是纯静态字段,而是时间区间内成立的事实。


为什么普通技能不允许时间重叠

_check_not_overlapping_regular_skill() 里,普通技能的重叠检查很严格。

原因很简单:

如果同一个员工、同一个技能,在同一时期同时有效两条等级不同的记录,比如:

  • English: Intermediate
  • English: Expert

系统就无法回答“当前到底算哪一级”。

所以普通技能更像一条版本线:

  • 旧等级结束
  • 新等级开始

它不是多个等级并排成立。


为什么认证可以同技能多条并存

认证的逻辑不一样。

源码允许同一个技能、同一个等级,随着不同 valid_from / valid_to 出现多条记录。

这非常符合证书管理现实:

  • 2024 年证书有效到 2025-05-31
  • 2025 年新证书又从 2025-06-01 开始

甚至短暂交错、重新发证、补证,都可能需要单独保留历史。

所以 Odoo 不是在问“你会不会”,而是在问:

你在什么时候,持有哪一段有效资格。


“当前技能”是怎么算出来的

hr.employee.skill.get_current_skills_by_employee() 很有代表性。

它会按员工和技能分组,再筛:

  • valid_to 为空,或
  • valid_to >= today

这就是当前有效技能。

但对认证,源码还做了一个很细的处理:

如果当前没有有效认证,它会把 最近过期的那条 拿出来作为结果。

这个细节特别好,因为它体现了产品上的妥协:

  • 从资格角度,它已经过期
  • 但从管理角度,“最近过期的是哪一张”仍然有参考价值

这比简单显示空白更有用。


为什么系统还会主动创建认证到期提醒

hr.employee._add_certification_activity_to_employees() 里,源码会:

  1. 找出岗位上要求认证的技能
  2. 找出员工当前拥有的对应认证及 valid_to
  3. 如果缺失,或者三个月内到期
  4. 给员工、经理或岗位负责人创建活动提醒

这说明 Odoo 不把认证只当作“档案陈列”。

它还把认证接进了日常管理动作:

  • 缺证
  • 快到期
  • 需要上传续证材料

这一下子就从“员工画像功能”变成了“合规运营功能”。


这套设计对 HR 有什么现实意义

1. 能力成长不再覆盖历史

员工从中级成长到高级,系统保留轨迹,而不是只留下最后一个答案。

2. 认证续期更容易做预警

特别适合有执照、合规、审计要求的岗位。

3. 岗位要求和员工现状能做差距分析

如果岗位要求认证,而员工没有或即将过期,系统可以提前催办。


实施时最常见的误解

误解一:技能就是标签

如果只是标签,就不需要有效期和历史,也做不好到期提醒。

误解二:等级变化直接改旧记录最省事

短期省事,长期失去培训、晋升、评估的时间线。

误解三:认证和普通技能是同一种东西

源码已经明确告诉你:它们的重叠规则和当前值逻辑都不一样。


一句话记忆

Odoo 把员工技能做成带时间语义的历史记录,把认证做成带有效期的资格记录;真正重要的不是“现在显示什么等级”,而是“这项能力或资质在什么时候成立”。

DISCUSSION

评论区

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