diff --git a/yuthon_salary/__manifest__.py b/yuthon_salary/__manifest__.py index 4d4ec6f2b..32ce24331 100644 --- a/yuthon_salary/__manifest__.py +++ b/yuthon_salary/__manifest__.py @@ -15,6 +15,8 @@ 'security/ir.model.access.csv', 'security/salary_security_rule.xml', 'data/rank_log_time.xml', + 'data/meal_cron.xml', + 'views/inherit_hr_payroll_structure_views.xml', 'views/inherit_hr_salary_rule_views.xml', 'views/inherit_hr_payslip_views.xml', diff --git a/yuthon_salary/data/meal_cron.xml b/yuthon_salary/data/meal_cron.xml new file mode 100644 index 000000000..70f16da63 --- /dev/null +++ b/yuthon_salary/data/meal_cron.xml @@ -0,0 +1,18 @@ + + + + + 定时任务:餐费缴费提醒 + + code + model.cron_send_meal_reminder() + + + 1 + days + + -1 + + + + diff --git a/yuthon_salary/models/yuthon_meal_expenses.py b/yuthon_salary/models/yuthon_meal_expenses.py index b1944cd90..c264729a2 100644 --- a/yuthon_salary/models/yuthon_meal_expenses.py +++ b/yuthon_salary/models/yuthon_meal_expenses.py @@ -109,6 +109,35 @@ class YuthonMealExpenses(models.Model): to_update.write({'meal_state': 'done'}) return True + def cron_send_meal_reminder(self): + """定时任务:给状态为已发送且缴费状态为待缴的记录发送缴费提醒""" + # 找出所有 已发送 且 仍然 待缴 的餐费记录 + meals = self.sudo().search([ + ('meal_state', '=', 'done'), + ('toll_state', '=', 'to_do'), + ]) + for meal in meals: + # 如果早餐次数和午餐次数都为0,则不发送提醒 + if meal.number_breakfasts == 0 and meal.number_lunches == 0: + continue + employee = meal.employee_id + if not employee or not employee.user_id or not employee.wecom_userid: + continue + # 和现有手机端餐费链接保持一致 + url = f'https://phone.thtzjt.com/phone/Meal/{employee.user_id.id}' + # 提示文案,按照要求修改 + employee_name = employee.name or '' + description = ( + f'{employee_name},您尚有餐费未缴纳,请及时登录系统查看并完成缴费,感谢配合。' + ) + self.sudo().env["wecom.apps"].sync_send_message_textcard( + category='can', + user_id=employee.wecom_userid, + title="缴纳餐费提醒", + description=description, + url=url, + btntxt="详细信息", + ) def action_generate_missing_feb(self): target_year = '2026' @@ -159,3 +188,133 @@ class YuthonMealExpenses(models.Model): ('date', '>=', date_start), ('date', '<=', date_end)], } + + def action_send_reminder(self): + """一键催缴:手动发送缴费提醒""" + self.ensure_one() + # 如果早餐次数和午餐次数都为0,则不发送提醒 + if self.number_breakfasts == 0 and self.number_lunches == 0: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '提醒', + 'message': '该记录早餐和午餐次数都为0,无需发送提醒', + 'type': 'info', + 'sticky': False, + } + } + employee = self.employee_id + if not employee or not employee.user_id or not employee.wecom_userid: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '错误', + 'message': '员工信息不完整,无法发送提醒', + 'type': 'danger', + 'sticky': False, + } + } + # 和现有手机端餐费链接保持一致 + url = f'https://phone.thtzjt.com/phone/Meal/{employee.user_id.id}' + # 提示文案,按照要求修改 + employee_name = employee.name or '' + description = ( + f'{employee_name},您尚有餐费未缴纳,请及时登录系统查看并完成缴费,感谢配合。' + ) + try: + self.sudo().env["wecom.apps"].sync_send_message_textcard( + category='can', + user_id=employee.wecom_userid, + title="缴纳餐费提醒", + description=description, + url=url, + btntxt="详细信息", + ) + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '发送成功', + 'message': '提醒已发送给员工', + 'type': 'success', + 'sticky': False, + } + } + except Exception as e: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '发送失败', + 'message': f'提醒发送失败:{str(e)}', + 'type': 'danger', + 'sticky': False, + } + } + + def action_batch_send_reminder(self): + """批量催缴:发送提醒给所有符合条件的员工""" + # 查询所有缴费状态为待缴,状态为已发送的记录 + meals = self.sudo().search([ + ('meal_state', '=', 'done'), + ('toll_state', '=', 'to_do'), + ]) + + success_count = 0 + skip_count = 0 + error_count = 0 + + for meal in meals: + # 如果早餐次数和午餐次数都为0,则不发送提醒 + if meal.number_breakfasts == 0 and meal.number_lunches == 0: + skip_count += 1 + continue + + employee = meal.employee_id + if not employee or not employee.user_id or not employee.wecom_userid: + error_count += 1 + continue + + # 和现有手机端餐费链接保持一致 + url = f'https://phone.thtzjt.com/phone/Meal/{employee.user_id.id}' + # 提示文案,按照要求修改 + employee_name = employee.name or '' + description = ( + f'{employee_name},您尚有餐费未缴纳,请及时登录系统查看并完成缴费,感谢配合。' + ) + try: + self.sudo().env["wecom.apps"].sync_send_message_textcard( + category='can', + user_id=employee.wecom_userid, + title="缴纳餐费提醒", + description=description, + url=url, + btntxt="详细信息", + ) + success_count += 1 + except Exception: + error_count += 1 + + # 构建返回消息 + message_parts = [] + if success_count > 0: + message_parts.append(f'成功发送{success_count}条提醒') + if skip_count > 0: + message_parts.append(f'跳过{skip_count}条记录(早餐和午餐次数都为0)') + if error_count > 0: + message_parts.append(f'失败{error_count}条记录(员工信息不完整)') + + message = ';'.join(message_parts) + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '批量催缴完成', + 'message': message, + 'type': 'success' if success_count > 0 else 'info', + 'sticky': False, + } + } diff --git a/yuthon_salary/views/yuthon_meal_expenses_views.xml b/yuthon_salary/views/yuthon_meal_expenses_views.xml index 5591a763f..8bac3845d 100644 --- a/yuthon_salary/views/yuthon_meal_expenses_views.xml +++ b/yuthon_salary/views/yuthon_meal_expenses_views.xml @@ -27,6 +27,7 @@
@@ -41,6 +42,7 @@