Merge pull request !3265 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2025-06-12 13:08:48 +00:00
committed by Gitee
3 changed files with 179 additions and 86 deletions
+45 -13
View File
@@ -296,20 +296,21 @@ class SoongWorkflowMixin(models.AbstractModel):
node_name_list = [node_name.name for node_name in node_list]
index = self_state
# 部门转入范围和条件判断才会创建
for node in node_name_list[index + 1:]:
self.env['trans.link'].create({
'node_button_id': btn_rec.id,
'name': node,
'link_type': 'trans',
'record_id': self.id,
})
# 存储实际会执行的节点路径
actual_path_nodes = []
# 第一步:跟踪整个工作流路径,只保留实际会执行的节点
while index < len(node_list):
current_node = node_list[index]
actual_path_nodes.append(current_node)
if not current_node.out_link_ids:
index = 20 # 防止死循环
break
# 获取当前节点的部门
current_department = self.department_id
# 处理多个输出链接的情况
if len(current_node.out_link_ids) > 1:
# 筛选与当前节点部门匹配的后续节点
@@ -318,19 +319,25 @@ class SoongWorkflowMixin(models.AbstractModel):
target_node = link.node_to
# 如果目标节点有部门限制,且与当前节点部门匹配
if target_node.department_id and (target_node.department_id == current_department or
current_department in self.get_all_sub_departments(target_node.department_id)):
current_department in self.get_all_sub_departments(
target_node.department_id)):
valid_nodes.append((target_node, link))
# 尝试父部门匹配
if not valid_nodes and current_department and current_department.parent_id:
parent_department = current_department.parent_id
for link in current_node.out_link_ids:
target_node = link.node_to
if target_node.department_id and (target_node.department_id == parent_department or
parent_department in self.get_all_sub_departments(target_node.department_id)):
parent_department in self.get_all_sub_departments(
target_node.department_id)):
valid_nodes.append((target_node, link))
# 如果没有找到匹配的节点,抛出错误
if not valid_nodes:
current_dept_name = current_department.name if current_department else "未指定部门"
raise ValidationError(f"没有找到符合当前部门( {current_dept_name} )的后续节点!")
# 选择第一个匹配的节点
next_node, matched_link = valid_nodes[0]
matched_key = next_node.name
@@ -339,9 +346,31 @@ class SoongWorkflowMixin(models.AbstractModel):
matched_link = current_node.out_link_ids[0]
next_node = matched_link.node_to
matched_key = next_node.name
# 更新索引并跳出循环
# 更新索引
index = state_list.index(matched_key)
break
if index >= len(node_list):
break
# 第二步:根据实际路径创建trans.link记录并生成domain
actual_path_links = []
for node in actual_path_nodes[1:]: # 跳过当前节点
link = self.env['trans.link'].create({
'node_button_id': btn_rec.id,
'name': node.name,
'link_type': 'trans',
'record_id': self.id,
})
actual_path_links.append(link)
# 第三步:创建domain条件
if actual_path_links:
# 获取所有创建的trans.link的ID
trans_link_ids = [link.id for link in actual_path_links]
# 创建domain条件
trans_domain = [('id', 'in', trans_link_ids)]
else:
trans_domain = [] # 如果没有路径节点,返回空domain
is_supervising = False
if self._module in ['yuthon_official']:
@@ -362,8 +391,11 @@ class SoongWorkflowMixin(models.AbstractModel):
"default_log_ids": logs.ids,
"default_node_btn_id": btn_rec.id,
"default_is_supervising": is_supervising,
"default_trans_link_id": self.env['trans.link'].search([])[0].id if btn_rec.name == '转交' else False,
"default_return_link_id": self.env['trans.link'].search([])[0].id if btn_rec.name == '退回' else False,
"default_trans_link_id": self.env['trans.link'].search(trans_domain, limit=1).id if btn_rec.name == '转交' else False,
"all_workflow_links": trans_link_ids,
"default_return_link_id": self.env['trans.link'].search(
[('link_type', '=', 'return'), ('record_id', '=', self.id)],
limit=1).id if btn_rec.name == '退回' else False,
},
}
@@ -31,6 +31,12 @@ class SoongWorkflowCommentWizard(models.TransientModel):
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)
@@ -119,86 +125,140 @@ class SoongWorkflowCommentWizard(models.TransientModel):
])
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):
self.employee_ids1 = False
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
for ret in self.trans_link_id:
workflow_id = self.trans_link_id.node_button_id.workflow_id
node = workflow_id.node_ids.search([('name', '=', self.trans_link_id.name), ('workflow_id', '=', workflow_id.id)])
button = node.button_ids[0] if node.button_ids else False
if not button:
for record in self:
if not record.trans_link_id:
continue
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
employee_user_role_ids = False
# 构建部门筛选条件
department_domain = []
# 按当前申请人自动匹配
if is_automatic: # 申请人-本部门
department_domain = ['|', ('department_id', '=', record_id.department_id.id), ('department_ids', 'in', record_id.department_id.id)]
elif is_automatic_company or is_automatic_group: # 申请人-本公司/本集团
# 查找user_id或users_id字段
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 = 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
# 部门筛选条件
department_domain = []
if record_id:
# 申请人自动匹配逻辑
if is_automatic:
department_domain = ['|',
('department_id', '=', record_id.department_id.id),
('department_ids', 'in', record_id.department_id.id)]
elif is_automatic_company or is_automatic_group:
applicant_field = None
for field_name, field_data in record_id._fields.items():
if field_name in ['user_id', 'users_id']:
field_value = getattr(record_id, field_name)
if field_value:
applicant_field = field_value
for field_name in ['user_id', 'users_id']:
if hasattr(record_id, field_name):
applicant_field = getattr(record_id, field_name)
if applicant_field:
break
# 如果找到申请人字段,则处理公司/集团逻辑
if applicant_field and hasattr(applicant_field, 'company_id'):
if is_automatic_company: # 申请人-本公司
company_departments = self.env['hr.department'].search(
[('company_id', '=', applicant_field.company_id.id)]).ids
department_domain = [('department_id', 'in', company_departments)]
elif is_automatic_group: # 申请人-本集团
if is_automatic_company:
company_departments = self.env['hr.department'].search([
('company_id', '=', applicant_field.company_id.id)
]).ids
department_domain = ['|',
('department_id', 'in', company_departments),
('department_ids', 'in', company_departments)]
elif is_automatic_group:
parent_company = applicant_field.company_id.parent_id
group_departments = self.env['hr.department'].search(
[('company_id', 'child_of', parent_company.id)]).ids if parent_company else []
department_domain = [('department_id', 'in', group_departments)]
else:
department_domain = []
# 按当前登录人自动匹配
elif is_logged_by: # 登录人-本部门
department_domain = [('department_id', '=', self.env.user.department_id.id)]
elif is_logged_company: # 登录人-本公司
company_departments = self.env['hr.department'].search(
[('company_id', '=', self.env.user.company_id.id)]).ids
department_domain = [('department_id', 'in', company_departments)]
elif is_logged_group: # 登录人-本集团
group_departments = self.env['hr.department'].search([
('company_id', 'child_of', parent_company.id)
]).ids if parent_company else []
department_domain = ['|',
('department_id', 'in', group_departments),
('department_ids', 'in', group_departments)]
# 登录人自动匹配逻辑
elif is_logged_by:
department_domain = ['|',
('department_id', '=', self.env.user.department_id.id),
('department_ids', 'in', self.env.user.department_id.id)]
elif is_logged_company:
company_departments = self.env['hr.department'].search([
('company_id', '=', self.env.user.company_id.id)
]).ids
department_domain = ['|',
('department_id', 'in', company_departments),
('department_ids', 'in', company_departments)]
elif is_logged_group:
parent_company = self.env.user.company_id.parent_id
group_departments = self.env['hr.department'].search(
[('company_id', 'child_of', parent_company.id)]).ids if parent_company else []
department_domain = [('department_id', 'in', group_departments)]
# 处理角色筛选条件
if link_users_id:
role_domain = ['|', ('user_role_id', '=', link_users_id.id), ('user_role_ids', 'in', link_users_id.id)]
company_domain = [('company_id', '=', self.env.user.company_id.id)]
# 自动匹配:结合角色和部门筛选
domain = role_domain + company_domain + department_domain
employee_user_role_ids = 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)]
company_domain = [('company_id', '=', self.env.user.company_id.id)]
# 自动匹配
domain = role_domain + company_domain + department_domain
employee_user_role_ids = self.env['hr.employee'].sudo().search(domain)
# 设置结果
self.approval_concatenation = node.approval_concatenation
self.employee_trans_domain_ids = employee_user_role_ids
self.employee_ids1 = employee_user_role_ids
# 特殊处理:分发按钮
if '分发' in ret.name:
self.employee_ids1 = record_id.users_id.employee_id
group_departments = self.env['hr.department'].search([
('company_id', 'child_of', parent_company.id)
]).ids if parent_company else []
department_domain = ['|',
('department_id', 'in', group_departments),
('department_ids', 'in', group_departments)]
# 角色筛选
if link_users_id:
role_domain = ['|',
('user_role_id', '=', link_users_id.id),
('user_role_ids', 'in', link_users_id.id)]
company_domain = [('company_id', '=', self.env.user.company_id.id)]
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)]
company_domain = [('company_id', '=', self.env.user.company_id.id)]
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()
@@ -10,6 +10,7 @@
<form string="意见">
<group invisible="1">
<field name="approval_concatenation" widget="radio"/>
<field name="invalid_link_ids" widget="many2many_tags"/>
<field name="comment"/>
</group>
<group invisible="node_btn_name in ['分发', '结束', '收回']">
@@ -49,7 +50,7 @@
<!-- 退回意见退回类型 -->
<field name="return_link_id" invisible="node_btn_name != '退回'" string="退回节点"/>
<!-- 转交人员 -->
<field name="trans_link_id" string="转交节点" invisible="node_btn_name == '退回'"/>
<field name="trans_link_id" string="转交节点" invisible="node_btn_name == '退回'" domain="[('id', 'not in', invalid_link_ids)]"/>
<field name="employee_trans_domain_ids" invisible="1"/>
<field name="employee_ids1" widget="many2many_tags" string="人员范围" invisible="1"/>
<field name="employee_ids" widget="many2many_tags" string="人员范围" domain="[('id', 'in', employee_ids1)]" options="{'no_create': True}"/>