# -*- coding: utf-8 -*- from odoo import api, fields, models, tools, _ from odoo.exceptions import ValidationError, UserError import logging _logger = logging.getLogger(__name__) class YuthonNotice(models.Model): _name = "yuthon.notice" _description = '通知公告' _inherit = ['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="顺序",compute='_compute_sequence',store=True) employee_ids = fields.Many2many('hr.employee', string="人员范围") department_ids = fields.Many2many('hr.department', string='部门范围') users_role_ids = fields.Many2many('res.groups', string='角色范围') users_role_group_ids = fields.Many2many('res.groups', string='角色组', relation='yuthon_notice_role_group_rel') 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="当前经办人", store=True, ) @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): def get_department_employees(department_id): valid_user_ids = set() employee_ids = self.env['hr.employee'].search([('department_id', '=', department_id.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: if notice.env.context.get('skip_constrains'): continue 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 all_users = set( notice.employee_ids.mapped('user_id').ids + group_role_ids.mapped('users').ids + notice.users_role_ids.mapped('users').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) def _compute_sequence(self): for record in self: record.sequence = 1 # 工作流的指定申请人逻辑? # 转交的时候选择条件,进行优化 # 报表合同和产品业务 # 企业微信等三方平台框架--和工作流