人力资源

Odoo 自动签退为什么不是“到点就关单”:看懂 open attendance、跨天修补与 auto check-out 的排错顺序

很多团队开了自动签退后,以为系统会在下班时间准点把打卡关掉。Odoo 的 hr_attendance 源码实际更谨慎:它先判断有没有 open attendance,再结合时区、当日历史工时、排班段和容忍度计算该签到哪里。它解决的是“漏签退如何被修补”,不是“排班系统替你写结论”。

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

先说结论

Odoo 的自动签退不是一个“到下班时间就把 check_out 写死”的定时器。

/home/ubuntu/odoo-temp/addons/hr_attendance/models/hr_attendance.py 里的 _cron_auto_check_out() 说明,官方真正做的是:

  • 先找还没签退的 open attendance
  • 再把 check_in 转成员工自己的时区
  • 再结合当天已累积工时、日历排班段、公司容忍度计算应该签到哪里
  • 最后把 out_mode 标成 auto_check_out

所以它解决的问题不是“系统替你打卡”,而是:

当员工忘了签退时,系统如何尽量保守地补一刀,同时别把工时算得更离谱。

第一层:自动签退只处理“还开着的单”

入口条件很明确:check_out = False,并且公司开启 auto_check_out

这意味着自动签退不是重新改写所有历史记录,而是专门处理那些“开口还没闭上”的 attendance。

所以如果你的问题是:

  • 已经有人手工签退了但时间不对
  • 历史记录重叠了
  • 同一天多段班次算错

自动签退本身不是第一修复器。

第二层:为什么源码要先把时间转到员工时区

_cron_auto_check_out() 里专门定义 check_in_tz(attendance),把 check_in 转到员工时区。

这一步不是细节,而是整个逻辑能不能成立的前提。

因为“今天工作了多久、是不是已经跨天、当前排班属于周几”,都必须站在 员工本地日历 上判断。

如果你直接拿 UTC 或服务器时区判断:

  • 跨国团队会错日
  • 夜班会错班
  • 前一天和今天的累计工时会串掉

第三层:为什么它还要看“今天之前已经有多少工时”

代码里会汇总该员工当天之前已完成 attendance 的 worked_hours,再把当前 open attendance 的时长加进去。

这是因为自动签退不是只看“这一条开了多久”,而是要看:

  • 这一天理论上应该工作多少
  • 前面已经工作了多少
  • 当前这段最多还能留下多少

这也是为什么它更像“补录上限控制”,而不是“把 check_out 写到排班终点”。

第四层:排班段和容忍度为什么比固定下班时间更重要

源码会根据员工所在版本/日历去找当天有效的 attendance schedule,再叠加公司 auto_check_out_tolerance

这说明官方知道现实排班不是一个固定 18:00:

  • 有两段班
  • 有两周轮班
  • 有弹性时长
  • 同一个人换合同后日历会变

所以“自动签退时间”并不是一个绝对时刻,而是:

理论工作时长 + 公司允许的超出容忍度。

第五层:为什么有时候系统会签到 23:59:59

代码里有一种兜底情况:当天找不到合适的班段上限时,会把 check_out 放到当天结束前。

这看起来很怪,但背后其实是风险最小化:

  • 至少别让 open attendance 无限拖到未来
  • 先把跨天污染切断
  • 后续再让 HR 或主管补修真实时间

换句话说,23:59:59 不是说“员工真干到午夜”,而是系统在说:

  • 我不知道最合理的签退点
  • 但我知道不能继续开着

第六层:out_mode = auto_check_out 的价值在于可追溯

自动签退不仅改时间,还会把来源写成 auto_check_out

这非常重要,因为后续你要区分:

  • 员工自己签退
  • kiosk 签退
  • systray 签退
  • 系统补签退

否则大家会把所有 check_out 当成同一可信度,后面就很难解释为什么这条记录看起来“像猜的”。

最容易踩的 4 个坑

1)把自动签退当排班引擎

它是补救机制,不是排班真相来源。

2)忽略时区

这会导致跨天和日累计工时一起错。

3)只看当前 open attendance,不看当天已完成工时

结果就是自动签退把一天总工时补超。

4)看到 23:59:59 就判定系统坏了

很多时候那是兜底止血,而不是最终业务结论。

排错顺序

  1. 先确认记录是不是 open attendance
  2. 看公司是否开启自动签退及容忍度
  3. 查员工时区和当天本地日期
  4. 查当天前面已累计的工时
  5. 再看资源日历、轮班周类型和弹性工时配置
  6. 最后才判断这次 auto check-out 是否合理

最后一句话

Odoo 自动签退的本质是“修补忘签退”,不是“代替员工精确下班”。把它当补救机制来配置和排错,你才不会对它期待错位。

DISCUSSION

评论区

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