diff --git a/yuthon_hr_attendance/models/overtime_approval.py b/yuthon_hr_attendance/models/overtime_approval.py index ea0b55193..9fbf654f9 100644 --- a/yuthon_hr_attendance/models/overtime_approval.py +++ b/yuthon_hr_attendance/models/overtime_approval.py @@ -70,7 +70,9 @@ class OvertimeApprovals(models.Model): for rec in self: if not rec.employee_ids or not rec.start_time: continue - current_date = (rec.start_time + timedelta(hours=8)).date() + # 当前记录的时间段(数据库存 UTC,统一比较无需 +8) + cur_start = rec.start_time + cur_end = rec.end_time for employee in rec.employee_ids: if not employee.user_id: continue @@ -87,12 +89,28 @@ class OvertimeApprovals(models.Model): target_record = target_model.browse(wf_rec.res_id) if not target_record.exists() or not target_record.start_time: continue - exist_date = (target_record.start_time + timedelta(hours=8)).date() - if exist_date == current_date: - raise UserError('员工【%s】在【%s】已有加班记录,不可重复提交!' % ( - employee.name, - current_date - )) + exist_start = target_record.start_time + exist_end = target_record.end_time + # 新旧记录都有结束时间:按时间区间是否有交集判断 + # (允许同一天不重叠的早/晚加班,如 08:00-12:00 与 18:00-22:00) + if cur_end and exist_end: + # 两个闭区间 [a,b] 与 [c,d] 有交集的充要条件:max(a,c) < min(b,d) + if max(cur_start, exist_start) < min(cur_end, exist_end): + raise UserError( + '员工【%s】在【%s】的加班时间段与已有记录冲突,不可重复提交!' % ( + employee.name, + (cur_start + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M'), + ) + ) + else: + # 缺少结束时间无法判断交集时,退化为按日期判断,避免漏拦 + exist_date = (exist_start + timedelta(hours=8)).date() + current_date = (cur_start + timedelta(hours=8)).date() + if exist_date == current_date: + raise UserError('员工【%s】在【%s】已有加班记录,不可重复提交!' % ( + employee.name, + current_date + )) for employee in rec.employee_ids: holiday_status_id = self.env['hr.leave.type'].search([('name', '=', '补休')]) start_year = rec.start_time.date().year