208 lines
9.2 KiB
Python
208 lines
9.2 KiB
Python
# -*- coding: utf-8 -*-
|
||
from odoo import api, fields, models, tools, _
|
||
from odoo.exceptions import ValidationError, UserError
|
||
import logging
|
||
from datetime import datetime, timedelta, date
|
||
|
||
_logger = logging.getLogger(__name__)
|
||
|
||
|
||
class YuthonNotice(models.Model):
|
||
_name = "yuthon.notice"
|
||
_description = '通知公告'
|
||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||
_rec_name = 'name'
|
||
_order = "sequence desc"
|
||
|
||
name = fields.Char(string='标题')
|
||
code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('notice_code'))
|
||
users_id = fields.Many2one('res.users', string="发布人", default=lambda self: self.env.user)
|
||
company_id = fields.Many2one(related="users_id.employee_id.company_id", string="公司", store=True)
|
||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||
notice_type_id = fields.Many2one('yuthon.notice.type', string="类型")
|
||
create_date1 = fields.Date(string="发布日期", default=fields.Date.today())
|
||
start_date = fields.Date(string="生效日期", default=fields.Date.today())
|
||
end_date = fields.Date(string="终止日期")
|
||
sequence = fields.Integer(string="顺序", default=1, compute='_compute_sequence')
|
||
employee_ids = fields.Many2many('hr.employee', string="人员范围")
|
||
department_ids = fields.Many2many('hr.department', string='部门范围')
|
||
users_role_ids = fields.Many2many('soong.user.role', string='角色范围')
|
||
users_role_group_ids = fields.Many2many('soong.user.role.group', string='角色组')
|
||
notice_state = fields.Selection([('no', '未发布'), ('yes', '已发布'), ('stop', '已终止')], default='no', string="公告状态")
|
||
documents_ids = fields.Many2many('ir.attachment', string="附件")
|
||
is_notice_roger = fields.Selection([('yes', '已读'), ('no', '未读')], default='no', string="确认状态")
|
||
is_change_notice = fields.Boolean(string="是否发送通知", default=True)
|
||
attn_notice = fields.Html(string="经办人意见")
|
||
notice_text = fields.Html(string="正文")
|
||
read_number = fields.Integer(string='阅读量', compute="_compute_read_number", store=True)
|
||
is_this_company = fields.Boolean(string='本公司', default=True)
|
||
approval_user_id = fields.Many2one('res.users', string="审核人")
|
||
approval_date = fields.Datetime(string="审核日期")
|
||
is_sticky = fields.Boolean(string="是否置顶")
|
||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度', default='normal')
|
||
active = fields.Boolean('Active', default=True, tracking=True)
|
||
|
||
work_end = fields.Boolean(string="结束")
|
||
users_ids = fields.Many2many(
|
||
'res.users',
|
||
relation='yuthon_notice_users_rel',
|
||
column1='notice_id',
|
||
column2='user_id',
|
||
string='用户'
|
||
)
|
||
self_users_ids = fields.Many2many(
|
||
'res.users',
|
||
relation='yuthon_notice_current_users_rel',
|
||
column1='notice_id',
|
||
column2='user_id',
|
||
string="当前经办人",
|
||
default=lambda self: [(6, 0, [self.env.user.id])]
|
||
)
|
||
|
||
# @api.onchange('users_ids')
|
||
# def _onchange_users_ids(self):
|
||
# today = date.today()
|
||
# self.start_date = today
|
||
# self.create_date1 = today
|
||
|
||
@api.model_create_multi
|
||
def create(self, vals_list):
|
||
for i in vals_list:
|
||
if i['department_ids'] == i['employee_ids'] == i['users_role_ids'] == i['users_role_group_ids']:
|
||
raise UserError('请填写发布的范围')
|
||
return super().create(vals_list)
|
||
|
||
def _get_default_name_title(self):
|
||
return self._description if self._description else self._name
|
||
|
||
name_title = fields.Char(default=_get_default_name_title)
|
||
|
||
@api.constrains('employee_ids', 'department_ids', 'users_role_ids', 'users_role_group_ids')
|
||
def _constrains_employee_related_fields(self):
|
||
"""
|
||
约束验证:当关联字段变化时,更新users_ids
|
||
"""
|
||
def get_department_employees(department_id):
|
||
"""递归获取部门及其子部门的员工对应的user_id"""
|
||
valid_user_ids = set()
|
||
# 查找当前部门的员工(使用id替代id.origin)
|
||
employee_ids = self.env['hr.employee'].search([('department_id', '=', department_id.id)])
|
||
# 收集有效的user_id
|
||
valid_user_ids.update([emp.user_id.id for emp in employee_ids if emp.user_id])
|
||
# 递归处理子部门
|
||
child_ids = self.env['hr.department'].search([('parent_id', '=', department_id.id)])
|
||
for child in child_ids:
|
||
valid_user_ids.update(get_department_employees(child))
|
||
return valid_user_ids
|
||
|
||
for notice in self:
|
||
# 避免重复触发约束(更新users_ids时跳过本次约束检查)
|
||
if notice.env.context.get('skip_constrains'):
|
||
continue
|
||
# 获取部门关联的用户ID
|
||
department_user_ids = set()
|
||
for department_id in notice.department_ids:
|
||
department_user_ids.update(get_department_employees(department_id))
|
||
group_role_ids = notice.users_role_group_ids.user_role_ids
|
||
all_users = set(
|
||
notice.employee_ids.mapped('user_id').ids +
|
||
group_role_ids.mapped('personnel_ids.user_id').ids +
|
||
notice.users_role_ids.mapped('personnel_ids.user_id').ids +
|
||
list(department_user_ids)
|
||
)
|
||
notice.with_context(skip_constrains=True).users_ids = [(6, 0, list(all_users))]
|
||
|
||
def get_no_read_count(self):
|
||
return self.search_count([('is_notice_roger', '=', 'no'), ('notice_state', '=', 'yes')])
|
||
|
||
def read(self, fields=None, load='_classic_read'):
|
||
for con in self:
|
||
con_id = self.env['yuthon.confirm.users'].search([('notice_id', '=', con.id), ('employee_id', '=', con.env.user.employee_id.id)])
|
||
if con_id.employee_id == con.env.user.employee_id:
|
||
con.is_notice_roger = 'yes'
|
||
con_id.write({'state': 'yes'})
|
||
return super(YuthonNotice, self).read(fields=fields, load=load)
|
||
|
||
@api.depends('read_number')
|
||
def _compute_read_number(self):
|
||
notice_confirm_ids = self.env['yuthon.confirm.users'].search(
|
||
[('notice_id.id', '=', self.id), ('state', '=', 'yes')])
|
||
for read in self:
|
||
if notice_confirm_ids:
|
||
read.read_number = len(notice_confirm_ids)
|
||
else:
|
||
read.read_number = 0
|
||
|
||
def on_sequence(self):
|
||
self.sequence = 1
|
||
|
||
@api.onchange('is_sticky')
|
||
def _compute_sequence(self):
|
||
for i in self:
|
||
if i.is_sticky:
|
||
i.sequence = 1
|
||
else:
|
||
i.sequence = 0
|
||
|
||
def no_sequence(self):
|
||
self.sequence = 0
|
||
|
||
def notice_publish(self):
|
||
if self.is_change_notice:
|
||
conf_old = self.env['yuthon.confirm.users'].search([('notice_id', '=', self.id), ('employee_id', 'in', self.users_ids.ids)])
|
||
for user_id in self.users_ids:
|
||
url = f'http://oa.thtzjt.com/webh5#/notice?id={self.id}'
|
||
if conf_old:
|
||
for co in conf_old:
|
||
co.write({'state': 'no'})
|
||
else:
|
||
self.env['yuthon.confirm.users'].create({
|
||
'notice_id': self.id,
|
||
'employee_id': user_id.employee_ids.id,
|
||
'notice_code': self.code,
|
||
'notice_name': self.name,
|
||
'state': 'no',
|
||
})
|
||
we_id = self.env['hr.employee'].search([('id', '=', user_id.employee_ids.id)]).wecom_userid
|
||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='notice', user_id=we_id, title="通知公告",
|
||
description=self.name + '发布人:' + self.users_id.name,
|
||
url=url, btntxt="详细信息")
|
||
self.write({"notice_state": 'yes'})
|
||
return {
|
||
'type': 'ir.actions.client',
|
||
'tag': 'display_notification',
|
||
'params': {
|
||
'type': 'success',
|
||
'message': '通知公告已经发布',
|
||
'sticky': False,
|
||
}
|
||
}
|
||
else:
|
||
raise UserError('该公告不允许通知,请勾选通知')
|
||
|
||
|
||
def look_up_notice_users(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"name": "通知公告确认信息",
|
||
"domain": [("notice_id", "=", self.id)],
|
||
"res_model": "yuthon.confirm.users",
|
||
"view_mode": "tree",
|
||
"context": {
|
||
"search_default_group_state": True,
|
||
},
|
||
}
|
||
|
||
def stop_notice(self):
|
||
self.write({
|
||
'notice_state': 'stop',
|
||
'end_date': fields.Date.today(),
|
||
})
|
||
|
||
|
||
class YuthonCsTree(models.Model):
|
||
_name = 'yuthon.cs.tree'
|
||
_description = 'Yuthon Customer Service Tree'
|
||
|
||
name = fields.Char(string='Name', required=True)
|