Files
gzth/yuthon_notice/models/yuthon_notice.py
T
2025-12-25 10:32:37 +08:00

208 lines
9.2 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.
# -*- 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)