考勤机

This commit is contained in:
李鹏宇
2026-09-07 19:18:35 +08:00
parent 7c9f98a35b
commit 6cc797e6c0
2 changed files with 47 additions and 37 deletions
+12 -14
View File
@@ -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,
},
}
@@ -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)