# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from email.policy import default from odoo import fields, models, api from odoo.exceptions import UserError, ValidationError from datetime import datetime, date, time, timedelta class SoongWorkflowCommentWizard(models.TransientModel): _name = "soong.workflow.comment.wizard" _description = "Soong Workflow Comment Wizard" _inherit = ['mail.thread.main.attachment', 'mail.activity.mixin'] name = fields.Char(string="name") res_model = fields.Char() res_id = fields.Integer() code = fields.Char() log_ids = fields.Many2many(comodel_name="soong.workflow.log") node_btn_id = fields.Many2one(comodel_name="soong.workflow.node.button") node_btn_name = fields.Char(string="动作名称", related='node_btn_id.name') user_id = fields.Many2one('res.users', string='用户', default=lambda self: self.env.user) user_role_ids = fields.Many2many('soong.user.role', string="角色", compute='_compute_user_role_ids', store=True) node_link_len = fields.Char(string="转交2") is_supervising = fields.Boolean(string="是否督办") comment_note_id = fields.Many2one('soong.note', string="常用意见", default='妥否,呈领导审批') comment_note = fields.Char(string="意见", default='同意') comment = fields.Char(compute='_compute_comment', store=True) state_list = fields.Char(string="状态列表") record_id = fields.Integer() trans_link_id = fields.Many2one('trans.link', string='转交节点') document_ids = fields.Many2many('ir.attachment', string="附件") return_link_id = fields.Many2one('trans.link', string='退回节点') invalid_link_ids = fields.Many2many( 'trans.link', string='无审批人节点', compute='_compute_invalid_link_ids', help='没有找到符合条件审批人的节点' ) employee_trans_domain_ids = fields.Many2many('hr.employee', 'employee_trans_domain_ids_rel', string="传阅人员", store=True) employee_ids = fields.Many2many('hr.employee', 'employee_ids_rel', 'custom_id', 'employee_id', string="传阅人员", store=True) circulated_employee_ids = fields.Many2many('hr.employee', 'circulated_employee_rel', 'custom_id', 'employee_id', string="传阅人员", store=True) supervising_employee_ids = fields.Many2many('hr.employee', 'supervising_employee_rel', 'custom_id', 'employee_id', string="督办人员", store=True) approval_concatenation = fields.Selection([('chuan', '串申'), ('bing', '并申')], string="审批形式", help='并:任何人均给意见,最后一个完成的人转交到下一节点.' '串:都会收到消息,但任意一个人转交后,即到下一节点,其他人将不再显示,相当于收回.') is_automatic = fields.Boolean('是否自动匹配') employee_ids1 = fields.Many2many( 'hr.employee', 'employee_ids1_rel', 'custom_id1', 'employee_id1', string="转交人员", store=True ) @api.onchange('employee_ids1') def _onchange_employee_ids1(self): if len(self.employee_ids1) == 1: self.employee_ids = self.employee_ids1 @api.constrains('employee_ids') def _check_employee_ids(self): if not self.employee_ids and self.node_btn_name != '结束': raise ValidationError("必须有转交人员") @api.depends('comment_note_id', 'comment_note') def _compute_comment(self): for record in self: comment_parts = [] if record.comment_note_id: comment_parts.append(record.comment_note_id.name) if record.comment_note: comment_parts.append(record.comment_note) record.comment = " ".join(comment_parts) if comment_parts else "" @api.depends('user_id.employee_ids.user_role_ids', 'user_id.employee_ids.user_role_id') def _compute_user_role_ids(self): for record in self: if record.user_id and record.user_id.employee_ids: role_ids_from_employee = record.user_id.employee_ids.user_role_ids role_id_from_field = record.user_id.employee_ids.user_role_id if role_id_from_field: record.user_role_ids = role_ids_from_employee | role_id_from_field else: record.user_role_ids = role_ids_from_employee else: record.user_role_ids = False @api.onchange('record_id') def _onchange_record_id(self): record_id = self.env[self.res_model].search([('id', '=', self.res_id)]) self.record_id = record_id @api.onchange('return_link_id') def onchange_employee_ids(self): record_id = self.env[self.res_model].search([('id', '=', self.res_id)]) for ret in self.return_link_id: if ret.name in ['拟办', '申请人']: self.employee_ids1 = record_id.users_id.employee_ids elif self.node_btn_name == '退回': next_list = [] workflow_id = self.return_link_id.node_button_id.workflow_id state_list = [i.node_name for i in workflow_id.node_ids] self_state = state_list.index(ret.name) button_ids = workflow_id.node_ids[self_state].button_ids for btn in button_ids: next_list.append(btn.name) if '转交' not in next_list: raise UserError('配置错误,请配置当前{}的转交按钮'.format(btn.name)) else: if btn.is_automatic: employee_user_role_id = self.env['hr.employee'].search( ['|', ('user_role_id', '=', btn.users_role_id.id), ('user_role_id', 'in', btn.users_role_group_ids.user_role_ids.ids), ('department_id', '=', record_id.department_id.id)]) self.employee_ids1 = employee_user_role_id else: employee_user_role_ids = self.env['hr.employee'].search( ['|', ('user_role_id', '=', btn.users_role_id.id), ('user_role_id', 'in', btn.users_role_group_ids.user_role_ids.ids), ]) self.employee_ids1 = employee_user_role_ids @api.depends('trans_link_id') def _compute_invalid_link_ids(self): for record in self: invalid_links = self.env['trans.link'] ctx_links = self.env.context.get('all_workflow_links', []) all_links = self.env['trans.link'].browse(ctx_links) if isinstance(ctx_links, (list, tuple)) else ctx_links record_id = self.env[record.res_model].browse(record.res_id) if record.res_model and record.res_id else None for link in all_links: if not link or isinstance(link, int): continue # 使用封装方法 approvers = self._get_approvers_for_link(link, record_id) if not approvers: invalid_links |= link record.invalid_link_ids = invalid_links @api.onchange('trans_link_id') def onchange_trans_employee_ids(self): for record in self: if not record.trans_link_id: continue record_id = self.env[record.res_model].browse(record.res_id) if record.res_model and record.res_id else None for link in record.trans_link_id: employee_user_role_ids = self._get_approvers_for_link(link, record_id) workflow_id = link.node_button_id.workflow_id node = workflow_id.node_ids.search([ ('name', '=', link.name), ('workflow_id', '=', workflow_id.id) ]) record.approval_concatenation = node.approval_concatenation record.employee_trans_domain_ids = employee_user_role_ids record.employee_ids1 = employee_user_role_ids def _get_approvers_for_link(self, link, record_id=None): """ 参数: link: trans.link 记录对象 record_id: 关联的业务记录对象 返回: hr.employee 记录集(可能为空) """ if not link or isinstance(link, int): return self.env['hr.employee'] workflow_id = link.node_button_id.workflow_id node = workflow_id.node_ids.search([ ('name', '=', link.name), ('workflow_id', '=', workflow_id.id) ]) if node.button_ids[0].name != '转交': button = node.button_ids[-1] if node.button_ids else False else: button = node.button_ids[0] if node.button_ids else False if not button: return self.env['hr.employee'] link_users_id = button.users_role_id link_users_group_ids = button.users_role_group_ids is_automatic = button.is_automatic is_automatic_company = button.is_automatic_company is_automatic_group = button.is_automatic_group is_logged_by = button.is_logged_by is_logged_company = button.is_logged_company is_logged_group = button.is_logged_group is_dep = button.is_dep if button.reviewer_id: employee = self.env['hr.employee'].search([ ('user_id', '=', button.reviewer_id.id), ], limit=1) return employee # 部门和公司筛选条件 department_domain = [] company_domain = [] user_role_domain = [] if record_id: # 获取当前用户和申请人的相关信息 current_user = self.env.user applicant = None # 尝试获取申请人的用户对象 for field_name in ['user_id', 'users_id']: if hasattr(record_id, field_name): applicant = getattr(record_id, field_name) if applicant: break # 根据勾选的条件设置域条件(只勾选一个) if is_automatic and record_id.department_id: # 按当前申请人自动匹配-本部门(保留部门和公司条件) department_domain = ['|', ('department_id', '=', record_id.department_id.id), ('department_ids', 'in', record_id.department_id.id)] company_domain = [('company_id', '=', record_id.company_id.id)] if hasattr(record_id, 'company_id') else [] elif is_automatic_company and applicant and hasattr(applicant, 'company_id'): # 按当前申请人自动匹配-本公司(仅保留公司条件) company_id = applicant.company_id.id company_domain = [('company_id', '=', company_id)] elif is_automatic_group and applicant and hasattr(applicant, 'company_id'): # 按当前申请人自动匹配-本集团(仅保留公司条件) parent_company = applicant.company_id.parent_id if parent_company: group_company_ids = self.env['res.company'].search([('id', 'child_of', parent_company.id)]).ids company_domain = [('company_id', 'in', group_company_ids)] elif is_dep and hasattr(record_id, 'department_id1') and record_id.department_id1: department_id1 = record_id.department_id1.id department_domain = ['|', ('department_id', '=', department_id1), ('department_ids', 'in', department_id1)] user_role_domain = ['|', ('user_role_id', '=', button.role_id.user_role_ids.ids), ('user_role_ids', 'in', button.role_id.user_role_ids.ids)] elif is_logged_by and current_user.department_id: # 按当前登录人自动匹配-本部门(保留部门和公司条件) department_domain = ['|', ('department_id', '=', current_user.department_id.id), ('department_ids', 'in', current_user.department_id.id)] company_domain = [('company_id', '=', current_user.company_id.id)] elif is_logged_company: # 按当前登录人自动匹配-本公司(仅保留公司条件) company_id = current_user.company_id.id company_domain = [('company_id', '=', company_id)] elif is_logged_group: # 按当前登录人自动匹配-本集团(仅保留公司条件) parent_company = current_user.company_id.parent_id if parent_company: group_company_ids = self.env['res.company'].search([('id', 'child_of', parent_company.id)]).ids company_domain = [('company_id', 'in', group_company_ids)] if link_users_id: role_domain = ['|', ('user_role_id', '=', link_users_id.id), ('user_role_ids', 'in', link_users_id.id)] if user_role_domain: role_domain = ['|'] + role_domain + user_role_domain domain = role_domain + company_domain + department_domain return self.env['hr.employee'].sudo().search(domain) elif link_users_group_ids: role_domain = ['|', ('user_role_id', 'in', link_users_group_ids.user_role_ids.ids), ('user_role_ids', 'in', link_users_group_ids.user_role_ids.ids)] if user_role_domain: role_domain = ['|'] + role_domain + user_role_domain domain = role_domain + company_domain + department_domain return self.env['hr.employee'].sudo().search(domain) # 特殊分发按钮 if '分发' in link.name and record_id and hasattr(record_id, 'users_id'): return record_id.users_id.employee_id return self.env['hr.employee'] # 默认返回空记录集 def add_comment(self): self.ensure_one() cx = self.env.context.copy() or {} record_id = self.env[self.res_model].search([('id', '=', self.res_id)]) is_admin = self.env.user.has_group('soong_workflow.group_soong_workflow_manager') if self.node_btn_name == '转交': self_node_id = record_id.workflow_id.node_ids.search( [('name', '=', record_id.state), ('workflow_id', '=', record_id.workflow_id.id)]) log = self.env['soong.workflow.log'].search([("model", "=", self.res_model), ("res_id", "=", self.res_id)]) query_user_id = self.env.user.id if is_admin and record_id: if hasattr(record_id, 'user_id') and record_id.user_id: query_user_id = record_id.user_id.id elif hasattr(record_id, 'users_id') and record_id.users_id: query_user_id = record_id.users_id.id # 查询审批记录(使用确定的用户ID) if len(log) > 1 and is_admin: current_node_log = self.sudo().env["soong.workflow.log"].search( [("model", "=", self.res_model), ("res_id", "=", self.res_id), ("node_id", "=", self.node_btn_id.node_id.id)]) else: current_node_log = self.sudo().env["soong.workflow.log"].search( [("model", "=", self.res_model), ("res_id", "=", self.res_id), ("done_by", "=", query_user_id), ("node_id", "=", self.node_btn_id.node_id.id)]) # 创建或更新当前用户的审批记录 if not current_node_log: self.sudo().env["soong.workflow.log"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "node_id": self.node_btn_id.node_id.id, "workflow_id": self.node_btn_id.workflow_id.id, "done_by": query_user_id, "node_btn_name": "0", "node_btn_id": self.node_btn_id.id, "lase_click_date": fields.Datetime.now(), "approval_state": "2", # 已完成 "document_ids": self.document_ids, "comment": self.comment, }) else: current_node_log.write({ "comment": self.comment, "approval_state": "2", # 已完成 "lase_click_date": fields.Datetime.now() }) # 检查是否为并审模式 if self.approval_concatenation == 'bing': # 并审模式 # 获取当前节点应该审批的所有员工 expected_employees = self.employee_ids # 查找下一个节点 next_node_id = record_id.workflow_id.node_ids.search([ ('name', '=', self.trans_link_id.name), ('workflow_id', '=', record_id.workflow_id.id) ]) completed_logs = self.sudo().env["soong.workflow.log"].search([ ("model", "=", self.res_model), ("res_id", "=", self.res_id), ("node_id", "=", self.node_btn_id.node_id.id), ("node_btn_name", "=", "4"), ("approval_state", "!=", "2") ]) all_completed = len(completed_logs) == 0 if all_completed: for employee in expected_employees: # 检查该员工在下一节点是否已有记录 next_node_employee_log = self.sudo().env["soong.workflow.log"].search([ ("model", "=", self.res_model), ("res_id", "=", self.res_id), ("node_id", "=", next_node_id.id), ('node_btn_name', '!=', '1'), ("done_by", "=", employee.user_id.id) ]) if not next_node_employee_log: # 创建初步记录,状态为"待审批" self.sudo().env["soong.workflow.log"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "node_id": next_node_id.id, "workflow_id": self.node_btn_id.workflow_id.id, "done_by": employee.user_id.id, "node_btn_name": "4", "approval_state": "0", # 待审批 }) workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)]) if self.employee_ids: workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.employee_ids if employee.user_id] workflow_record_id.employee_ids = self.employee_ids workflow_record_id.approve_state = "pending" # 待审批 related_record = self.env[self.res_model].browse(self.res_id) if hasattr(related_record, 'self_users_ids'): user_ids = [employee.user_id.id for employee in self.employee_ids if employee.user_id] related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)] record_id.write({'state': self.trans_link_id.name}) for employee in self.employee_ids: action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0] url = f'https://oa.thtzjt.com/web?login={employee.user_id.login}&oauth_uid={employee.wecom_userid}#id={record_id.id}&cids=2&action={action_id.id}&model={record_id._name}&view_type=form&menu_id=10104' self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description, description="标题: {}\n".format( record_id.name) + self.env.user.name + ' ' + str( fields.Datetime.now() + timedelta( hours=8)), url=url, btntxt="查看详情") else: # 串审模式 (沿用原有逻辑) # 查找下一个节点 next_node_id = record_id.workflow_id.node_ids.search([ ('name', 'ilike', self.trans_link_id.name), ('workflow_id', '=', record_id.workflow_id.id) ]) # 创建下一节点的审批记录 self.sudo().env["soong.workflow.log"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "node_id": next_node_id.id, "workflow_id": self.node_btn_id.workflow_id.id, "done_by": self.employee_ids.user_id.id if self.employee_ids else query_user_id, "node_btn_name": "0", "lase_click_date": fields.Datetime.now(), "approval_state": "1", # 待审批 }) # 更新业务记录状态 related_record = self.env[self.res_model].browse(self.res_id) if hasattr(related_record, 'self_users_ids'): user_ids = [employee.user_id.id for employee in self.employee_ids if employee.user_id] related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)] record_id.write({'state': self.trans_link_id.name}) if self.node_btn_name == '结束': # 抄送传阅日志 if self_node_id.is_carbon_copy: for employee in self_node_id.employee_ids: if not employee.wecom_userid: raise ("请同步{}的企业微信".format(employee.name)) record_id = self.env[self.res_model].search([('id', '=', self.res_id)]) self.sudo().env["soong.workflow.record.copy"].create({ "code": record_id.code, "name": record_id.name, "res_model": self.res_model, "workflow_id": self.node_btn_id.workflow_id.id, "res_id": self.res_id, "done_by": employee.user_id.id, "approval_state_copy": "0", }) self.sudo().env["soong.workflow.log2"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "node_id": self.node_btn_id.node_id.id, "workflow_id": self.node_btn_id.workflow_id.id, "done_by": employee.user_id.id, "node_btn_id": self.node_btn_id.id, "approval_state": "0", }) url = f'https://oa.thtzjt.com/web#id={self.id}&cids=2&action={record_id.action.id}&model={self.res_model}&view_type=from&menu_id={record_id.id}' description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str( fields.Datetime.now() + timedelta(hours=8)) self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description + "传阅/抄送", description=description, url=url, btntxt="查看详情") self.env['soong.workflow.record'].search([('code', '=', record_id.code)]).write({'approve_state': 'pending'}) return self.node_btn_id.with_context(cx).run() if self.node_btn_name == '退回': record_id.write({'state': self.return_link_id.name}) next_node_id = record_id.workflow_id.node_ids.search([('name', '=', self.return_link_id.name), ('workflow_id', '=', record_id.workflow_id.id)]) for next_link in record_id.workflow_id.link_ids: if next_link.name.split('-> ')[0].strip() == self.return_link_id.name.strip(): next_node_id = next_link.node_from record_id.log_ids[-1].write({'approval_state': '2', "lase_click_date": fields.Datetime.now(), "comment": self.comment, "node_btn_name": "1"}) # if not self.sudo().env["soong.workflow.log"].search([('node_id', '=', next_node_id.id)]): self.sudo().env["soong.workflow.log"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "node_id": next_node_id.id, "workflow_id": self.node_btn_id.workflow_id.id, "done_by": self.employee_ids[0].user_id.id, "approval_state": "0", "node_btn_id": self.node_btn_id.id, }) workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)]) workflow_record_id.employee_ids = self.employee_ids related_record = self.env[self.res_model].browse(self.res_id) if hasattr(related_record, 'self_users_ids'): user_ids = [employee.user_id.id for employee in self.employee_ids if employee.user_id] related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)] return self.node_btn_id.with_context(cx).run() if self.node_btn_name == '结束': # 获取当前登录用户 current_user = self.env.user # 获取当前时间 current_datetime = fields.Datetime.now() log_records = None if record_id.log_ids2: log_records = record_id.log_ids2 elif record_id.log_ids: log_records = record_id.log_ids if log_records: # 查找当前用户的日志记录 user_log = log_records.filtered(lambda log: log.done_by == current_user) if user_log: user_log.write({ 'comment': self.comment, 'approval_state': "3", 'lase_click_date': current_datetime }) record_id.work_end = True self.env['soong.workflow.record'].search([ ('code', '=', record_id.code) ]).write({ 'approve_state': 'end', 'employee_ids': False, 'node_id': False, }) # 给申请人发消息 biz_record = self.env[self.res_model].browse(self.res_id) if hasattr(biz_record, 'user_id') and biz_record.user_id: employee = biz_record.user_id.employee_id elif hasattr(biz_record, 'users_id') and biz_record.users_id: employee = biz_record.users_id.employee_id action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0] url = f'https://oa.thtzjt.com/web?login={employee.user_id.login}&oauth_uid={employee.wecom_userid}#id={record_id.id}&cids=2&action={action_id.id}&model={record_id._name}&view_type=form&menu_id=10104' self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description, description=f"编号为{record_id.code}的{record_id._description}已结束", url=url, btntxt="查看详情") recipients = [] if self.node_btn_id.workflow_id.archive_type == 'applicant': biz_record = self.env[self.res_model].browse(self.res_id) if hasattr(biz_record, 'user_id') and biz_record.user_id: employee = biz_record.user_id.employee_id elif hasattr(biz_record, 'users_id') and biz_record.users_id: employee = biz_record.users_id.employee_id recipients.append(employee) elif self.node_btn_id.workflow_id.archive_type == 'role': role_ids = self.node_btn_id.workflow_id.role_ids employees = self.env['hr.employee'].search([ '|', ('user_role_id', 'in', role_ids.ids), ('user_role_ids', 'in', role_ids.ids) ]) recipients = [emp for emp in employees] else: employees = self.node_btn_id.workflow_id.employee_ids recipients = [emp for emp in employees] for employee in recipients: url = f'https://oa.thtzjt.com/web?login={employee.user_id.login}&oauth_uid={employee.wecom_userid}#id={record_id.id}&cids=2&action={action_id.id}&model={record_id._name}&view_type=form&menu_id=10104' self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description, description=f"编号为{record_id.code}的{record_id._description}已结束,请归档", url=url, btntxt="查看详情") if self.node_btn_name == "分发": if self.employee_ids: record_id.log_ids[-1].write({"comment": self.comment, "approval_state": "2", "lase_click_date": fields.Datetime.now()}) self.sudo().env["soong.workflow.log"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "node_id": record_id.workflow_id.node_ids[-1].id, "workflow_id": self.node_btn_id.workflow_id.id, "done_by": self.employee_ids.user_id.id, "node_btn_name": "0", }) if self.circulated_employee_ids: for employee in self.circulated_employee_ids: if not employee.wecom_userid: raise ("请同步{}的企业微信".format(employee.name)) record_id = self.env[self.res_model].search([('id', '=', self.res_id)]) self.sudo().env["soong.workflow.record.copy"].create({ "code": record_id.code, "name": record_id.name, "res_model": self.res_model, "workflow_id": self.node_btn_id.workflow_id.id, "res_id": self.res_id, "done_by": employee.user_id.id, "approval_state_copy": "0", }) self.sudo().env["soong.workflow.log2"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "node_id": self.node_btn_id.node_id.id, "workflow_id": self.node_btn_id.workflow_id.id, "done_by": employee.user_id.id, "node_btn_id": self.node_btn_id.id, "approval_state": "0", }) url = f'https://oa.thtzjt.com/web#id={self.id}&cids=2&action={record_id.action.id}&model={self.res_model}&view_type=from&menu_id={record_id.id}' description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str( fields.Datetime.now() + timedelta(hours=8)) self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description + "传阅/抄送", description=description, url=url, btntxt="查看详情") if self.node_btn_name == "收回": log_ids = record_id.log_ids.sorted('sequence') if log_ids[-1].approval_state == '2': raise UserError('当前状态不可以收回') self.env['soong.workflow.record'].search([('code', '=', record_id.code)]).write({"employee_ids": self.env.user.employee_id.id,}) related_record = self.env[self.res_model].browse(self.res_id) if hasattr(related_record, 'self_users_ids'): related_record.self_users_ids = [(6, 0, [self.env.user.id])] log_ids[-1].unlink() log_ids[-2].write({'approval_state': '1'}) record_id.write({'state': log_ids[-2].name}) return self.node_btn_id.with_context(cx).run() def update_self_users_ids(self): related_record = self.env[self.res_model].browse(self.res_id) if hasattr(related_record, 'self_users_ids'): user_ids = [employee.user_id.id for employee in self.employee_ids if employee.user_id] related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)]