From f7ef05a787f6f17b7fec11696aa92d01408ec433 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?=
<9664676+pengyuthon@user.noreply.gitee.com>
Date: Tue, 30 Jun 2026 16:17:20 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../models/expatriation_approval.py | 78 +++++++++++++++++++
.../views/expatriation_approval.xml | 37 ++++++++-
yuthon_work_brand/views/hr_menus.xml | 4 +
3 files changed, 115 insertions(+), 4 deletions(-)
diff --git a/yuthon_hr_attendance/models/expatriation_approval.py b/yuthon_hr_attendance/models/expatriation_approval.py
index c420ea1ad..23d9ae184 100644
--- a/yuthon_hr_attendance/models/expatriation_approval.py
+++ b/yuthon_hr_attendance/models/expatriation_approval.py
@@ -15,6 +15,25 @@ class ExpatriationApproval(models.Model):
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
expatriates_ids = fields.Many2many('hr.employee', string="外派人员")
start_date = fields.Date(string="开始日期")
+ return_date = fields.Date(
+ string="返回日期",
+ compute="_compute_return_date",
+ )
+ approve_state = fields.Selection(
+ [("start", "草稿"), ("pending", "审批中"), ("end", "结束")],
+ string="审批状态",
+ compute="_compute_approve_state",
+ )
+ expatriation_state = fields.Selection(
+ [("expatriating", "外派中"), ("returned", "已返回")],
+ string="状态",
+ compute="_compute_expatriation_state",
+ )
+ reclaim_state = fields.Boolean(
+ string="已作废",
+ compute="_compute_reclaim_state",
+ search="_search_reclaim_state",
+ )
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
default='normal')
active = fields.Boolean('Active', default=True, tracking=True)
@@ -47,4 +66,63 @@ class ExpatriationApproval(models.Model):
'approval_date': fields.Datetime.now(),
})
+ def _compute_approve_state(self):
+ """从关联的 back.approval 找到对应的 workflow.record,取其 approve_state"""
+ for rec in self:
+ wf = self.env['soong.workflow.record'].search([
+ ('res_model', '=', 'expatriation.approval'),
+ ('res_id', '=', rec.id),
+ ('reclaim_state', '=', False),
+ ], limit=1)
+ rec.approve_state = wf.approve_state if wf else False
+
+ def _compute_return_date(self):
+ """取关联 back.approval 的 end_date,但需 workflow 已 end 才写入"""
+ for rec in self:
+ back = self.env['back.approval'].search([
+ ('expatriation_id', '=', rec.id),
+ ], limit=1)
+ if not back:
+ rec.return_date = False
+ continue
+ wf = self.env['soong.workflow.record'].search([
+ ('res_model', '=', 'back.approval'),
+ ('res_id', '=', back.id),
+ ('reclaim_state', '=', False),
+ ('approve_state', '=', 'end'),
+ ], limit=1)
+ rec.return_date = back.end_date if wf else False
+
+ def _compute_reclaim_state(self):
+ """从 workflow.record 取 reclaim_state"""
+ for rec in self:
+ wf = self.env['soong.workflow.record'].search([
+ ('res_model', '=', 'expatriation.approval'),
+ ('res_id', '=', rec.id),
+ ], limit=1)
+ rec.reclaim_state = wf.reclaim_state if wf else False
+
+ def _search_reclaim_state(self, operator, value):
+ """domain 搜索:按 workflow.record 的 reclaim_state 过滤"""
+ reclaimed_records = self.env['soong.workflow.record'].search([
+ ('res_model', '=', 'expatriation.approval'),
+ ('reclaim_state', '=', True),
+ ])
+ reclaimed_ids = reclaimed_records.mapped('res_id')
+ if operator == '=':
+ return [('id', 'in' if value else 'not in', reclaimed_ids)]
+ elif operator == '!=':
+ return [('id', 'not in' if value else 'in', reclaimed_ids)]
+ return []
+
+ def _compute_expatriation_state(self):
+ """有返回日期→已返回,审批结束→外派中,否则空"""
+ for rec in self:
+ if rec.return_date:
+ rec.expatriation_state = 'returned'
+ elif rec.approve_state == 'end':
+ rec.expatriation_state = 'expatriating'
+ else:
+ rec.expatriation_state = False
+
diff --git a/yuthon_hr_attendance/views/expatriation_approval.xml b/yuthon_hr_attendance/views/expatriation_approval.xml
index 80017936e..94c1b3209 100644
--- a/yuthon_hr_attendance/views/expatriation_approval.xml
+++ b/yuthon_hr_attendance/views/expatriation_approval.xml
@@ -4,10 +4,14 @@
expatriation.approval
-
-
-
-
+
+
+
+
+
+
+
+
@@ -48,6 +52,8 @@
+
+
@@ -63,4 +69,27 @@
expatriation.approval
tree,form
+
+ expatriation.approval.simple.tree
+ expatriation.approval
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 外派返回查询
+ expatriation.approval
+ tree,form
+ [('reclaim_state', '=', False)]
+
+
\ No newline at end of file
diff --git a/yuthon_work_brand/views/hr_menus.xml b/yuthon_work_brand/views/hr_menus.xml
index 0640fc427..335b08597 100644
--- a/yuthon_work_brand/views/hr_menus.xml
+++ b/yuthon_work_brand/views/hr_menus.xml
@@ -192,6 +192,10 @@
+