From d2fde86063073b4fc2df44ed245d07533582edca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Sat, 24 Jan 2026 20:32:41 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E7=94=A8=E8=BF=99?= =?UTF-8?q?=E4=B8=AA=E7=94=A8=E7=AB=A0=E8=8C=83=E5=9B=B4=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yuthon_trade/views/yuthon_trade_setting_views.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yuthon_trade/views/yuthon_trade_setting_views.xml b/yuthon_trade/views/yuthon_trade_setting_views.xml index d64b68c88..b17aace84 100644 --- a/yuthon_trade/views/yuthon_trade_setting_views.xml +++ b/yuthon_trade/views/yuthon_trade_setting_views.xml @@ -47,6 +47,8 @@ 用章类型 seals.type.setting tree + {'group_by': 'scope_setting_id'} + [('start_date', '<=', context_today().strftime('%Y-%m-%d'))] seals.scope.setting.tree From 19f1f8a74765dce1ff76b59ed7b0988c63957bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Sat, 24 Jan 2026 21:10:15 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E7=94=A8=E8=BF=99?= =?UTF-8?q?=E4=B8=AA=E7=94=A8=E7=AB=A0=E8=8C=83=E5=9B=B4=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yuthon_trade/views/yuthon_seals_approval_views.xml | 2 +- yuthon_trade/views/yuthon_trade_setting_views.xml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/yuthon_trade/views/yuthon_seals_approval_views.xml b/yuthon_trade/views/yuthon_seals_approval_views.xml index 62cb54c01..c8337d37d 100644 --- a/yuthon_trade/views/yuthon_seals_approval_views.xml +++ b/yuthon_trade/views/yuthon_seals_approval_views.xml @@ -43,7 +43,7 @@ - + diff --git a/yuthon_trade/views/yuthon_trade_setting_views.xml b/yuthon_trade/views/yuthon_trade_setting_views.xml index b17aace84..7a2eab8a0 100644 --- a/yuthon_trade/views/yuthon_trade_setting_views.xml +++ b/yuthon_trade/views/yuthon_trade_setting_views.xml @@ -43,6 +43,20 @@ + + seals.type.setting.search + seals.type.setting + + + + + + + + + + + 用章类型 seals.type.setting From 83bde38b383a5a3918a3165b0d41bf88f5758431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Mon, 26 Jan 2026 09:41:49 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=BE=85=E5=8A=9E=EF=BC=9A=E5=8A=9E?= =?UTF-8?q?=E7=BB=93=E6=97=B6=E9=97=B4=E2=80=94=E2=80=94=E2=80=94=E2=80=94?= =?UTF-8?q?=E5=88=B0=E8=BE=BE=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soong_workflow/views/soong_workflow_record.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soong_workflow/views/soong_workflow_record.xml b/soong_workflow/views/soong_workflow_record.xml index cfde14aed..8502c1d9a 100644 --- a/soong_workflow/views/soong_workflow_record.xml +++ b/soong_workflow/views/soong_workflow_record.xml @@ -243,7 +243,7 @@ decoration-danger="approve_state == 'end'" decoration-success="approve_state == 'pending'"/> - + From 165d70f3ab462cc5c4c50cdc45bfd4a484aa8efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Mon, 26 Jan 2026 10:56:50 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=89=B9=E9=87=8F=E8=A1=A5=E5=85=A8?= =?UTF-8?q?=E5=8A=9E=E7=BB=93=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soong_workflow/models/soong_workflow_mixin.py | 4 ++ .../models/soong_workflow_record.py | 42 +++++++++++++++++++ .../views/soong_workflow_record.xml | 18 ++++++++ 3 files changed, 64 insertions(+) diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index fcd04ba59..87e584576 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -667,6 +667,10 @@ class SoongWorkflowMixin(models.AbstractModel): sorted_logs = rec.log_ids.sorted(lambda log: log.id) if sorted_logs and sorted_logs[-1].lase_click_date: node_update_time = sorted_logs[-1].lase_click_date + + # 补丁:如果审批状态已经是结束,但还没拿到时间,则尝试用当前时间作为办结时间 + if not node_update_time and record_obj.approve_state == 'end': + node_update_time = fields.Datetime.now() except Exception as e: _logger.debug(f"Failed to get node_update_time: {e}") diff --git a/soong_workflow/models/soong_workflow_record.py b/soong_workflow/models/soong_workflow_record.py index e4625d0fe..f7680c16a 100644 --- a/soong_workflow/models/soong_workflow_record.py +++ b/soong_workflow/models/soong_workflow_record.py @@ -622,6 +622,48 @@ class SoongWorkflowRecord(models.Model): }, } + def action_update_history_end_time(self): + """ + 批量计算已结束流程的办结时间 + """ + # 寻找所有审批状态为结束(end)且办结时间为空的记录 + records = self.search([ + ('approve_state', '=', 'end'), + ('node_update_time', '=', False) + ]) + + count = 0 + for rec in records: + if not rec.res_model or not rec.res_id: + continue + + try: + # 获取对应的业务单据 + source_record = self.env[rec.res_model].browse(rec.res_id) + if not source_record.exists(): + continue + + # 提取该单据最后一条审批日志的时间 + if hasattr(source_record, 'log_ids') and source_record.log_ids: + # 按ID排序,取最后一条记录 + sorted_logs = source_record.log_ids.sorted(lambda l: l.id) + if sorted_logs and sorted_logs[-1].lase_click_date: + # 更新办结时间 + rec.write({'node_update_time': sorted_logs[-1].lase_click_date}) + count += 1 + except Exception as e: + _logger.error(f"计算记录 {rec.id} 办结时间失败: {e}") + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '处理完成', + 'message': f'成功更新了 {count} 条记录的办结时间', + 'sticky': False, + } + } + diff --git a/soong_workflow/views/soong_workflow_record.xml b/soong_workflow/views/soong_workflow_record.xml index 8502c1d9a..c4178c9af 100644 --- a/soong_workflow/views/soong_workflow_record.xml +++ b/soong_workflow/views/soong_workflow_record.xml @@ -92,6 +92,8 @@ groups="soong_workflow.group_soong_workflow_manager"/>