diff --git a/hr_attendance_manage_own/models/hr_attendance.py b/hr_attendance_manage_own/models/hr_attendance.py index 5269fbe..c063cf5 100644 --- a/hr_attendance_manage_own/models/hr_attendance.py +++ b/hr_attendance_manage_own/models/hr_attendance.py @@ -37,11 +37,25 @@ def _check_overtime_status(self): _("You are not allowed to change the overtime status.") ) + def _get_write_bypass_fields(self): + param = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("hr_attendance_manage_own.write_bypass_fields", "") + ) + return {f.strip() for f in param.split(",") if f.strip()} + def write(self, vals): if not self._is_own_manager_only(): return super().write(vals) if self._is_attendance_manager_for_employees(self.employee_id): return super().write(vals) + # Strip validated_overtime_hours so the compute determines its value. + # The form client may include it in the payload when saving. + vals = {k: v for k, v in vals.items() if k != "validated_overtime_hours"} + bypass_fields = self._get_write_bypass_fields() + if not set(vals.keys()) - bypass_fields: + return super().write(vals) if self.filtered(lambda r: r._is_processed()): raise AccessError( _( @@ -49,9 +63,6 @@ def write(self, vals): "been processed (approved or refused)." ) ) - # Strip validated_overtime_hours so the compute determines its value. - # The form client may include it in the payload when saving. - vals = {k: v for k, v in vals.items() if k != "validated_overtime_hours"} return super().write(vals) @api.ondelete(at_uninstall=False) diff --git a/hr_attendance_manage_own/readme/CONFIGURE.md b/hr_attendance_manage_own/readme/CONFIGURE.md index 981286f..60faba0 100644 --- a/hr_attendance_manage_own/readme/CONFIGURE.md +++ b/hr_attendance_manage_own/readme/CONFIGURE.md @@ -3,3 +3,12 @@ To configure this module: 1. Go to *Settings \> Users & Companies \> Groups* 2. Find and select the "User: Manage own attendances" group 3. Add users to this group to allow them to create and edit their own attendance records + +Optionally, you can configure fields that bypass the processed-record write +restriction. This is useful when other modules (e.g. `hr_timesheet_sheet`) need +to write certain fields on attendance records that have already been approved or +refused. + +1. Go to *Settings \> Technical \> Parameters \> System Parameters* +2. Create a parameter with key `hr_attendance_manage_own.write_bypass_fields` +3. Set the value to a comma-separated list of field names (e.g. `sheet_id`) diff --git a/hr_attendance_manage_own/tests/test_hr_attendance_manage_own.py b/hr_attendance_manage_own/tests/test_hr_attendance_manage_own.py index c5ff69f..71456cc 100644 --- a/hr_attendance_manage_own/tests/test_hr_attendance_manage_own.py +++ b/hr_attendance_manage_own/tests/test_hr_attendance_manage_own.py @@ -187,6 +187,18 @@ def test_full_manager_bypass(self): self.attendance.with_user(manager_user).action_approve_overtime() self.assertEqual(self.attendance.overtime_status, "approved") + def test_write_bypass_fields_on_processed(self): + self.user.groups_id = [Command.link(self.own_manager_group.id)] + self.attendance.overtime_status = "approved" + self.env["ir.config_parameter"].set_param( + "hr_attendance_manage_own.write_bypass_fields", "check_in" + ) + self.attendance.with_user(self.user).write({"check_in": "2026-02-26 09:00:00"}) + with self.assertRaises(AccessError): + self.attendance.with_user(self.user).write( + {"check_in": "2026-02-26 11:00:00", "check_out": "2026-02-26 18:00:00"} + ) + def test_attendance_manager_bypass(self): officer_user = self.env["res.users"].create( {