# -*- 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'] _transient_max_count = 0 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="常用意见") comment_note = fields.Text(string="意见") comment = fields.Char(compute='_compute_comment', store=True) state_list = fields.Char(string="状态列表") record_id = fields.Integer() is_selection = fields.Boolean(string="是否自动选择") trans_link_id = fields.Many2one('trans.link', string='转交节点', ondelete='set null') document_ids = fields.Many2many('ir.attachment', string="附件") return_link_id = fields.Many2one('trans.link', string='退回节点', ondelete='set null') 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', help='只可以看不可以评论,看过以后状态自动变为已阅', string="抄送/传阅人员", store=True) dep_manager_employee_ids = fields.Many2many('hr.employee', 'dep_manager_employee_rel', 'custom_id', 'employee_id', string="承办", store=True) add_employee_ids = fields.Many2many('hr.employee', 'add_employee_rel', 'custom_id', 'employee_id', string="加签人员", help='点击确认以后评论的人员', 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('是否自动匹配') company_id = fields.Many2one('res.company', '公司', default=lambda self: self.env.user.company_id) is_this_company = fields.Boolean('本公司', default=True) employee_ids1 = fields.Many2many('hr.employee', 'employee_ids1_rel', 'custom_id1', 'employee_id1', string="转交人员", store=True) @api.onchange('is_selection') def _onchange_is_selection(self): domain = [('id', 'in', self.employee_ids1.ids)] if self.is_selection: if self.is_this_company: domain.append(('company_id', '=', self.company_id.id)) all_employees = self.env['hr.employee'].search(domain) self.employee_ids = all_employees else: self.employee_ids = False @api.onchange('employee_ids1') def _onchange_employee_ids1(self): filtered_employees = self.employee_ids1.filtered( lambda emp: emp.company_id.id == self.company_id.id ) if len(filtered_employees) == 1: self.employee_ids = filtered_employees else: self.employee_ids = False @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 ['拟办', '申请人']: if hasattr(record_id, 'user_id') and record_id.user_id: employee_ids1 = record_id.user_id.employee_ids elif hasattr(record_id, 'users_id') and record_id.users_id: employee_ids1 = record_id.users_id.employee_ids self.employee_ids1 = employee_ids1 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] if ret.name == '询价': name = 'draft' else: name = ret.name self_state = state_list.index(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 current_link = record.trans_link_id if current_link and all_links: sorted_all_links = all_links.sorted('sequence') for idx, link in enumerate(sorted_all_links): if link.id == current_link.id and link.sequence == current_link.sequence: approvers = self._get_approvers_for_link(link, record_id) # if not approvers: # invalid_links |= link log_records = record_id.log_ids approved_users = log_records.filtered(lambda log: log.node_btn_name != '1' and log.done_by).mapped('done_by.employee_ids') approved_employee_ids = approved_users.ids employee_ids = approvers.ids if len(approvers) > 1: is_all_included = all(emp_id in approved_employee_ids for emp_id in employee_ids) if is_all_included: if idx + 1 < len(sorted_all_links): self.trans_link_id = sorted_all_links[idx + 1] invalid_links |= current_link break 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) ]) button_priority_list = ["分发", "下发", "转交", "结束"] button = False if node.button_ids: for btn_name in button_priority_list: target_btn = next((btn for btn in node.button_ids if btn.name == btn_name), None) if target_btn: button = target_btn break 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 is_field = button.specify_field_id 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', '=', applicant.company_id.id)] 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)] elif is_field: field_name = button.specify_field_id.name field_value = record_id[field_name] if field_value: if button.specify_field_id.relation == 'res.users': employee = self.env['hr.employee'].sudo().search( [('user_id', '=', field_value.id)], limit=1 ) if employee: return employee else: department_domain = ['|', ('department_id', '=', field_value.id), ('department_ids', 'in', field_value.id)] 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') log_done_by_ids = [log.done_by.id for log in record_id.log_ids if log.done_by] if self.node_btn_name == '转交': has_comment_note = bool(self.comment_note_id) has_comment = bool(self.comment and self.comment.strip()) if not has_comment_note and not has_comment: raise UserError('请填写备注') 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", # 已完成 "comment": self.comment, }) else: current_node_log.write({ "comment": self.comment, "approval_state": "2", # 已完成 'document_ids': [(6, 0, self.document_ids.ids)], "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 next_node_log_records = self.env["soong.workflow.log"] 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: # 创建初步记录,状态为"待审批" 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", # 待审批 }) next_node_log_records += next_node_employee_log 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}) if self.circulated_employee_ids: workflow_record_id.is_log2 = True workflow_record_id.employee2_ids = [(6, 0, self.circulated_employee_ids.ids)] 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#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form' result_data = 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="查看详情") # msg_id = result_data[-1]['msgid'] # target_logs = next_node_log_records.filtered(lambda l: l.done_by.id == employee.user_id.id) # if target_logs: # target_logs.msg_id = msg_id 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}) for employee in self.circulated_employee_ids: 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", }) if employee.user_id.id not in log_done_by_ids: self.sudo().env["soong.workflow.log2"].create({ "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", }) action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0] url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&action={action_id.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 == '退回': 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"}) 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) user_ids = [employee.user_id.id for employee in self.employee_ids if employee.user_id] if hasattr(related_record, 'self_users_ids'): related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)] workflow_record_id.users_ids = [(6, 0, user_ids)] if self.node_btn_name in ['结束', '确认']: current_user = self.env.user current_datetime = fields.Datetime.now() is_admin = current_user.has_group('soong_workflow.group_soong_workflow_manager') if is_admin: record_id.log_ids[-1].sudo().write({ 'comment': self.comment, 'approval_state': "2", 'lase_click_date': fields.Datetime.now() - timedelta(hours=8), 'document_ids': [(6, 0, self.document_ids.ids)] }) self.env['soong.workflow.record'].search([('code', '=', record_id.code)]).write({'approve_state': 'end', "employee_ids": False, "node_id": False, }) record_id.work_end = True if record_id.log_ids: user_log = record_id.log_ids.filtered(lambda log: log.done_by == current_user) if user_log: user_log.write({ 'comment': self.comment, 'approval_state': "2", 'lase_click_date': current_datetime, 'document_ids': [(6, 0, self.document_ids.ids)] }) if record_id.log_ids2 and self.node_btn_name == '确认': user_log2 = record_id.log_ids2.filtered(lambda log: log.done_by == current_user) if user_log2: user_log2.write({ 'commit': self.comment, 'approval_state': "2", 'lase_click_date': current_datetime, }) for employee in self.circulated_employee_ids: action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0] url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&action={action_id.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)) workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)]) workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id] workflow_record_id.employee_ids = [(4, employee.id)] 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", }) if employee.user_id.id not in log_done_by_ids: self.sudo().env["soong.workflow.log2"].create({ "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", }) # 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 not record_id.log_ids2.search([('approval_state', '=', '0')]) or record_id.log_ids2: last_log = record_id.log_ids[-1] if record_id.log_ids else None if last_log: 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 same_name_logs = record_id.log_ids.filtered( lambda log: log.name == last_log.name and log.node_btn_name == '4' and log.id != last_log.id ) all_approved = all(log.approval_state == '3' for log in same_name_logs) all_approved = all_approved and (last_log.approval_state == '3') log2_ids_all_qualified = True if record_id.log_ids2: log2_ids_all_qualified = all(log2.approval_state == '2' for log2 in record_id.log_ids2) if all_approved and log2_ids_all_qualified: workflow_record = self.env['soong.workflow.record'].search([('code', '=', record_id.code)], limit=1) if workflow_record: workflow_record.write({ 'approve_state': 'end', 'employee_ids': applicant.id, 'soong_state': 'to_active', 'node_id': False, }) self.sudo().env["soong.workflow.log"].create({ "code": self.code, "model": self.res_model, "res_id": self.res_id, "workflow_id": self.node_btn_id.workflow_id.id, "lase_click_date": fields.Datetime.now(), "done_by": applicant.id, "approval_state": "0", "commit":'待归档', "node_btn_id": self.node_btn_id.id, }) record_id.work_end = True # 给申请人发消息 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_ids elif hasattr(biz_record, 'users_id') and biz_record.users_id: employee = biz_record.users_id.employee_ids action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0] 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_ids elif hasattr(biz_record, 'users_id') and biz_record.users_id: employee = biz_record.users_id.employee_ids 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#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form' if self.res_model == 'purchase.order': self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title='采购审批单', description=f"{record_id.name}审批结束,可采购入库", url=url, btntxt="查看详情") else: 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="查看详情") self.node_btn_id.with_context(cx).run() if self.node_btn_name == "分发": record_id.is_send = True menu_id = self.env['ir.ui.menu'].search([('name', '=', '行政收文')]) workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)]) action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0] url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={menu_id.id}&active_id={action_id.id}&model=yuthon.official.incoming.normal&view_type=form' description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8)) if self.employee_ids: workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.employee_ids if employee.user_id] next_node_id = record_id.workflow_id.node_ids.search([('name', '=', '董事长'), ('workflow_id', '=', record_id.workflow_id.id)]) record_id.log_ids[-1].write({"comment": self.comment, "approval_state": "2", "lase_click_date": fields.Datetime.now()}) log_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, "node_btn_name": "0", }) result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id='18562027762', title=record_id._description, description=description, url=url, btntxt="查看详情") # msg_id = result_data[-1]['msgid'] # log_id.msg_id = msg_id for emp in self.dep_manager_employee_ids: workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.dep_manager_employee_ids if employee.user_id] next_node_id = record_id.workflow_id.node_ids.search([('name', '=', '承办'), ('workflow_id', '=', record_id.workflow_id.id)]) log_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": emp.user_id.id, "node_btn_name": "4", }) result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=emp.wecom_userid, title=record_id._description + "承办", description=description, url=url, btntxt="查看详情") # msg_id = result_data[-1]['msgid'] # log_id.msg_id = msg_id for employee in self.circulated_employee_ids: workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id] 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", }) if employee.user_id.id not in log_done_by_ids: log2_id = self.sudo().env["soong.workflow.log2"].create({ "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", }) result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id='18562027762', title=record_id._description + "传阅/抄送",description=description, url=url, btntxt="查看详情") # msg_id = result_data[-1]['msgid'] # log2_id.msg_id = msg_id workflow_record_id.employee_ids = self.dep_manager_employee_ids + self.employee_ids + self.circulated_employee_ids record_id.log_ids[-1].write({"comment": self.comment, "approval_state": "2", "lase_click_date": fields.Datetime.now()}) if self.node_btn_name == "收回": # recall_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/recall?access_token={access_token}' record = self.env[self.res_model].search([('id', '=', self.res_id)]) log_ids = record.log_ids.sorted('sequence') if self.env.user.name not in ['Administrator', '叶华锋']: if log_ids[-1].approval_state in ['1', '2']: raise UserError('当前状态不可以收回') 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, [log_ids[-2].done_by.id])] self.env['soong.workflow.record'].search([('code', '=', record.code)]).write( {"employee_ids": [(6, 0, [log_ids[-2].done_by.employee_ids.id])], "users_ids": [(6, 0, [log_ids[-2].done_by.id])], 'soong_state': 'to_do' }) log_ids[-1].unlink() log_ids[-2].write({'approval_state': '1'}) if log_ids[-2].name == '询价': record.write({'state': 'draft', 'work_end': False}) else: record.write({'state': log_ids[-2].name, 'work_end': False}) self.node_btn_id.with_context(cx).run() if self.node_btn_name == '归档': workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)]) workflow_record_id.write({'soong_state': 'active', 'employee_ids':False } ) if self.node_btn_name != "收回": tree_id = self.env.ref("soong_workflow.soong_workflow_record_my_tree").id self.red_reload() return { 'name': '流程待办', 'view_mode': 'tree', 'res_model': 'soong.workflow.record', 'type': 'ir.actions.act_window', 'views': [[tree_id, 'tree']], 'domain': [('users_ids', 'in', self.env.uid), ('reclaim_state', '=', False), ('soong_state', '=', 'to_do')], 'context': { 'header_search_default_approve_state': 1, 'header_search_default_to_do': 1, 'check_employee': 1 } } def red_reload(self): return { 'type': 'ir.actions.client', 'tag': 'flush_badge', } 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,)]