From f03d9e7ee55e4554de2da9c1796456b0ebee5e9c 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: Wed, 22 Apr 2026 10:18:35 +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 --- .../models/message_reminder_tasks.py | 133 +++++++++++------- 1 file changed, 82 insertions(+), 51 deletions(-) diff --git a/yuthon_hr_attendance/models/message_reminder_tasks.py b/yuthon_hr_attendance/models/message_reminder_tasks.py index c3e8715b2..4da78d6ae 100644 --- a/yuthon_hr_attendance/models/message_reminder_tasks.py +++ b/yuthon_hr_attendance/models/message_reminder_tasks.py @@ -22,13 +22,29 @@ class MessageReminderTasks(models.Model): holiday = fields.Boolean(string="假期") def get_reminder_tasks(self): + """每天自动生成当日提醒任务""" current_date = (fields.Date.today() + relativedelta(hours=8)).date() + self._generate_reminder_tasks_by_date(current_date) + + def generate_weekly_reminder_tasks(self): + """批量生成 2026-04-15 至 2026-04-21 提醒任务""" + start_date = fields.Date.from_string('2026-04-15') + end_date = fields.Date.from_string('2026-04-21') + + current_date = start_date + while current_date <= end_date: + self._generate_reminder_tasks_by_date(current_date) + current_date += timedelta(days=1) + + def _generate_reminder_tasks_by_date(self, current_date): + """按指定日期生成提醒任务(每日/批量共用逻辑)""" target_company_names = ['天河物管', '天河粮储', '集团本部'] target_companies = self.env['res.company'].search([('name', 'in', target_company_names)]) target_calendars = self.env['resource.calendar'].search([ ('company_id', 'in', target_companies.ids) ]) - # 获取日历关联的白名单员工 + + # 日历白名单员工 whitelist_employees = target_calendars.mapped('resource_user_ids').ids condition1_employees = self.env['hr.employee'].search([ ('id', 'not in', whitelist_employees), @@ -36,42 +52,50 @@ class MessageReminderTasks(models.Model): ('user_state', '=', 'in'), ('active', '=', True) ]) + + # 角色:保安、工程、联安粮库 target_role_names = ['保安部', '工程部', '联安粮库'] - target_roles = self.env['planning.role'].search([ - ('name', 'in', target_role_names) - ]) - default_reminder_types = ['work', 'offWork'] - default_reminder_times = [ - datetime.combine(current_date, datetime.strptime('00:55', '%H:%M').time()), # 时差 - datetime.combine(current_date, datetime.strptime('10:00', '%H:%M').time()) - ] + target_roles = self.env['planning.role'].search([('name', 'in', target_role_names)]) + condition2_employee_ids = [] if target_roles: for role in target_roles: resource_employees = role.resource_ids.mapped('employee_id') condition2_employee_ids.extend(resource_employees) condition2_employee_ids = list(set(condition2_employee_ids)) + # 哺乳人员 breastfeeding_employees = target_calendars.mapped('breastfeeding_holiday_ids.employee_id') - breastfeeding_employee_ids = breastfeeding_employees.ids if breastfeeding_employees else [] - # 获取不在白名单且是行政班次的人员 + breastfeeding_employee_ids = breastfeeding_employees.ids or [] + + # 行政班人员(不在白名单、不在角色排班) final_employees = condition1_employees.filtered(lambda emp: emp not in condition2_employee_ids) + task_vals_list = [] is_workday = self._process_shift_days(current_date) - template = self.env['planning.slot.template'].search( - [('role_id.name', '=', '集团行政')], - limit=1 - ) + + # 集团行政模板 + template = self.env['planning.slot.template'].search([('role_id.name', '=', '集团行政')], limit=1) sch_check_in_time, sch_check_out_time = self.normal_clock_in_time(template, current_date) + + # 默认提醒时间 + default_reminder_times = [ + datetime.combine(current_date, datetime.strptime('00:55', '%H:%M').time()), + datetime.combine(current_date, datetime.strptime('10:00', '%H:%M').time()) + ] + default_reminder_types = ['work', 'offWork'] + + # 1. 行政班次 if is_workday: for employee in final_employees: emp_name = employee.name emp_department = employee.department_id.name emp_company = employee.company_id.name is_lactating = employee.id in breastfeeding_employee_ids + if is_lactating: - # 哺乳人员 - reminder_times = self.get_reminder_lactating_personnel(employee, current_date, sch_check_in_time, sch_check_out_time) + reminder_times = self.get_reminder_lactating_personnel(employee, current_date, sch_check_in_time, + sch_check_out_time) reminder_types = ['work', 'offWork'] shift_name = '行政班次(哺乳)' else: @@ -79,59 +103,66 @@ class MessageReminderTasks(models.Model): reminder_types = default_reminder_types shift_name = '行政班次' - for reminder_time, reminder_type in zip(reminder_times, reminder_types): + for rt, rtype in zip(reminder_times, reminder_types): task_vals = { 'name': emp_name, - 'current_data': reminder_time.date(), + 'current_data': rt.date(), 'department': emp_department, 'company': emp_company, 'shift_name': shift_name, - 'type': reminder_type, - 'reminder_time': fields.Datetime.to_string(reminder_time), + 'type': rtype, + 'reminder_time': fields.Datetime.to_string(rt), } task_vals_list.append(task_vals) - # 计划行政 + # 2. 计划排班班次 slot_start = datetime.combine(current_date, datetime.min.time()) - timedelta(hours=8) slot_end = datetime.combine(current_date + timedelta(days=1), datetime.min.time()) - timedelta(hours=8) - # 查找员工对应的班次 + for employee in condition2_employee_ids: - reminder_plan_times = [] - reminder_plan_types = [] planning_slot = self.env['planning.slot'].search([ ('resource_id.name', '=', employee.name), ('start_datetime', '>=', slot_start), ('start_datetime', '<', slot_end), ], limit=1) - template = self.env['planning.slot.template'].search([('planning_name', '=', planning_slot.planning_name)], limit=1) - if template: - sch_check_in_time, sch_check_out_time = self.normal_clock_in_time(template, current_date) - is_lactating = employee.id in breastfeeding_employee_ids - if is_lactating: - reminder_plan_times = self.get_reminder_lactating_personnel(employee.id, current_date, sch_check_in_time, sch_check_out_time) - reminder_plan_types = ['work', 'offWork'] - shift_name = f"{template.planning_name}(哺乳)" - else: - reminder_plan_times.append(sch_check_in_time - timedelta(minutes=5)) - reminder_plan_types.append('work') - reminder_plan_times.append(sch_check_out_time) - reminder_plan_types.append('offWork') - shift_name = template.planning_name + if not planning_slot: + continue - for reminder_time, reminder_type in zip(reminder_plan_times, reminder_plan_types): - task_plan_vals = { - 'name': employee.name, - 'department': employee.department_id.name, - 'company': employee.company_id.name, - 'shift_name': shift_name, - 'current_data': (reminder_time + relativedelta(hours=8)).date(), - 'type': reminder_type, - 'reminder_time': fields.Datetime.to_string(reminder_time), - } - task_vals_list.append(task_plan_vals) + template = self.env['planning.slot.template'].search([ + ('planning_name', '=', planning_slot.planning_name) + ], limit=1) - self.env['message.reminder.tasks'].create(task_vals_list) + if not template: + continue + + c_in, c_out = self.normal_clock_in_time(template, current_date) + is_lactating = employee.id in breastfeeding_employee_ids + + if is_lactating: + r_times = self.get_reminder_lactating_personnel(employee, current_date, c_in, c_out) + r_types = ['work', 'offWork'] + shift_name = f"{template.planning_name}(哺乳)" + else: + r_times = [c_in - timedelta(minutes=5), c_out] + r_types = ['work', 'offWork'] + shift_name = template.planning_name + + for rt, rtype in zip(r_times, r_types): + task_plan_vals = { + 'name': employee.name, + 'department': employee.department_id.name, + 'company': employee.company_id.name, + 'shift_name': shift_name, + 'current_data': (rt + timedelta(hours=8)).date(), + 'type': rtype, + 'reminder_time': fields.Datetime.to_string(rt), + } + task_vals_list.append(task_plan_vals) + + # 创建数据 + if task_vals_list: + self.env['message.reminder.tasks'].create(task_vals_list) def get_reminder_lactating_personnel(self, employee, current_data, sch_check_in_time, sch_check_out_time):