diff --git a/yuthon_wechat/models/hr_attendance_detail.py b/yuthon_wechat/models/hr_attendance_detail.py index e5bdf94b1..a0b1be194 100644 --- a/yuthon_wechat/models/hr_attendance_detail.py +++ b/yuthon_wechat/models/hr_attendance_detail.py @@ -587,8 +587,10 @@ class HrAttendanceDetail(models.Model): if user.oauth_uid: # 查询当前用户区间内的所有打卡数据没有的创建 for current_date in self.divide_time_range_fixed(start_time, now_time): - # 写入打卡数据 + # 普通用户写入打卡数据 self._do_save_wx_attendance_data(user, current_date) + # 计划用户的打开时间 + # self._do_plan_save_wx_attendance_data(user, current_date) return True def _do_save_wx_attendance_data(self, user, current_date): @@ -613,36 +615,11 @@ class HrAttendanceDetail(models.Model): "attendance_type": "wx_work" }) - else: - return True # 暂时跳过 - planning_slot_id = self.env['planning.slot'].search( - [('resource_id', '=', hr_employee_obj.resource_id.id), - ('start_datetime', '>=', current_datetime_start), - ('start_datetime', '<=', current_datetime_end)]) - # 是否排班 - if planning_slot_id: - attendance_obj = self.env['hr.attendance'].sudo().create({ - 'employee_id': hr_employee_obj.id, - "userid": user.oauth_uid, - "current_data": current_date, - "shift_id": planning_slot_id.id, - "attendance_type": "wx_work" - }) - else: - # 没有排班 - return True if not hr_employee_obj.default_planning_role_id: if attendance_obj.is_approval: # 已经审批修复无需再次进行更新数据 return True self._do_not_planning_role(user, current_date, attendance_obj) - else: - return True # 暂时跳过 - if planning_slot_id: - if attendance_obj.is_approval: - # 已经审批修复无需再次进行更新数据 - return True - self._do_planning_role(user, current_date, attendance_obj) # 查询出当前抓取微信的当前时间的所有数据 attendance_detail_obj = self.env['hr.attendance.detail'].sudo().search( @@ -653,6 +630,45 @@ class HrAttendanceDetail(models.Model): attendance_detail_obj.hr_attendance_id = attendance_obj.id return True + def _do_plan_save_wx_attendance_data(self, user, current_date): + """ + 开始 整理 计划排版的 考勤数据 + :param user: + :param current_date: + :return: + """ + # 同步整理当天出勤数据 + hr_employee_obj = self.env['hr.employee'].sudo().search([("user_id", "=", user.id)], limit=1) + current_datetime_start = datetime.combine(datetime.strptime(current_date, '%Y-%m-%d'), datetime.min.time()) + current_datetime_end = datetime.combine(datetime.strptime(current_date, '%Y-%m-%d'), datetime.max.time()) + # 判断是否是 排版打卡 + if hr_employee_obj.default_planning_role_id: + planning_slot_ids = self.env['planning.slot'].search( + [('resource_id', '=', hr_employee_obj.resource_id.id), + ('start_datetime', '>=', current_datetime_start), + ('start_datetime', '<=', current_datetime_end)]) + for planning_slot_id in planning_slot_ids: + # 查询其中的一个排版信息是否生成了打卡记录 + attendance_obj = self.env['hr.attendance'].search( + [("userid", "=", user.oauth_uid), ("current_data", "=", current_date), ("shift_id", "=", planning_slot_id.id) + ], limit=1) + + if not attendance_obj: + self.env['hr.attendance'].sudo().create({ + 'employee_id': hr_employee_obj.id, + "userid": user.oauth_uid, + "current_data": current_date, + "shift_id": planning_slot_id.id, + "attendance_type": "wx_work" + }) + if attendance_obj.is_approval: + # 已经审批修复无需再次进行更新数据 + return True + + self._do_planning_role(user, current_date, attendance_obj, planning_slot_id) + + return True + def _do_not_planning_role(self, user, current_date, attendance_obj): """ 正常班次的 上班下班判断 @@ -716,95 +732,83 @@ class HrAttendanceDetail(models.Model): }) return True - def _do_planning_role(self, user, current_date, attendance_obj): + def _do_planning_role(self, user, current_date, attendance_obj, planning_id): """ 带有计划的班次判断 :param user: 用户集合 :param current_date: 循环判断的时间 :param attendance_obj: 判断的时刻的考勤集合 + :param planning_id: :return: """ - current_data = datetime.strptime(current_date, '%Y-%m-%d') - # 获取当天的起始和结束时间 - current_datetime_start = datetime.combine(current_data, datetime.min.time()) - current_datetime_end = datetime.combine(current_data, datetime.max.time()) - # 获取本人当天的班次 - hr_employee_obj = self.env['hr.employee'].sudo().search([("user_id", "=", user.id)], limit=1) + # 获取模板信息 + template_id = planning_id.planning_id + # check_in_start = fields.Datetime(string="上班开始") + check_in_start = template_id.check_in_start + # check_in_end = fields.Datetime(string="上班结束") + check_in_end = template_id.check_in_end + # check_out_start = fields.Datetime(string="下班开始") + check_out_start = template_id.check_out_start + # check_out_end = fields.Datetime(string="下班结束") + check_out_end = template_id.check_out_end + # 判断打卡情况排除未打卡情况 + # 上班 + attendance_detail_obj = self.env['hr.attendance.detail'].sudo().search( + [("exception_type", "!=", "未打卡"), + ("userid", "=", user.oauth_uid), + ("checkin_time", ">=", check_in_start), + ("checkin_time", "<=", check_in_end), + ]) + # 关联 打卡详情 + attendance_detail_obj.hr_attendance_id = attendance_obj.id - planning_ids = self.env['planning.slot'].search( - [('resource_id', '=', hr_employee_obj.resource_id.id), - ('start_datetime', '>=', current_datetime_start - timedelta(hours=8)), - ('start_datetime', '<=', current_datetime_end - timedelta(hours=8))]) + if len(attendance_detail_obj) <= 0: + attendance_obj.sudo().write({"is_no_card": True, "is_abnormal": True}) + # 打了一次卡记录说明缺卡 + else: + # 多次打卡时间的集合 + checkin_time_list = [obj.checkin_time for obj in attendance_detail_obj] + # 最早 时间 + min_time = min(checkin_time_list) + attendance_obj.sudo().write({ + "sch_check_in_time": planning_id.start_datetime, + "check_in": min_time, + "is_late_card": min_time > planning_id.start_datetime, + }) - for planning_id in planning_ids: - # 获取模板信息 - template_id = planning_id.planning_id - # check_in_start = fields.Datetime(string="上班开始") - check_in_start = template_id.check_in_start - # check_in_end = fields.Datetime(string="上班结束") - check_in_end = template_id.check_in_end - # check_out_start = fields.Datetime(string="下班开始") - check_out_start = template_id.check_out_start - # check_out_end = fields.Datetime(string="下班结束") - check_out_end = template_id.check_out_end - # 判断打卡情况排除未打卡情况 - # 上班 - attendance_detail_obj = self.env['hr.attendance.detail'].sudo().search( - [("exception_type", "!=", "未打卡"), - ("userid", "=", user.oauth_uid), - ("checkin_time", ">=", check_in_start), - ("checkin_time", "<=", check_in_end), - ]) - if len(attendance_detail_obj) <= 0: - attendance_obj.sudo().write({"is_no_card": True, "is_abnormal": True}) - # 打了一次卡记录说明缺卡 - else: - # 多次打卡时间的集合 - checkin_time_list = [obj.checkin_time for obj in attendance_detail_obj] - # 最早 时间 - min_time = min(checkin_time_list) + # 下班 + attendance_detail_obj = self.env['hr.attendance.detail'].sudo().search( + [("exception_type", "!=", "未打卡"), + ("userid", "=", user.oauth_uid), + ("checkin_time", ">=", check_out_start), + ("checkin_time", "<=", check_out_end), + ]) + # 关联 打卡详情 + attendance_detail_obj.hr_attendance_id = attendance_obj.id + + if len(attendance_detail_obj) <= 0: + attendance_obj.sudo().write({"is_no_card": True, "is_abnormal": True}) + # 打了一次卡记录说明缺卡 + else: + # 多次打卡时间的集合 + checkin_time_list = [obj.checkin_time for obj in attendance_detail_obj] + # 最早 时间 + max_time = max(checkin_time_list) + # 如果上班没有打卡 + if not attendance_obj.check_in: attendance_obj.sudo().write({ "sch_check_in_time": planning_id.start_datetime, - "check_in": min_time, - "is_late_card": min_time > planning_id.start_datetime, + "check_in": max_time, + "is_late_card": max_time < planning_id.start_datetime, + }) + else: + attendance_obj.sudo().write({ + "sch_check_out_time": planning_id.end_datetime, + "check_out": max_time, + "is_late_card": max_time < planning_id.end_datetime, "is_no_card": True, "is_abnormal": True, }) - # 下班 - attendance_detail_obj = self.env['hr.attendance.detail'].sudo().search( - [("exception_type", "!=", "未打卡"), - ("userid", "=", user.oauth_uid), - ("checkin_time", ">=", check_out_start), - ("checkin_time", "<=", check_out_end), - ]) - if len(attendance_detail_obj) <= 0: - attendance_obj.sudo().write({"is_no_card": True, "is_abnormal": True}) - # 打了一次卡记录说明缺卡 - else: - # 多次打卡时间的集合 - checkin_time_list = [obj.checkin_time for obj in attendance_detail_obj] - # 最早 时间 - max_time = max(checkin_time_list) - # 如果上班没有打卡 - if not attendance_obj.check_in: - attendance_obj.sudo().write({ - "sch_check_in_time": planning_id.start_datetime, - "check_in": max_time, - "is_late_card": max_time < planning_id.start_datetime, - "is_no_card": True, - "is_abnormal": True, - }) - else: - attendance_obj.sudo().write({ - "sch_check_out_time": planning_id.end_datetime, - "check_out": max_time, - "is_late_card": max_time < planning_id.end_datetime, - "is_no_card": True, - "is_abnormal": True, - }) - - if planning_id.role_id.name == '保安部': - pass return True