先说结论
如果你把 hr.work.entry.type 看成一个“出勤类型字典表”,那会低估它很多。
/home/ubuntu/odoo-temp/addons/hr_work_entry/models/hr_work_entry_type.py 和 hr_work_entry_holidays/models/hr_work_entry.py 说明,这个模型其实在同时承担四件事:
- 展示协议:
display_code - 薪资/系统协议:
code - 计薪语义:
amount_rate、is_extra_hours - 假勤映射协议:
leave_type_ids
所以 Work Entry Type 不是“给用户选一个标签”,而是:
让排班、请假、工时和薪资都能用同一套标准对象对齐语义。
第一层:display_code 和 code 根本不是一回事
源码里这两个字段并列存在:
display_code:最多 3 位,明确说是展示用途code:Payroll Code,官方特别警告“会被很多引用使用”
这已经非常明确:
display_code是给人看的code是给系统和下游规则认的
实施里最常见的错误,就是把这两个字段一起随意改名。
但从源码注释看,官方显然希望你把它们分开理解:
- 页面上想显示更短、更友好的缩写,用
display_code - 薪资规则、导出接口、本地化逻辑真正要稳定依赖的,是
code
所以 code 更像一个协议常量,不是随手美化的标签。
第二层:is_leave / is_work 不是两个独立真相,而是一对互斥语义
源码没有让你同时自由维护两个字段,而是:
- 存一个
is_leave - 用 compute / inverse 推出
is_work
这背后的意思非常清楚:
官方不想让一个 Work Entry Type 在语义上既是 leave 又是 work。
因为一旦这层边界模糊,后续很多地方都会出问题:
- 工时统计
- 工资输入归类
- 与 leave type 的映射
- 日历中的有效工作时段判断
所以 is_work 看起来像独立勾选,实际上只是 is_leave 的镜像表达。
第三层:倍率和 Extra Hours 让它不只是分类,还带计薪含义
amount_rate 和 is_extra_hours 最容易被忽略。
但字段说明已经讲得很直白:
amount_rate:如果想双倍支付,设置成 200%is_extra_hours:这些小时会被当作额外工时加到月薪
也就是说,Work Entry Type 并不只在说“这段时间是什么性质”,还在说:
- 这段时间按什么倍率进入薪资
- 这段时间是否当 bonus/extra 处理
这一步一旦建模错了,薪资结果就可能整批偏掉。
第四层:请假模块不是自己造一套工资输入,而是挂到 Work Entry Type 上
hr_work_entry_holidays/models/hr_work_entry.py 给 hr.work.entry.type 加了:
leave_type_ids
这代表假勤并没有绕开 work entry 体系,而是直接把 Time Off Type 映射到 Work Entry Type。
再看 HrVersion._get_leave_work_entry_type(),默认就是返回 leave.work_entry_type_id。
意思很明确:
- 批准请假后生成什么 work entry
- 最终靠的不是“请假名称”
- 而是这张假单绑定的 work entry type
因此 Work Entry Type 才是真正会被薪资和工时体系消费的对象。
第五层:国家维度和唯一性约束说明它是“可被法规消费”的对象
源码里还有两条很强的约束:
- Attendance 默认类型不能随便改国家
- 已被 work entry 使用过的类型,国家也不能乱改
code + country组合必须唯一
这说明官方知道 Work Entry Type 很可能会被:
- 国家本地化工资规则
- 报表
- 导出系统
- 法规适配
直接依赖。
所以它不是“前台枚举值”,而是一个会被本地化规则吃进去的基础协议对象。
第六层:真正的风险不在新增类型,而在乱改旧类型
很多团队做上线时会担心“类型够不够多”。
源码告诉你,更危险的其实是:
- 上线后随意改
code - 改国家归属
- 把 leave/work 语义反过来
- 把旧类型复用成新业务含义
因为 Work Entry Type 一旦被:
- 历史 work entry
- 假勤映射
- 薪资规则
- 外部导出
共同引用,它就变成了一个需要长期稳定的协议对象。
实施时最容易踩的 4 个坑
1. 把 code 当展示缩写
真正给人看的应优先是 display_code。
2. 用一个类型同时表达 leave 和 work
源码本身就在避免这种混语义。
3. 忽略 amount_rate / is_extra_hours
这样配置看似通过,薪资结果却会错。
4. 上线后直接改旧类型的 code 或国家
这是最容易引发连锁问题的做法。
最后一句话
Work Entry Type 在 Odoo 里不是下拉选项字典,而是连接请假、工时与薪资的协议层;最该做的是稳定维护,而不是随意重命名。
DISCUSSION
评论区