From 1b802cd6860e620648007c436b2ac5ad43799f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Wed, 9 Sep 2026 10:34:57 +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 | 30 +++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/attendance_iot/models/hr_employee.py b/attendance_iot/models/hr_employee.py index 0b1fadd0d..201fde606 100644 --- a/attendance_iot/models/hr_employee.py +++ b/attendance_iot/models/hr_employee.py @@ -86,7 +86,31 @@ class HrEmployee(models.Model): return self._get_attendance_iot_copy_action(sync_to_all=False) def action_attendance_iot_sync_all(self): - # 「同步到全部设备」按钮:打开弹窗并默认带出本公司全部考勤机 + # 「考勤机更新」按钮:直接把选中员工的人脸数据同步到其关联的全部设备 + # 逻辑与 attendance.iot.user.tree 的 action_batch_sync_to_all_devices 一致(直接推送,不走弹窗) if not self: - raise UserError(_('请先在员工列表中勾选要同步的员工,再点击「同步到全部设备」。')) - return self._get_attendance_iot_copy_action(sync_to_all=True) + raise UserError(_('请先在员工列表中勾选要同步的员工,再点击「考勤机更新」。')) + # 收集所有选中员工的设备绑定记录(attention: attendance_iot_ids 是绑定记录的一对多) + bindings = self.env['attendance.iot.user'].search([('employee_id', 'in', self.ids)]) + if bindings: + # action_update_iot_info 内部会跳过 iot_sync 上下文,这里显式传 False 确保推送 + bindings.with_context(iot_sync=False).action_update_iot_info() + # 在每位员工的消息面板(花名册 form 右侧 chatter)生成同步日志 + # hr.employee 继承 mail.thread,可直接 message_post;用内部备注子类型,不触发邮件 + for employee in self: + emp_bindings = bindings.filtered(lambda b: b.employee_id == employee) + iot_names = '、'.join(emp_bindings.mapped('attendance_iot_id.name')) or _('(无)') + employee.message_post( + body=_('考勤机记录已同步到关联的全部设备:%s') % iot_names, + subtype_xmlid='mail.mt_note', + ) + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': '同步完成', + 'message': _('已向 %s 名员工关联的全部设备推送同步指令') % len(self), + 'sticky': False, + 'type': 'success', + } + }