From 6cc797e6c09c56cfb0ab7be4e46d56c578a3e3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Mon, 7 Sep 2026 19:18:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=83=E5=8B=A4=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- attendance_iot/models/hr_employee.py | 26 ++++----- .../attendance_iot_import_user_wizard.py | 58 +++++++++++-------- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/attendance_iot/models/hr_employee.py b/attendance_iot/models/hr_employee.py index ac3813506..4ad55679c 100644 --- a/attendance_iot/models/hr_employee.py +++ b/attendance_iot/models/hr_employee.py @@ -53,15 +53,13 @@ class HrEmployee(models.Model): return res def _get_attendance_iot_copy_action(self, sync_to_all=False): - # 打开「拷贝考勤机记录」弹窗的公共方法 - # sync_to_all=True 时弹窗默认带出本公司全部考勤机(同步到全部设备) - self.ensure_one() - # 源考勤机:取该员工已绑定的第一台考勤机 - source_iot = self.attendance_iot_ids[:1].attendance_iot_id - # 员工还没绑定任何考勤机时无法拷贝,直接提示 - if not source_iot: - raise exceptions.UserError('该员工还没有绑定任何考勤机,无法拷贝!') - # 返回弹窗动作,context 带上源考勤机、员工、是否同步全部设备 + # 打开「拷贝考勤机记录」弹窗(供员工列表按钮调用,支持多选员工) + # sync_to_all=True 时弹窗默认带出选中员工公司的全部考勤机 + # 取选中员工的 id 列表(列表可勾选多条) + employee_ids = self.ids + # 源公司:取第一个选中员工的公司 + company = self[:1].company_id + # 返回弹窗动作,context 带上员工、公司、是否同步全部设备 return { 'type': 'ir.actions.act_window', 'name': '拷贝考勤机记录', @@ -70,11 +68,11 @@ class HrEmployee(models.Model): 'view_id': self.env.ref('attendance_iot.attendance_iot_import_user_wizard_form').id, 'target': 'new', 'context': { - # 源考勤机:弹窗里显示为「当前被拷贝考勤机」 - 'default_source_attendance_iot_id': source_iot.id, - # 被拷贝的员工:点同步时按该员工创建考勤机用户记录 - 'default_source_employee_id': self.id, - # 是否默认带出本公司全部考勤机 + # 选中要同步的员工 id 列表 + 'default_employee_ids': employee_ids, + # 选中员工所在公司(决定带出哪家公司的考勤机) + 'default_company_id': company.id, + # 是否默认带出公司全部考勤机 'default_sync_to_all': sync_to_all, }, } diff --git a/attendance_iot/wizard/attendance_iot_import_user_wizard.py b/attendance_iot/wizard/attendance_iot_import_user_wizard.py index 241a4669c..fb9dcc2e2 100644 --- a/attendance_iot/wizard/attendance_iot_import_user_wizard.py +++ b/attendance_iot/wizard/attendance_iot_import_user_wizard.py @@ -13,42 +13,54 @@ class AttendanceIotImportUserWizard(models.TransientModel): def default_get(self, fields_list): # 先调用父类获取各字段的默认值字典 res = super(AttendanceIotImportUserWizard, self).default_get(fields_list) - # 从上下文中取出列表页勾选的考勤机用户记录 id 列表 - active_ids = self.env.context.get('active_ids') - # 按 id 批量取出被勾选的考勤机用户记录 - records = self.env['attendance.iot.user'].browse(active_ids) - # 取第一条记录,作为被拷贝的源考勤机 - source_iot = records[0].attendance_iot_id - # 查出源考勤机所属公司的全部考勤机,作为同步目标默认带出(不排除源设备) - company_iots = self.env['attendance.iot'].search( - [('company_id', '=', source_iot.company_id.id)]) - - res.update({ - 'current_attendance_iot_id': source_iot.id, - 'attendance_iot_ids': [(6, 0, company_iots.ids)], - }) - + # 入口一:员工列表按钮进入,context 带了选中的员工 id 列表 + employee_ids = self.env.context.get('default_employee_ids') + if employee_ids: + # 源公司:第一个选中员工的公司 + company = self.env['hr.employee'].browse(employee_ids[0]).company_id + # 「同步到全部设备」时默认带出该公司全部考勤机 + if self.env.context.get('default_sync_to_all'): + company_iots = self.env['attendance.iot'].search( + [('company_id', '=', company.id)]) + res['attendance_iot_ids'] = [(6, 0, company_iots.ids)] + else: + # 入口二:考勤机用户列表勾选进入,取第一条记录的源考勤机 + active_ids = self.env.context.get('active_ids') + records = self.env['attendance.iot.user'].browse(active_ids) + # 取第一条记录,作为被拷贝的源考勤机 + source_iot = records[0].attendance_iot_id + # 查出源考勤机所属公司的全部考勤机,作为同步目标默认带出(不排除源设备) + company_iots = self.env['attendance.iot'].search( + [('company_id', '=', source_iot.company_id.id)]) + res.update({ + 'current_attendance_iot_id': source_iot.id, + 'attendance_iot_ids': [(6, 0, company_iots.ids)], + }) return res def action_import(self): - # 获取用户, employee_id - # 根据 attendance_iot_user.employ_id 批量给每个考勤机创建信息 - # 完成 - ids = self.env.context.get('active_ids') - records = self.env['attendance.iot.user'].browse(ids) + # 入口一:员工列表按钮进入,context 带了选中的员工 id 列表 + employee_ids = self.env.context.get('default_employee_ids') + if employee_ids: + # 按员工处理(browse 自动去重) + employees = self.env['hr.employee'].browse(employee_ids) + else: + # 入口二:考勤机用户列表勾选进入,取勾选记录对应的员工 + employees = self.env['attendance.iot.user'].browse( + self.env.context.get('active_ids')).mapped('employee_id') values = [] for attendance_iot_id in self.attendance_iot_ids: - for record in records: + for employee in employees: # 去重,已经有的记录不再更新, iot_user = self.env['attendance.iot.user'].search( - [('attendance_iot_id','=', attendance_iot_id.id), ('employee_id', '=', record.employee_id.id)]) + [('attendance_iot_id','=', attendance_iot_id.id), ('employee_id', '=', employee.id)]) if iot_user: if not self.is_force_update: continue iot_user.with_context(iot_sync=True).unlink() values.append({ 'attendance_iot_id': attendance_iot_id.id, - 'employee_id': record.employee_id.id + 'employee_id': employee.id }) self.env['attendance.iot.user'].sudo().create(values)