# -*- coding: utf-8 -*- import logging import datetime from odoo import models, fields, api, _, modules from odoo.exceptions import ValidationError, UserError _logger = logging.getLogger(__name__) MODEL_DOMAIN = """[ ('is_workflow', '=', True), ('state', '=', 'base'), ('transient', '=', False), '!', '|', '|', '|', '|', '|', '|', '|', ('model', '=ilike', 'res.%'), ('model', '=ilike', 'ir.%'), ('model', '=ilike', 'soong.workflow%'), ('model', '=ilike', 'bus.%'), ('model', '=ilike', 'base.%'), ('model', '=ilike', 'base_%'), ('model', '=', 'base'), ('model', '=', '_unknown'), ]""" class SoongWorkflowEntrust(models.Model): _name = "soong.workflow.entrust" _description = "工作流委托" model_id = fields.Many2one("ir.model", string="名称", domain=MODEL_DOMAIN, default=lambda self: self.env['ir.model'].search([('model', '=', 'entrust.all')])) entrust_user_id = fields.Many2one('res.users', string='委托人') entrust_user_id2 = fields.Many2one('res.users', string='被委托人') is_expiration_date = fields.Boolean(string="一直有效", default=True) start_date = fields.Date(string="生效日期", copy=False, default=fields.Date.today()) end_date = fields.Date(string="失效日期", copy=False) is_enable = fields.Boolean(string="是否启用", default=True, compute="compute_is_enable", store=True) entrust_notice = fields.Boolean(string="发送事务提醒消息", default=True) workflow_data = fields.Char(string="委托流程记录方便到期删除") @api.constrains('is_enable', 'entrust_user_id', 'entrust_user_id2') def onchange_entrust(self): # 如果是全部流程 if self.is_enable: all_work_list = [] if self.env['ir.model'].search([('id', '=', self.model_id.id)]).name == '全部流程': all_work_ids = self.env['soong.workflow'].search([('is_enable', '=', True)]) else: all_work_ids = self.env['soong.workflow'].search([('is_enable', '=', True), ('model_id', '=', self.model_id.id)]) # 便利出所有的记录集,查出与本人相关的 for work_id in all_work_ids: state_dict = {} for state in work_id.node_ids: node_data_list = [] for node in state.button_ids: if node.name == '转交': if node.btn_hide: if node.review_type == 'user_role': node_data = {'users_role_id': node.users_role_id.id} elif node.review_type == 'individual': node_data = {'reviewer_id': node.reviewer_id.id, } else: node_data = [] node_data_list.append(node_data) state_dict[state.name + '-' + str(work_id.id)] = node_data_list all_work_list.append(state_dict) # 查找委托人当前关联的流程 reviewer_id = self.env['res.users'].search([('id', '=', self.entrust_user_id.id)]) users_role_id = reviewer_id.employee_id.user_role_id.id for work in all_work_list: # 判断角色是否在里面 users_role = [key for key, items in work.items() if any(item.get('users_role_id') == users_role_id for item in items)] for role in users_role: workflow = int(role.split('-')[-1]) work_code = role.split('-')[0] workflow_id = self.env['soong.workflow'].search([('id', '=', workflow)]) for flow in workflow_id.node_ids: if flow.name == work_code and flow.button_ids[-1].name != '转交': flow.write({ 'button_ids': [(0, 0, { "name": _("转交"), "workflow_id": workflow_id.id, "sequence": 999, "review_type": "individual", "btn_hide": True, "action_type": 'code', "reviewer_id": self.entrust_user_id2.id, "has_comment": True, })] }) if self.workflow_data: self.workflow_data = self.workflow_data + work_code + '-' + str(workflow_id.id) + ',' else: self.workflow_data = work_code + '-' + str(workflow_id.id) + ',' else: for de in self: work_ids_list = de.workflow_data.split(',')[0:-1] for work in work_ids_list: workflow_id = self.env['soong.workflow'].search([('id', '=', int(work.split('-')[-1]))]) for flow in workflow_id.node_ids: if flow.name == work.split('-')[0] and flow.button_ids[-1].name == '转交': flow.button_ids[-1].unlink() self.workflow_data = '' @api.depends('start_date', 'end_date', 'is_expiration_date') def compute_is_enable(self): for rec in self: if rec.is_expiration_date: rec.is_enable = True else: if rec.start_date and rec.end_date: if rec.start_date <= fields.Date.today() < rec.end_date: rec.is_enable = True else: rec.is_enable = False class EntrustAll(models.Model): _name = "entrust.all" _inherit = 'soong.workflow.mixin' _description = "全部流程" name = fields.Char(string='name')