From a4fd9f8210dac1b03b8de05dfc89fbfa5903f920 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: Thu, 18 Dec 2025 11:11:00 +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 --- .../controllers/home.py | 2 +- .../models/soong_workflow_record.py | 2 +- yuthon_will_task/__manifest__.py | 1 + yuthon_will_task/models/__init__.py | 1 + yuthon_will_task/models/yuthon_dates_task.py | 20 +++++ yuthon_will_task/models/yuthon_will_task.py | 75 ++++++++++++++++++- yuthon_will_task/security/ir.model.access.csv | 2 +- .../views/yuthon_dates_task_views.xml | 20 +++++ yuthon_will_task/views/yuthon_task_menu.xml | 5 ++ .../views/yuthon_will_task_views.xml | 3 +- 10 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 yuthon_will_task/models/yuthon_dates_task.py create mode 100644 yuthon_will_task/views/yuthon_dates_task_views.xml diff --git a/sh_backmate_theme_adv_enterprise/controllers/home.py b/sh_backmate_theme_adv_enterprise/controllers/home.py index 7a5f44f72..0b6289dd2 100644 --- a/sh_backmate_theme_adv_enterprise/controllers/home.py +++ b/sh_backmate_theme_adv_enterprise/controllers/home.py @@ -21,7 +21,7 @@ MENU_BADGE_MODEL_FUNC_ENUM = { 'yuthon_property.yuthon_property_rent_list': {'model': 'property.rent.list', 'func': 'get_no_read_count'}, 'yuthon_property.yuthon_property_management_list': {'model': 'property.management.list', 'func': 'get_no_read_count'}, 'yuthon_property.yuthon_property_deposit_list': {'model': 'property.deposit.list', 'func': 'get_no_read_count'}, - 'soong_workflow.menu_workflow_approval_request_my_start': {'model': 'soong.workflow.record', 'func': 'get_no_read_count'}, + 'soong_workflow.menu_soong_workflow_todo_record': {'model': 'soong.workflow.record', 'func': 'get_no_read_count'}, 'soong_workflow.menu_workflow_approval_request_copy': {'model': 'soong.workflow.record.copy', 'func': 'get_no_read_count'}, 'yuthon_will_task.menu_yuthon_will_task_root': {'model': 'yuthon.will.task', 'func': 'read_number'}, 'issue_library.yuthon_library_my_menu': {'model': 'issue.library', 'func': 'read_number'}, diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py index a5c4de307..c99f6e6bb 100644 --- a/soong_workflow/models/soong_workflow_record.py +++ b/soong_workflow/models/soong_workflow_record.py @@ -16,7 +16,7 @@ class SoongWorkflowRecord(models.Model): def get_no_read_count(self): domain = [ - ('approve_state', '=', 'pending'), + ('soong_state', '=', 'to_do'), ('employee_ids.user_id', '=', self.env.user.id), ('users_ids', 'in', self.env.user.id), ('reclaim_state', '=', False) diff --git a/yuthon_will_task/__manifest__.py b/yuthon_will_task/__manifest__.py index c20728651..095d22cb5 100644 --- a/yuthon_will_task/__manifest__.py +++ b/yuthon_will_task/__manifest__.py @@ -14,6 +14,7 @@ 'security/yuthon_will_task_security.xml', 'security/ir.model.access.csv', 'views/yuthon_will_task_views.xml', + 'views/yuthon_dates_task_views.xml', 'views/yuthon_task_time_views.xml', 'views/yuthon_task_menu.xml', ], diff --git a/yuthon_will_task/models/__init__.py b/yuthon_will_task/models/__init__.py index e748bc535..93c6a213a 100644 --- a/yuthon_will_task/models/__init__.py +++ b/yuthon_will_task/models/__init__.py @@ -1,3 +1,4 @@ from . import yuthon_will_task from . import yuthon_task_time from . import inherit_room_booking +from . import yuthon_dates_task diff --git a/yuthon_will_task/models/yuthon_dates_task.py b/yuthon_will_task/models/yuthon_dates_task.py new file mode 100644 index 000000000..58e67b239 --- /dev/null +++ b/yuthon_will_task/models/yuthon_dates_task.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import qrcode +import base64 +from io import BytesIO +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError, UserError +import os +from datetime import timedelta + + +class YuthonDatesTask(models.Model): + _name = "yuthon.dates.task" + _description = "日程任务" + + reminder_time = fields.Datetime(string='提醒时间') + yuthon_will_task_id = fields.Many2one('yuthon.will.task', string='关联日程管理') + employee_ids = fields.Many2many('hr.employee', string='提醒单位') + task_state = fields.Selection([('to_do', '待提醒'), ('done', '已提醒')], string='状态') + diff --git a/yuthon_will_task/models/yuthon_will_task.py b/yuthon_will_task/models/yuthon_will_task.py index 3798360d3..8828d8cf6 100644 --- a/yuthon_will_task/models/yuthon_will_task.py +++ b/yuthon_will_task/models/yuthon_will_task.py @@ -204,9 +204,14 @@ class YuthonWillTask(models.Model): def add_comment(self): self.ensure_one() - admin = self.env['hr.employee'].search([('name', '=', 'Administrator')]) - employee_list = [i.id for i in self.employee_ids] + [i.id for i in self.employee_ids2] + admin.id - for employee_id in self.env['hr.employee'].search([('id', 'in', employee_list)]): + employee_list = [] + for task in self.env['yuthon.dates.task'].search([('task_state', '=', 'to_do')]): + now = datetime.now() + if task.reminder_time == now: + task.task_state = 'done' + for task_time in task.employee_ids: + employee_list.append(task_time.employee_id) + for employee_id in employee_list: if not employee_id.wecom_userid: raise UserError("请同步{}的企业微信".format(employee_id.name)) url = f'https://oa.thtzjt.com/webh5#/journey?id={self.id}' @@ -252,4 +257,68 @@ class YuthonWillTask(models.Model): 'message': '已发送取消提醒消息', 'sticky': False, } + } + + @api.model + def create(self, vals): + """创建日程时,同步创建提醒任务""" + will_task = super(YuthonWillTask, self).create(vals) + will_task._sync_dates_task() + return will_task + + def write(self, vals): + """修改日程时,先删除旧提醒任务,再创建新的""" + res = super(YuthonWillTask, self).write(vals) + key_fields = ['start_date', 'request_hour_from', 'task_time_ids', 'employee_ids', 'employee_ids2'] + if any(field in vals for field in key_fields): + self._sync_dates_task() + return res + + def _sync_dates_task(self): + reminder_employees = self.employee_ids | self.employee_ids2 + if not reminder_employees: + return + old_tasks = self.env['yuthon.dates.task'].search([('yuthon_will_task_id', '=', self.id)]) + if old_tasks: + old_tasks.unlink() + start_hour = float(self.request_hour_from) + hours = int(start_hour) + minutes = int((start_hour - hours) * 60) + task_start_datetime = datetime.combine(self.start_date,time(hour=hours, minute=minutes)) + for task_time in self.task_time_ids: + reminder_time_str = task_time.name + reminder_hours = 0.0 + import re + match = re.match(r'(\d+)(分钟|小时|天)', reminder_time_str.strip()) + num = int(match.group(1)) + unit = match.group(2) + if unit == '小时': + reminder_hours = num + elif unit == '分钟': + reminder_hours = num / 60.0 + elif unit == '天': + reminder_hours = num * 24.0 + reminder_datetime = task_start_datetime - timedelta(hours=reminder_hours) + existing_dates_task = self.env['yuthon.dates.task'].search([ + ('yuthon_will_task_id', '=', self.id), + ('reminder_time', '=', reminder_datetime) + ]) + task_vals = { + 'reminder_time': reminder_datetime - timedelta(hours=8), + 'employee_ids': [(6, 0, reminder_employees.ids)], + 'task_state': 'to_do', + } + if existing_dates_task: + existing_dates_task.write(task_vals) + else: + task_vals['yuthon_will_task_id'] = self.id + self.env['yuthon.dates.task'].create(task_vals) + + def schedule_reminders(self): + return { + 'type': 'ir.actions.act_window', + 'name': '提醒任务详情', + 'view_mode': 'tree', + 'res_model': 'yuthon.dates.task', + 'domain': [('yuthon_will_task_id', '=', self.id)], } \ No newline at end of file diff --git a/yuthon_will_task/security/ir.model.access.csv b/yuthon_will_task/security/ir.model.access.csv index 6761eb5e7..4914348d6 100644 --- a/yuthon_will_task/security/ir.model.access.csv +++ b/yuthon_will_task/security/ir.model.access.csv @@ -1,6 +1,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_yuthon_task_time,yuthon_task_time,model_yuthon_task_time,yuthon_will_task.group_yuthon_will_task_user,1,1,1,1 access_yuthon_will_task,yuthon_will_task,model_yuthon_will_task,yuthon_will_task.group_yuthon_will_task_user,1,1,1,1 - +access_yuthon_dates_task,yuthon_dates_task,model_yuthon_dates_task,yuthon_will_task.group_yuthon_will_task_user,1,1,1,1 diff --git a/yuthon_will_task/views/yuthon_dates_task_views.xml b/yuthon_will_task/views/yuthon_dates_task_views.xml new file mode 100644 index 000000000..b95f921e4 --- /dev/null +++ b/yuthon_will_task/views/yuthon_dates_task_views.xml @@ -0,0 +1,20 @@ + + + + yuthon.dates.task.tree + yuthon.dates.task + + + + + + + + + + + 日程任务 + yuthon.dates.task + tree + + diff --git a/yuthon_will_task/views/yuthon_task_menu.xml b/yuthon_will_task/views/yuthon_task_menu.xml index 208b00a25..1b7b5861e 100644 --- a/yuthon_will_task/views/yuthon_task_menu.xml +++ b/yuthon_will_task/views/yuthon_task_menu.xml @@ -48,4 +48,9 @@ parent="task_type_menu" action="yuthon_task_time_setting_action" sequence="5"/> + \ No newline at end of file diff --git a/yuthon_will_task/views/yuthon_will_task_views.xml b/yuthon_will_task/views/yuthon_will_task_views.xml index 047654fd8..66d85a92a 100644 --- a/yuthon_will_task/views/yuthon_will_task_views.xml +++ b/yuthon_will_task/views/yuthon_will_task_views.xml @@ -26,6 +26,7 @@