From 40eef70bfff404e668d728d612d7a90e277522b4 Mon Sep 17 00:00:00 2001 From: pengyuthon Date: Wed, 7 Jan 2026 01:07:20 +0800 Subject: [PATCH] 1 --- soong_workflow/models/soong_workflow_log.py | 2 +- soong_workflow/models/soong_workflow_mixin.py | 55 ++++++++--- soong_workflow/models/soong_workflow_node.py | 28 ++++++ .../templates/soong_workflow_templates.xml | 23 +---- soong_workflow/views/menuitem.xml | 15 ++- .../views/soong_workflow_log_views.xml | 92 +++++-------------- .../views/soong_workflow_node_views.xml | 1 + .../wizard/soong_workflow_comment_wizard.py | 54 ++++------- .../soong_workflow_comment_wizard_view.xml | 16 +++- 9 files changed, 136 insertions(+), 150 deletions(-) diff --git a/soong_workflow/models/soong_workflow_log.py b/soong_workflow/models/soong_workflow_log.py index b77537595..696630ac5 100644 --- a/soong_workflow/models/soong_workflow_log.py +++ b/soong_workflow/models/soong_workflow_log.py @@ -82,7 +82,7 @@ class SoongWorkflowLog2(models.Model): sequence = fields.Integer(string="序号", compute="_compute_sequence") done_by = fields.Many2one(comodel_name="res.users", string="审批人") name = fields.Char(string="节点名称", compute="_compute_name", store=True) - approval_state = fields.Selection([('0', '未读'), ('1', '已读')], string='状态', default='0') + approval_state = fields.Selection([('0', '待办理'), ('1', '办理中'), ('2', '已办结')], string='状态', default='0') document_ids = fields.Many2many('ir.attachment', string="附件") lase_click_date = fields.Datetime(string="操作时间") commit = fields.Char(string="意见") diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 2f8704dd5..5eeb11b3f 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -81,11 +81,9 @@ class SoongWorkflowMixin(models.AbstractModel): domain=lambda self: [('res_model', '=', self._name)], auto_join=True, string="审批明细") approval_sign_ids = fields.Many2many('res.users', store=False, compute="_compute_approval_sign_ids", string="加签人员") - is_back = fields.Boolean( - string='是否允许收回', - compute='_compute_is_back', - store=False, - ) + is_back = fields.Boolean(string='是否允许收回', compute='_compute_is_back', store=False,) + is_confirm = fields.Boolean(string="未确认", compute='_compute_is_confirm', store=False,) + is_end = fields.Boolean(string="未结束", compute='_compute_is_confirm', store=False,) def _compute_is_back(self): for record in self: @@ -97,6 +95,22 @@ class SoongWorkflowMixin(models.AbstractModel): if matched_logs and all(log.approval_state == '0' for log in matched_logs): record.is_back = True + def _compute_is_confirm(self): + for record in self: + record.is_confirm = True + record.is_end = True + 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) + lg1 = record.log_ids.search(domain) + if lg2: + record.is_confirm = False + if lg1: + record.is_end = False + + + + @api.depends("node_id", "log_ids") def _compute_approval_sign_ids(self): for record in self: @@ -819,18 +833,21 @@ class SoongWorkflowMixin(models.AbstractModel): domain = eval(button.invisible_expression) btn_invisible = self.sudo().env[button.workflow_id.model_id.model].search(domain).ids invisible += " or id not in {0} ".format(str(btn_invisible)) - # 如果是加签确认 - # if is_apostille: - # id_el = etree.Element("field") - # id_el.set("name", "approval_sign_ids") - # id_el.set("invisible", "1") - # invisible += " or uid not in approval_sign_ids" - if button.name in ["退回", "结束"]: + if button.name == '确认': + id_el = etree.Element("field") + id_el.set("name", "log_ids") + id_el.set("invisible", "1") + invisible += " or not log_ids or is_confirm" + if button.name == '结束': + id_el = etree.Element("field") + id_el.set("name", "log_ids") + id_el.set("invisible", "1") + invisible += " or not log_ids or is_end" + if button.name == "退回": id_el = etree.Element("field") id_el.set("name", "log_ids") id_el.set("invisible", "1") invisible += " or not log_ids " - if button.name == "分发": invisible += " or is_send" if button.name == "收回": @@ -839,10 +856,8 @@ class SoongWorkflowMixin(models.AbstractModel): id_el.set("invisible", "1") invisible += " or not log_ids or not is_back" invisible += " or work_end" - if model == 'purchase.order': invisible = invisible.replace("询价", "draft") - btn_exec_action_el.set("invisible", invisible) btn_exec_action_el.set("context", "{'btn_key':'%s','active_model':'%s'}" % (button.btn_key, self._name),) res["arch"] = etree.tostring(arch, encoding="unicode").replace("\t", "") @@ -902,6 +917,16 @@ class SoongWorkflowMixin(models.AbstractModel): header_el = arch.xpath("//form/header") header_el = header_el[0] if header_el else False # Create State Element If not Exists + end_el = etree.Element("field") + end_el.set("name", "is_end") + end_el.set("invisible", "1") + header_el.append(end_el) + + confirm_el = etree.Element("field") + confirm_el.set("name", "is_confirm") + confirm_el.set("invisible", "1") + header_el.append(end_el) + if header_el is not False: state_el = etree.Element("field") state_el.set("name", "state") diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py index 056a3c0c3..c987fc5ee 100644 --- a/soong_workflow/models/soong_workflow_node.py +++ b/soong_workflow/models/soong_workflow_node.py @@ -87,6 +87,7 @@ class SoongWorkflowNode(models.Model): is_apostille = fields.Boolean(string="加签", default=False) employee_ids = fields.Many2many('hr.employee', string='抄送/传阅人员') is_end = fields.Boolean(string="结束", default=False) + is_confirm = fields.Boolean(string="确认", default=False) department_id = fields.Many2many('hr.department', string='部门转入范围') comment_id = fields.Many2one('soong.note', string="固定意见") approval_concatenation = fields.Selection([('chuan', '串申'), ('bing', '并申')], string="审批形式", default="bing", @@ -148,6 +149,31 @@ class SoongWorkflowNode(models.Model): remove_ids = record.button_ids.filtered(lambda r: r.name in ["结束"]) record.button_ids = [(3, remove_id.id) for remove_id in remove_ids] + @api.onchange("is_confirm") + def onchange_is_confirm(self): + for record in self: + if record.is_confirm: + record.use_custom_colors = True + sequence = max([r.sequence for r in record.button_ids] if record.button_ids else [1]) + record.button_ids = [ + (0, 0, { + "name": _("确认"), + # "workflow_id": record.workflow_id.ids[0] if record.workflow_id.ids else None, + "node_id": record.id, + "sequence": sequence + 1, + "action_type": "confirm", + "btn_hide": False, # 对所有人显示 + "has_comment": False, # 对所有人显示 + "review_type": "confirm", + }), + ] + else: + record.use_custom_colors = True + record.bg_color = DEFAULT_BG_COLOR + record.res_bg_color = DEFAULT_BG_COLOR + remove_ids = record.button_ids.filtered(lambda r: r.name in ["确认"]) + record.button_ids = [(3, remove_id.id) for remove_id in remove_ids] + def btn_role_sync(self): for record in self: now_btn = record.button_ids.filtered(lambda r: r.name in ["转交"]) @@ -344,6 +370,7 @@ class SoongWorkflowNodeButton(models.Model): # ('invisible', '隐藏条件'), ('apostille', '加签确认'), ('end', "结束"), + ('confirm', "确认"), ('withdraw', '收回'), ], ) @@ -377,6 +404,7 @@ class SoongWorkflowNodeButton(models.Model): ("win_act", "Window Action"), ("apostille", "加签按钮"), ('end', "结束"), + ('confirm', "确认"), ], string="Action Type", default="link", diff --git a/soong_workflow/templates/soong_workflow_templates.xml b/soong_workflow/templates/soong_workflow_templates.xml index d8a3c8500..8f4ecdd2b 100644 --- a/soong_workflow/templates/soong_workflow_templates.xml +++ b/soong_workflow/templates/soong_workflow_templates.xml @@ -43,16 +43,6 @@ - - - - - - - - - - @@ -82,8 +72,7 @@ - + @@ -107,16 +96,6 @@ - - - - - - - - - - diff --git a/soong_workflow/views/menuitem.xml b/soong_workflow/views/menuitem.xml index 154b37ed8..779c6cc70 100644 --- a/soong_workflow/views/menuitem.xml +++ b/soong_workflow/views/menuitem.xml @@ -31,11 +31,11 @@ parent="menu_soong_workflow_root" action="soong_workflow_hr_employee_action" sequence="5"/> - + + + + + + - - soong.workflow.log.kanban - soong.workflow.log - - - - - - - - - - -
-
- - - - - - -
-
-
- 经办人: [] -
-
- - - -
- -
- - [] - -
-
- -
- - - -
-
-
-
-
-
-
-
-
- soong.workflow.log.tree soong.workflow.log @@ -62,8 +8,6 @@ - - @@ -73,22 +17,32 @@
- - soong.workflow.log.search - soong.workflow.log - - - - - - - - - + 工作流日志 soong.workflow.log tree - {'search_default_code': 1} + + + + soong.workflow.log2.tree + soong.workflow.log2 + + + + + + + + + + + + + + + 传阅日志 + soong.workflow.log2 + tree \ No newline at end of file diff --git a/soong_workflow/views/soong_workflow_node_views.xml b/soong_workflow/views/soong_workflow_node_views.xml index 235244391..76f864e50 100644 --- a/soong_workflow/views/soong_workflow_node_views.xml +++ b/soong_workflow/views/soong_workflow_node_views.xml @@ -41,6 +41,7 @@ options="{'no_create': True}"/> + diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index 16db6f7ae..9c8f2a478 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -202,7 +202,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): ('name', '=', link.name), ('workflow_id', '=', workflow_id.id) ]) - button_priority_list = ["分发", "下发","转交", "结束"] + button_priority_list = ["分发", "下发", "转交", "结束"] button = False if node.button_ids: for btn_name in button_priority_list: @@ -517,7 +517,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): 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 == '结束': + 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') @@ -541,10 +541,21 @@ class SoongWorkflowCommentWizard(models.TransientModel): '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, self.circulated_employee_ids.ids)] + 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, @@ -564,6 +575,10 @@ class SoongWorkflowCommentWizard(models.TransientModel): "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_ids.search([('approval_state', 'in', ['0', '1'])]) and not record_id.log_ids2.search([('approval_state', '=', '0')]): record_id.work_end = True # last_log = log_records[-1] if log_records else None @@ -632,37 +647,6 @@ class SoongWorkflowCommentWizard(models.TransientModel): description=f"编号为{record_id.code}的{record_id._description}已结束,请归档", url=url, btntxt="查看详情") self.node_btn_id.with_context(cx).run() - if self.node_btn_name == '确认': - log_rec_id = record_id.log_ids2.filtered(lambda log: log.done_by == self.env.user) - log_rec_id.write({ - 'comment': self.comment, - 'approval_state': "1", - 'lase_click_date': fields.datetime.now(), - 'document_ids': [(6, 0, self.document_ids.ids)] - }) - for employee in self.circulated_employee_ids: - 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, self.circulated_employee_ids.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", - }) - 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", - }) if self.node_btn_name == "分发": record_id.is_send = True workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)]) @@ -744,7 +728,7 @@ class SoongWorkflowCommentWizard(models.TransientModel): self.node_btn_id.with_context(cx).run() if self.node_btn_name != "收回": - menu_id = self.env.ref("soong_workflow.menu_soong_workflow_todo_record_first").id + menu_id = self.env.ref("yuthon_work_brand.menu_soong_workflow_todo_record").id return { "type": "ir.actions.client", "tag": "reload", diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml index 3ed46ff3f..378b5f8f2 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml +++ b/soong_workflow/wizard/soong_workflow_comment_wizard_view.xml @@ -14,7 +14,7 @@ - +