fix(fusion_clock): stop stale missed-clock-in nag; add Owner role + attendance exemption
The "explain your missed clock-out" dialog (driven by hr.employee. x_fclk_pending_reason) was set by the absence + auto-clock-out crons but only cleared by the systray reason dialog -- never by the kiosk/NFC clock paths that staff actually use. During the kiosk rollout the absence cron flagged the whole company (hundreds of "absent" logs); those stale flags then nagged everyone forever, even while currently clocked in. Fixes: - Clear x_fclk_pending_reason on every successful clock-in (portal, systray, PIN kiosk, NFC kiosk). Back on the clock => no nag. - get_status / dashboard never report pending while checked-in or exempt; the systray also guards the dialog client-side. - Absence detection no longer sets x_fclk_pending_reason (an absence has no "departure time" to explain). It still logs 'absent' + notifies the office. - One-time migration (19.0.4.2.0) clears existing stale flags. Owner / attendance exemption: - New "Owner" role (top of the Fusion Clock access dropdown, implies Manager) plus a per-employee "Exempt from Attendance" checkbox. - hr.employee._fclk_is_attendance_exempt(); the absence, auto-clock-out, reminder and weekly-summary crons all skip exempt employees, and the dialog is suppressed for them. Tests: tests/test_pending_reason_exempt.py (13 cases). Full fusion_clock suite green except pre-existing env-sensitive failures. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,18 @@ class HrEmployee(models.Model):
|
||||
help="If set, employee must explain a missed clock-out before clocking in again.",
|
||||
)
|
||||
|
||||
# Attendance exemption (owners / anyone who works but is not "on the clock").
|
||||
# Exempt employees are skipped by absence detection, auto-clock-out and
|
||||
# reminders, and never see the missed-clock-out reason dialog.
|
||||
x_fclk_exempt_from_attendance = fields.Boolean(
|
||||
string='Exempt from Attendance Tracking',
|
||||
default=False,
|
||||
help="If set, this employee is never flagged absent, auto-clocked-out, "
|
||||
"reminded, or asked to explain a missed clock-out. Use for owners "
|
||||
"and others who work but are not on the clock. The Fusion Clock "
|
||||
"'Owner' role grants this automatically.",
|
||||
)
|
||||
|
||||
# Kiosk PIN
|
||||
x_fclk_kiosk_pin = fields.Char(
|
||||
string='Kiosk PIN',
|
||||
@@ -122,6 +134,19 @@ class HrEmployee(models.Model):
|
||||
help="Tracks the last date a reminder was sent to avoid duplicates.",
|
||||
)
|
||||
|
||||
def _fclk_is_attendance_exempt(self):
|
||||
"""True when this employee is exempt from attendance automation.
|
||||
|
||||
Exempt = the per-employee checkbox is set, OR the linked user holds the
|
||||
Fusion Clock 'Owner' role. Exempt employees are never flagged absent,
|
||||
auto-clocked-out, reminded, or shown the missed-clock-out reason dialog.
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.x_fclk_exempt_from_attendance:
|
||||
return True
|
||||
user = self.user_id
|
||||
return bool(user) and user.has_group('fusion_clock.group_fusion_clock_owner')
|
||||
|
||||
def _get_fclk_schedule_for_date(self, date):
|
||||
"""Return this employee's dated Fusion Clock schedule for a local date."""
|
||||
self.ensure_one()
|
||||
|
||||
Reference in New Issue
Block a user