diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 0f4d365bf..edfe27d3e 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -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: diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index e46a62dab..059a19cc4 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -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() diff --git a/yuthon_salary/controllers/salary_phone.py b/yuthon_salary/controllers/salary_phone.py index 616800981..f21900d42 100644 --- a/yuthon_salary/controllers/salary_phone.py +++ b/yuthon_salary/controllers/salary_phone.py @@ -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 = {