From db1da4723f368b804767d4e2b73f256d67f1658b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Tue, 2 Sep 2025 18:52:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yuthon_hr_attendance/models/hr_attendance.py | 81 ++++++++++++++++++- .../models/hr_attendance_detail_wechat.py | 3 +- yuthon_notice/views/yuthon_notice_views.xml | 2 +- 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/yuthon_hr_attendance/models/hr_attendance.py b/yuthon_hr_attendance/models/hr_attendance.py index ea7aeb4fd..6e6240eff 100644 --- a/yuthon_hr_attendance/models/hr_attendance.py +++ b/yuthon_hr_attendance/models/hr_attendance.py @@ -221,9 +221,84 @@ class HrAttendance(models.Model): def missing_card_judgment(self): today = fields.Date.today() - attend_records = self.env['hr.attendance'].search(['current_data', '=', today]) - for record in attend_records: - record.is_no_card = not record.check_in or not record.check_out + employee_list = [] + role_ids = self.env['planning.role'].search([ + ('name', 'not in', ['厨卫(集团)', '项目运营岗']) + ]) + for role in role_ids: + for resource_id in role.resource_ids: + if resource_id.employee_id.id not in employee_list: + employee_list.append(resource_id.employee_id.id) + attend_records = self.env['hr.attendance'].search([ + ('current_data', '=', today), + ('employee_id', 'not in', employee_list) + ]) + all_employees = self.env['hr.employee'].search([ + ('id', 'not in', employee_list) + ]) + + # 判断是否为工作日 + is_workday = self._process_shift_days(today) + for employee in all_employees: + # 查找该员工当天的考勤记录 + employee_record = attend_records.filtered( + lambda r: r.employee_id.id == employee.id + ) + + # 工作日打卡情况判断 + if is_workday: + if employee_record: + is_no_card = not employee_record.check_in or not employee_record.check_out + else: + is_no_card = True + else: + is_no_card = False + + if employee_record: + # 更新现有记录的缺卡状态 + employee_record.write({'is_no_card': is_no_card}) + else: + # 没有记录且需要标记为缺卡时,创建新记录 + self.env['hr.attendance'].create({ + 'employee_id': employee.id, + 'current_data': today, + 'is_no_card': is_no_card, + 'check_in': False, + 'check_out': False + }) + + def _process_shift_days(self, current_data): + """ + 判断是否是工作日 调休日 双休 + """ + calendar_leaves = self.env['resource.calendar.leaves'].search([("calendar_id", "=", "行政考勤工作日")]) + holidays_list = [] + shift_days_list = [] + # 提取节假日和调休日 + for leave in calendar_leaves: + if leave.holidays: + holidays_list.extend(leave.holidays.split(',')) + if leave.alternate_rest_day: + holidays_list.extend(leave.alternate_rest_day.split(',')) + if leave.shift_replacement_day: + shift_days_list.extend(leave.shift_replacement_day.split(',')) + + holidays_list = [self.remove_leading_zero(date) for date in holidays_list] + shift_days_list = [self.remove_leading_zero(date) for date in shift_days_list] + + if (current_data in holidays_list) or (current_data.weekday() in [5, 6]): + return False + elif current_data in shift_days_list: + return True + else: + return True + + def remove_leading_zero(self, date_str): + month, day = date_str.split('月') + month = month.lstrip('0') + day = day.rstrip('日') + day = day.lstrip('0') + return f'{month}月{day}日' @api.depends('employee_id', 'check_in', 'check_out') def _compute_display_name(self): diff --git a/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py b/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py index f717d9f23..9dd789721 100644 --- a/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py +++ b/yuthon_hr_attendance/models/hr_attendance_detail_wechat.py @@ -350,7 +350,7 @@ class HrAttendanceDetail(models.Model): employee_list.append(resource_id.employee_id.id) if employee.id not in employee_list: # 判断是否工作日 - if not self._process_shift_days(current_data): + if self._process_shift_days(current_data): return is_early_card, is_late_card, is_abnormal, is_warning, absenteeism_card # 迟到判断 @@ -365,6 +365,7 @@ class HrAttendanceDetail(models.Model): # 迟到超过60分钟标记为旷工 if late_delta > 60: absenteeism_card = True + # 早退判断 if check_out and end_datetime and check_out < end_datetime: is_early_card = True diff --git a/yuthon_notice/views/yuthon_notice_views.xml b/yuthon_notice/views/yuthon_notice_views.xml index fdaa85e3c..2042f3ae8 100644 --- a/yuthon_notice/views/yuthon_notice_views.xml +++ b/yuthon_notice/views/yuthon_notice_views.xml @@ -79,7 +79,7 @@ - +