先说结论
很多人以为 Odoo 的请假和项目工时是两套平行系统:
- 请假在 Time Off 里审批
- 工时在 Timesheets / Project 里登记
- 两边最多在报表层做一下扣减
但如果你去看 /home/ubuntu/odoo-temp/addons/project_timesheet_holidays/,会发现官方选的是更强耦合的方案:
- 请假审批通过时,自动生成
account.analytic.line - 这些分析行挂到公司配置的内部项目
internal_project_id - 同时挂到专用任务
leave_timesheet_task_id - 公共假期也能为员工批量生成 future timesheets
- 并且普通用户不能手工篡改这类请假工时
所以这套设计真正想解决的问题不是“请假要不要影响工时”,而是:
请假如何作为一类正式工时事实,进入项目/分析账户体系。
第一层:为什么 Odoo 不满足于“请假只在考勤侧生效”
如果请假只停留在 HR 视角,系统当然也能算出某人休了几天。
但项目和工时分析还会继续遇到几个问题:
- 员工当月记录了多少可计入工时的时间
- 利用率分母分子怎么统一
- 项目分析账户里哪些时间是交付工时,哪些是请假占用
- 公共假期是否影响工时报表
于是官方没有只在人事模块里“减库存”,而是把请假变成正式分析行。
这一步说明:
在 Odoo 里,请假不是项目系统外的一块阴影,而是会进分析账的时间事实。
第二层:审批通过后为什么直接生成分析行
在 hr_leave.py 里,_validate_leave_request() 会调用 _generate_timesheets()。
生成逻辑会:
- 找公司配置的内部项目和请假任务
- 按员工日历拆出每天对应的工时数
- 为每一天构造
account.analytic.line - 带上
holiday_id、employee_id、task_id、project_id
这说明官方不是等报表查询时临时把请假折算成工时,而是在审批落地那一刻就把它记成分析事实。
这样后续无论你看:
- 工时报表
- 分析账户
- 员工工时汇总
- 项目视角的时间占用
都可以站在同一类底层记录上工作。
第三层:为什么一定要挂到内部项目和专用任务
很多系统做到这一步,会只在分析行里留一个“请假”类型字段。
Odoo 更进一步,要求公司配置:
internal_project_idleave_timesheet_task_id
这意味着请假工时不是漂浮在系统里的匿名记录,而是明确归属到:
- 某个内部项目
- 某个任务容器
这有两个好处:
1. 时间数据结构统一
正常工作工时和请假工时都用 project/task/account 的结构承载。
2. 报表视角统一
很多以项目/任务为入口的分析,不需要为请假单独再造一套数据模型。
所以官方其实是在用项目系统承接“非交付时间”。
第四层:为什么公共假期也会生成 future timesheets
hr_employee.py 里有一段非常容易被忽视但很重要的逻辑:
- 新员工创建后,会补未来公共假期 timesheets
- 员工重新激活、工作日历变化时,也会删除并重建相关 future public holiday timesheets
这说明 Odoo 对公共假期的态度不是“到时候报表少算一天就行”,而是:
公共假期也应预先形成结构化时间事实,并随着员工状态和日历变化重新校准。
这对多日历、多公司、弹性工时环境尤其重要。
第五层:为什么普通用户不能直接编辑这类工时
account_analytic.py 里对这类分析行加了很多保护:
- linked to
holiday_id的 timesheet 不能随便删 - linked to
global_leave_id的 timesheet 不能手工删 - 非 sudo 用户不能改请假关联的 timesheet
- 也不能直接给
is_timeoff_task任务新建普通工时
这套限制的目的非常明确:
- 请假事实应由 Time Off 应用驱动
- Timesheets 页面只能消费结果,不能反向篡改原始请假业务
否则你就会得到“工时改了,但请假单没改”或者“请假取消了,工时没回收”的数据撕裂。
第六层:is_timeoff_task 到底解决了什么问题
project_task.py 里会计算:
leave_types_countis_timeoff_task
本质上它要识别:
- 哪些任务已经承担了请假工时容器的角色
然后在 timesheet 创建域与权限校验里,禁止把这类任务当普通项目任务乱用。
所以 Time Off task 不是一个为了界面好看设的标签,而是一个数据边界标记:
这个任务是 HR/工时系统共用的特殊任务,不是普通交付任务。
新手最容易误解的 4 件事
1. 以为请假只会影响 HR 模块,不会进项目
不对,审批通过后会生成项目分析行。
2. 以为请假工时只是报表动态折算
不对,Odoo 是实打实创建 account.analytic.line。
3. 以为请假 task 只是个默认值,删改无所谓
不对,它是整套时间归集逻辑的锚点。
4. 以为用户可以直接改请假工时行来修数据
不对,源码明确限制了删除与修改入口。
实战里最该注意什么
1. 客户一说“请假没体现在工时里”,先查公司配置
- internal project 有没有
- leave timesheet task 有没有
没有这两个,后面很多逻辑都落不下来。
2. 遇到公共假期工时异常,不只看请假单,还要看员工日历和激活状态
因为 future timesheets 会随着这些条件重建。
3. 不要让顾问用“直接删 analytic line”修请假问题
正确入口应该是:
- 调整请假单
- 调整公共假期
- 或校正公司/员工配置
否则数据会越修越裂。
一句话记忆法
Odoo 的请假不是报表层扣减,而是在审批后生成挂到内部项目与专用任务上的分析行,让请假时间也能以正式工时事实进入项目体系。
DISCUSSION
评论区