From 2a93ece4ba54ecaa402a3e370c68cf97a9bb5332 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sun, 24 May 2026 13:34:45 -0400 Subject: [PATCH] feat(shopfloor): per-user 7-day tablet event smart button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Owner-only smart button on res.users form. Click opens the audit log filtered to that user (both user_id and attempted_user_id, so failed unlock attempts against a tile show up too). Compute is non-stored: search_count on the audit model per user on demand. Sudo'd because the audit model has Owner-only ACL — the compute fires for the form-viewing user (Owner) who would see the results anyway via the menu. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../models/res_users.py | 33 +++++++++++++++++++ .../views/res_users_views.xml | 26 +++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/fusion_plating/fusion_plating_shopfloor/models/res_users.py b/fusion_plating/fusion_plating_shopfloor/models/res_users.py index 61182f95..352f6ce3 100644 --- a/fusion_plating/fusion_plating_shopfloor/models/res_users.py +++ b/fusion_plating/fusion_plating_shopfloor/models/res_users.py @@ -140,6 +140,39 @@ class ResUsers(models.Model): 'target': 'new', } + x_fc_tablet_event_count_7d = fields.Integer( + string='Tablet Events (7d)', + compute='_compute_tablet_event_count_7d', + store=False, + ) + + def _compute_tablet_event_count_7d(self): + from datetime import timedelta + cutoff = fields.Datetime.now() - timedelta(days=7) + for user in self: + user.x_fc_tablet_event_count_7d = self.env[ + 'fp.tablet.session.event' + ].sudo().search_count([ + '|', + ('user_id', '=', user.id), + ('attempted_user_id', '=', user.id), + ('create_date', '>=', cutoff), + ]) + + def action_view_tablet_events(self): + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': _('Tablet Events: %s') % self.name, + 'res_model': 'fp.tablet.session.event', + 'view_mode': 'list,form', + 'domain': [ + '|', + ('user_id', '=', self.id), + ('attempted_user_id', '=', self.id), + ], + } + def _check_credentials(self, credential, env): """Custom auth manager: accept `type='fp_tablet_pin'` credential. diff --git a/fusion_plating/fusion_plating_shopfloor/views/res_users_views.xml b/fusion_plating/fusion_plating_shopfloor/views/res_users_views.xml index f5200f05..8543a071 100644 --- a/fusion_plating/fusion_plating_shopfloor/views/res_users_views.xml +++ b/fusion_plating/fusion_plating_shopfloor/views/res_users_views.xml @@ -55,4 +55,30 @@ + + + res.users.form.tablet.event.smart.button + res.users + + + + + + + +