Files
gzth/yuthon_will_task/models/yuthon_will_task.py
T
2025-10-25 15:47:36 +08:00

254 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from odoo import api, fields, models, modules
import datetime
from datetime import datetime, timedelta, time
from odoo.exceptions import UserError
import logging
_logger = logging.getLogger(__name__)
class YuthonWillTask(models.Model):
_name = 'yuthon.will.task'
_description = '日程'
_rec_name = 'name'
# _inherit = ['mail.thread.main.attachment', 'mail.activity.mixin']
request_hour_from = fields.Selection([
('0', '0:00'), ('0.5', '0:30'),
('1', '01:00'), ('1.5', '01:30'),
('2', '02:00'), ('2.5', '02:30'),
('3', '03:00'), ('3.5', '03:30'),
('4', '04:00'), ('4.5', '04:30'),
('5', '05:00'), ('5.5', '05:30'),
('6', '06:00'), ('6.5', '06:30'),
('7', '07:00'), ('7.5', '07:30'),
('8', '08:00'), ('8.5', '08:30'),
('9', '09:00'), ('9.5', '09:30'),
('10', '10:00'), ('10.5', '10:30'),
('11', '11:00'), ('11.5', '11:30'),
('12', '12:00'), ('12.5', '12:30'),
('13', '13:00'), ('13.5', '13:30'),
('14', '14:00'), ('14.5', '14:30'),
('15', '15:00'), ('15.5', '15:30'),
('16', '16:00'), ('16.5', '16:30'),
('17', '17:00'), ('17.5', '17:30'),
('18', '18:00'), ('18.5', '18:30'),
('19', '19:00'), ('19.5', '19:30'),
('20', '20:00'), ('20.5', '20:30'),
('21', '21:00'), ('21.5', '21:30'),
('22', '22:00'), ('22.5', '22:30'),
('23', '23:00'), ('23.5', '23:30')], string='开始时间', default='9')
request_hour_to = fields.Selection([
('0', '12:00'), ('0.5', '12:30'),
('1', '01:00'), ('1.5', '01:30'),
('2', '02:00'), ('2.5', '02:30'),
('3', '03:00'), ('3.5', '03:30'),
('4', '04:00'), ('4.5', '04:30'),
('5', '05:00'), ('5.5', '05:30'),
('6', '06:00'), ('6.5', '06:30'),
('7', '07:00'), ('7.5', '07:30'),
('8', '08:00'), ('8.5', '08:30'),
('9', '09:00'), ('9.5', '09:30'),
('10', '10:00'), ('10.5', '10:30'),
('11', '11:00'), ('11.5', '11:30'),
('12', '12:00'), ('12.5', '12:30'),
('13', '13:00'), ('13.5', '13:30'),
('14', '14:00'), ('14.5', '14:30'),
('15', '15:00'), ('15.5', '15:30'),
('16', '16:00'), ('16.5', '16:30'),
('17', '17:00'), ('17.5', '17:30'),
('18', '18:00'), ('18.5', '18:30'),
('19', '19:00'), ('19.5', '19:30'),
('20', '20:00'), ('20.5', '20:30'),
('21', '21:00'), ('21.5', '21:30'),
('22', '22:00'), ('22.5', '22:30'),
('23', '23:00'), ('23.5', '23:30')], string='结束时间', default='18')
priority = fields.Selection([('general', '不紧急不重要'), ('important', '重要不紧急'),
('urgent', '紧急不重要'), ('very_urgent', '重要且紧急')], string='优先级', default='general')
code = fields.Char(string="任务编号", default=lambda self: self.env['ir.sequence'].next_by_code('task_code'))
user_id = fields.Many2one('res.users', string="创建人", default=lambda self: self.env.user)
company_id = fields.Many2one('res.company', string="公司", default=lambda self: self.env.company)
name = fields.Text(string='任务内容')
remarks = fields.Text(string='备注')
creation_time = fields.Date(string='创建时间', default=fields.Date.today())
employee_ids = fields.Many2many('hr.employee', 'will_task_employee_rel', 'custom_id', 'employee_id',
string='人员', store=True, index=True)
employee_ids2 = fields.Many2many('hr.employee', 'will_task_employee_rel2', 'custom_id', 'employee_id',
string='司机', store=True, index=True)
user_role_ids = fields.Many2many('soong.user.role', string='角色', store=True, index=True)
task_time_ids = fields.Many2many('yuthon.task.time', string='提醒')
document_ids = fields.Many2many('ir.attachment', string="附件")
address = fields.Char(string='地点')
start_date = fields.Date(string='开始日期', default=fields.Date.today)
task_time = fields.Char(string='任务时间', compute='_compute_task_time')
is_this_company = fields.Boolean(string='本公司', default=True)
task_state = fields.Selection([('will', '待办'), ('done', '已办'), ('cancel', '取消')], default='will', string='状态', store=True)
users_ids = fields.Many2many(
'res.users',
relation='yuthon_will_task_users_rel', #
column1='task_id',
column2='user_id',
string='用户',
store=True,
index=True,
default=lambda self: self.env.user
)
self_users_ids = fields.Many2many(
'res.users',
relation='yuthon_will_task_current_users_rel',
column1='task_id',
column2='user_id',
string="当前经办人",
store=True, default=lambda self: [(6, 0, [self.env.user.id])]
)
@api.depends('start_date', 'request_hour_from', 'request_hour_to')
def _compute_task_time(self):
for record in self:
date_str = ""
if record.start_date:
date_str = record.start_date.strftime("%Y/%m/%d")
hour_mapping = {
'0': '0:00', '0.5': '0:30',
'1': '01:00', '1.5': '01:30',
'2': '02:00', '2.5': '02:30',
'3': '03:00', '3.5': '03:30',
'4': '04:00', '4.5': '04:30',
'5': '05:00', '5.5': '05:30',
'6': '06:00', '6.5': '06:30',
'7': '07:00', '7.5': '07:30',
'8': '08:00', '8.5': '08:30',
'9': '09:00', '9.5': '09:30',
'10': '10:00', '10.5': '10:30',
'11': '11:00', '11.5': '11:30',
'12': '12:00', '12.5': '12:30',
'13': '13:00', '13.5': '13:30',
'14': '14:00', '14.5': '14:30',
'15': '15:00', '15.5': '15:30',
'16': '16:00', '16.5': '16:30',
'17': '17:00', '17.5': '17:30',
'18': '18:00', '18.5': '18:30',
'19': '19:00', '19.5': '19:30',
'20': '20:00', '20.5': '20:30',
'21': '21:00', '21.5': '21:30',
'22': '22:00', '22.5': '22:30',
'23': '23:00', '23.5': '23:30'
}
from_time = hour_mapping.get(record.request_hour_from, "")
to_time = hour_mapping.get(record.request_hour_to, "")
if date_str and from_time and to_time:
record.task_time = f"{date_str} ({from_time}--{to_time})"
else:
record.task_time = ""
@api.onchange('employee_ids', 'user_id')
def _onchange_employee_ids(self):
user_ids = []
if self.user_id:
user_ids.append(self.user_id.id)
for employee in self.employee_ids:
if employee.user_id:
user_ids.append(employee.user_id.id)
for employee2 in self.employee_ids2:
if employee2.user_id:
user_ids.append(employee2.user_id.id)
roles = self.employee_ids.mapped('user_role_id')
self.user_role_ids = roles
self.users_ids = [(6, 0, user_ids)]
def read_number(self):
return self.search_count([('task_state', '=', 'will'), ('users_ids', 'in', self.env.user.id)])
def will_task_time(self):
# 任务状态判断
for task in self.search([('task_state', '=', 'will')]):
# 计算开始时间(将日期和时间选择转换为datetime对象)
hour_from = float(task.request_hour_from)
start_hour = int(hour_from)
start_minute = int((hour_from - start_hour) * 60)
start_datetime = datetime.combine(fields.Date.from_string(task.start_date), time(start_hour, start_minute))
if task.request_hour_to:
hour_to = float(task.request_hour_to)
end_hour = int(hour_to)
end_minute = int((hour_to - end_hour) * 60)
end_datetime = start_datetime.replace(hour=end_hour, minute=end_minute)
else:
end_datetime = start_datetime + timedelta(hours=1)
now = datetime.now() + timedelta(hours=8)
if now > end_datetime:
task.write({'task_state': 'done'})
continue
_logger.info(f"日程消息提醒定时任务判断\n当前时间:{now} --- 任务开始时间:{start_datetime}")
if now <= start_datetime:
if task.task_time_ids:
for task_time in task.task_time_ids:
duration = self._compute_duration(task_time)
trigger_time = now + duration
_logger.info(f"判断可否发送消息\n任务天:-{trigger_time.day}时:-{trigger_time.hour}分:-{trigger_time.minute}\n当前天:-{start_datetime.day}时:-{start_datetime.hour}分:-{start_datetime.minute}")
if (trigger_time.day == start_datetime.day and trigger_time.hour == start_datetime.hour and trigger_time.minute == start_datetime.minute):
task.add_comment()
def _compute_duration(self, task_time):
if task_time.task_unit == 'min':
return timedelta(minutes=task_time.number)
elif task_time.task_unit == 'hour':
return timedelta(hours=task_time.number)
elif task_time.task_unit == 'day':
return timedelta(days=task_time.number)
else:
return timedelta.max
def add_comment(self):
self.ensure_one()
employee_list = [i.id for i in self.employee_ids] + [i.id for i in self.employee_ids2]
for employee_id in self.env['hr.employee'].search([('id', 'in', employee_list)]):
if not employee_id.wecom_userid:
raise UserError("请同步{}的企业微信".format(employee_id.name))
url = f'http:://oa.thtzjt.com/webh5#/journey?id={self.id}'
data_name = "事项名称: " + self.name + '\n'
data_user_ids = '参与人: ' + ', '.join(self.employee_ids.mapped('name')) + '\n'
data_employee_id = ('司机:' + ', '.join(self.employee_ids2.mapped('name')) + '\n') if self.employee_ids2 else ''
data_nota = ('备注:' + self.remarks) if self.remarks else ('') + '\n'
data = data_name + data_user_ids + data_nota + data_employee_id
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='task', user_id=employee_id.wecom_userid,title="日程事项提醒", description=data,
url=url, btntxt="详细信息")
def button_add_comment(self):
self.add_comment()
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'type': 'success',
'message': '已发送提醒消息',
'sticky': False,
}
}
def button_add_comment_cancel(self):
self.write({'task_state': 'cancel'})
employee_list = [i.id for i in self.employee_ids] + [i.id for i in self.employee_ids2]
for employee_id in self.env['hr.employee'].search([('id', 'in', employee_list)]):
if not employee_id.wecom_userid:
raise UserError("请同步{}的企业微信".format(employee_id.name))
menu_id = self.env['ir.ui.menu'].search([('name', '=', '我的日程')])
url = f'https://oa.thtzjt.com/web#id={self.id}&cids=2&action={menu_id.action.id}&model=yuthon.will.task&view_type=list&menu_id={menu_id.id}'
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='task', user_id=employee_id.wecom_userid,
title="日程事项提醒", description="事项名称: " + self.name + '\t' + '该事项已取消',
url=url, btntxt="详细信息")
for record in self:
partner_ids = record.employee_ids.user_id.partner_id.ids
record.with_context(lang=record.env.lang)._message_auto_subscribe_notify(partner_ids, 'yuthon_will_task.mail_action_yuthon_will_task_add_comment')
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'type': 'success',
'message': '已发送取消提醒消息',
'sticky': False,
}
}