This commit is contained in:
pengyuthon
2026-01-13 11:26:00 +08:00
parent 8ff1fdfe3a
commit 672b8d5523
3 changed files with 162 additions and 172 deletions
+157 -163
View File
@@ -92,27 +92,16 @@ class SoongWorkflowMixin(models.AbstractModel):
current_state = record.state
if not current_state or not record.log_ids:
continue
# 判断当前节点的状态
matched_logs = record.log_ids.filtered(lambda log: log.name == current_state)
if matched_logs and all(log.approval_state == '0' for log in matched_logs):
record.is_back = True
if matched_logs:
if matched_logs[-1].approval_state != '0':
record.is_back = True
if record._name == 'yuthon.official.incoming.normal':
current_user_in_logs2 = any(
log.done_by.id == self.env.uid
for log in record.log_ids2
)
organizer_user_in_logs = any(
log.done_by.id == self.env.user.id
for log in record.log_ids.filtered(lambda l: l.name == '承办')
)
all_handling_logs_approval_0 = all(
log.approval_state == '0'
for log in record.log_ids.filtered(lambda l: l.name == '承办')
)
all_logs2_approval_0 = all(
log.approval_state == '0'
for log in record.log_ids2
)
current_user_in_logs2 = any(log.done_by.id == self.env.uid for log in record.log_ids2)
organizer_user_in_logs = any(log.done_by.id == self.env.user.id for log in record.log_ids.filtered(lambda l: l.name == '承办'))
all_handling_logs_approval_0 = all(log.approval_state == '0' for log in record.log_ids.filtered(lambda l: l.name == '承办'))
all_logs2_approval_0 = all(log.approval_state == '0' for log in record.log_ids2)
if all_logs2_approval_0 and all_handling_logs_approval_0 and not current_user_in_logs2 and not organizer_user_in_logs:
record.is_back = True
@@ -130,7 +119,7 @@ class SoongWorkflowMixin(models.AbstractModel):
def _compute_is_confirm(self):
for record in self:
record.is_confirm = True
record.is_end = True
record.is_end = False
domain = [('done_by', '=', self.env.user.id), ('workflow_id', '=', record.workflow_id.id),
('res_id', '=', record.id), ('approval_state', 'in', ['0', '1'])]
lg2 = record.log_ids2.search(domain)
@@ -138,7 +127,7 @@ class SoongWorkflowMixin(models.AbstractModel):
if lg2 or lg1:
record.is_confirm = False
if not lg1 and not lg2:
record.is_end = False
record.is_end = True
@api.depends("node_id", "log_ids")
def _compute_approval_sign_ids(self):
@@ -341,163 +330,168 @@ class SoongWorkflowMixin(models.AbstractModel):
wizard = self.env.ref("soong_workflow.view_soong_workflow_comment_wizard")
# 状态列表
node_list = btn_rec.workflow_id.node_ids.sorted('sequence')
state_list = [i.node_name for i in btn_rec.workflow_id.node_ids.sorted('sequence')]
if self.name_title != '采购申请单':
state_list = [i.node_name for i in btn_rec.workflow_id.node_ids.sorted('sequence')]
else:
state_list = [i.node_name for i in btn_rec.workflow_id.node_ids.sorted('sequence')] + ['purchase']
# 当前节点状态
self_state = state_list.index(self.state)
state = self.state
if self.state == 'draft':
state = '询价'
self_state = state_list.index(state)
# 当前节点
current_node = node_list[state_list.index(self.state)]
self.env['trans.link'].search([]).unlink()
# 退回节点根据日志进行判断
if btn_rec.name == '退回':
approved_logs = self.log_ids.filtered(lambda log: log.approval_state == '2')
for ret in approved_logs:
if not self.env['trans.link'].search([('name', '=', ret.name)]):
self.env['trans.link'].create({
'node_button_id': btn_rec.id,
'name': ret.name,
'link_type': 'return',
'record_id': self.id,
})
if btn_rec.name == '转交':
required_fields = [
field.name for field in current_node.field_ids
if field.required and field.name
]
missing_fields = []
if required_fields:
for field_name in required_fields:
field_value = getattr(self, field_name.name, None)
if not field_value:
missing_fields.append(field_name.field_description)
if missing_fields:
raise UserError(f"转交失败!必填字段未填写:{', '.join(missing_fields)}")
if btn_rec.name != '结束':
current_node = node_list[state_list.index(state)]
self.env['trans.link'].search([]).unlink()
# 退回节点根据日志进行判断
if btn_rec.name == '退回':
approved_logs = self.log_ids.filtered(lambda log: log.approval_state == '2')
for ret in approved_logs:
if not self.env['trans.link'].search([('name', '=', ret.name)]):
self.env['trans.link'].create({
'node_button_id': btn_rec.id,
'name': ret.name,
'link_type': 'return',
'record_id': self.id,
})
if btn_rec.name == '转交':
required_fields = [
field.name for field in current_node.field_ids
if field.required and field.name
]
missing_fields = []
if required_fields:
for field_name in required_fields:
field_value = getattr(self, field_name.name, None)
if not field_value:
missing_fields.append(field_name.field_description)
if missing_fields:
raise UserError(f"转交失败!必填字段未填写:{', '.join(missing_fields)}")
skipped_node_names = [] # 因没有可用按钮而跳过的节点
node_list = list(btn_rec.workflow_id.node_ids.sorted('sequence'))
index = self_state
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 btn_rec.link_id in current_node.out_link_ids and len(current_node.out_link_ids) == 1:
matched_link = btn_rec.link_id
next_node = matched_link.node_to
matched_key = next_node.name
else:
if len(current_node.out_link_ids) > 1:
# 筛选与当前节点部门匹配的后续节点
valid_nodes = []
for link in current_node.out_link_ids:
if self.name_title in ['业务审批', '会审意见表', '信息发布申请表',]:
category_names = self.information_categories_ids.mapped('name')
target_name = link.name.split('->')[-1].strip()
if '工会活动' in category_names:
if target_name == '工会主席':
target_node = link.node_to
valid_nodes.append((target_node, link))
else:
if target_name == '复核':
target_node = link.node_to
valid_nodes.append((target_node, link))
if target_name == '承办部门意见':
target_node = link.node_to
valid_nodes.append((target_node, link))
else:
target_node = link.node_to
# 如果目标节点有部门限制,且与当前节点部门匹配
if target_node.department_id and any(
dept in current_department or
current_department in self.get_all_sub_departments(dept)
for dept in 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 any(
dept in parent_department or
parent_department in self.get_all_sub_departments(dept)
for dept in target_node.department_id
):
valid_nodes.append((target_node, link))
# 如果两种匹配都失败,将所有节点加入有效列表
if not valid_nodes:
for link in current_node.out_link_ids:
valid_nodes.append((link.node_to, link))
# 选择第一个匹配的节点
next_node, matched_link = valid_nodes[0]
matched_key = next_node.name
else:
matched_link = current_node.out_link_ids[0]
skipped_node_names = [] # 因没有可用按钮而跳过的节点
node_list = list(btn_rec.workflow_id.node_ids.sorted('sequence'))
index = self_state
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 btn_rec.link_id in current_node.out_link_ids and len(current_node.out_link_ids) == 1:
matched_link = btn_rec.link_id
next_node = matched_link.node_to
matched_key = next_node.name
transfer_buttons = [
btn for btn in next_node.button_ids
if btn.name == '转交'
]
end_buttons = [
btn for btn in next_node.button_ids
if btn.name == '结束'
]
has_visible_transfer_btn = True
for btn in transfer_buttons:
if btn.is_review_invisible:
domain = eval(btn.invisible_expression)
expression_result = self.search(domain)
has_self_in_result = self.id in expression_result.ids
if not end_buttons:
if has_self_in_result:
has_visible_transfer_btn = True
break
else:
if len(current_node.out_link_ids) > 1:
# 筛选与当前节点部门匹配的后续节点
valid_nodes = []
for link in current_node.out_link_ids:
if self.name_title in ['业务审批', '会审意见表', '信息发布申请表',]:
category_names = self.information_categories_ids.mapped('name')
target_name = link.name.split('->')[-1].strip()
if '工会活动' in category_names:
if target_name == '工会主席':
target_node = link.node_to
valid_nodes.append((target_node, link))
else:
has_visible_transfer_btn = False
if target_name == '复核':
target_node = link.node_to
valid_nodes.append((target_node, link))
if target_name == '承办部门意见':
target_node = link.node_to
valid_nodes.append((target_node, link))
else:
target_node = link.node_to
# 如果目标节点有部门限制,且与当前节点部门匹配
if target_node.department_id and any(
dept in current_department or
current_department in self.get_all_sub_departments(dept)
for dept in 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 any(
dept in parent_department or
parent_department in self.get_all_sub_departments(dept)
for dept in target_node.department_id
):
valid_nodes.append((target_node, link))
# 如果两种匹配都失败,将所有节点加入有效列表
if not valid_nodes:
for link in current_node.out_link_ids:
valid_nodes.append((link.node_to, link))
# 选择第一个匹配的节点
next_node, matched_link = valid_nodes[0]
matched_key = next_node.name
else:
matched_link = current_node.out_link_ids[0]
next_node = matched_link.node_to
matched_key = next_node.name
transfer_buttons = [
btn for btn in next_node.button_ids
if btn.name == '转交'
]
end_buttons = [
btn for btn in next_node.button_ids
if btn.name == '结束'
]
has_visible_transfer_btn = True
for btn in transfer_buttons:
if btn.is_review_invisible:
domain = eval(btn.invisible_expression)
expression_result = self.search(domain)
has_self_in_result = self.id in expression_result.ids
if not end_buttons:
if has_self_in_result:
has_visible_transfer_btn = True
break
else:
has_visible_transfer_btn = False
else:
has_visible_transfer_btn = True
else:
has_visible_transfer_btn = True
else:
has_visible_transfer_btn = True
if not has_visible_transfer_btn:
skipped_node_names.append(next_node.name)
_logger.info(f"跳过节点: {next_node.name},无可见的转交按钮")
if not has_visible_transfer_btn:
skipped_node_names.append(next_node.name)
_logger.info(f"跳过节点: {next_node.name},无可见的转交按钮")
# 更新索引
index = state_list.index(matched_key)
if index >= len(node_list):
break
# 更新索引
index = state_list.index(matched_key)
if index >= len(node_list):
break
#根据实际路径创建trans.link记录并生成domain
actual_path_links = []
for node in actual_path_nodes[1:]:
if node.name not in skipped_node_names:
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)
if actual_path_links:
trans_link_ids = [link.id for link in actual_path_links]
trans_domain = [('id', 'in', trans_link_ids)]
else:
trans_domain = []
#根据实际路径创建trans.link记录并生成domain
actual_path_links = []
for node in actual_path_nodes[1:]:
if node.name not in skipped_node_names:
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)
if actual_path_links:
trans_link_ids = [link.id for link in actual_path_links]
trans_domain = [('id', 'in', trans_link_ids)]
else:
trans_domain = []
is_supervising = False
if self.name_title in ['行政发文']:
is_supervising = self.is_supervising
if btn_rec.node_id.comment_id:
comment_note_id = btn_rec.node_id.comment_id.id
else:
@@ -518,8 +518,8 @@ class SoongWorkflowCommentWizard(models.TransientModel):
"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))
# 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})
@@ -652,7 +652,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
"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:
@@ -693,7 +692,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
title=record_id._description,
description=f"编号为{record_id.code}的{record_id._description}已结束,请归档",
url=url, btntxt="查看详情")
self.node_btn_id.with_context(cx).run()
return 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', '=', '行政收文')])
@@ -714,7 +713,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
"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=emp.wecom_userid, title=record_id._description, description=description, url=url, btntxt="查看详情")
# 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 = None
if result_data and isinstance(result_data, list) and len(result_data) > 0:
last_item = result_data[-1]
@@ -794,7 +793,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
record.write({'state': log_ids[-2].name, 'work_end': False})
self.node_btn_id.with_context(cx).run()
if self.node_btn_name == '归档':
record = self.env[self.res_model].search([('id', '=', self.res_id)])
record.log_ids[-1].write({'approval_state': '2'})
@@ -804,8 +802,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
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()
+1 -1
View File
@@ -9,7 +9,7 @@ class YuthonWillTask(http.Controller):
@http.route('/party/list', methods=['POST'], type='http', auth='public', csrf=False)
def party_list(self, **kwargs):
party_ids = request.env['yuthon.salary.party'].sudo().search([('employee_id.id', '=', kwargs.get('employee_id'))])
party_ids = request.env['yuthon.salary.party'].sudo().search([])[0]
data_list = []
for party in party_ids:
result = {