Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions hr_attendance_manage_own/models/hr_attendance.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,32 @@ 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(
_(
"You cannot modify attendance records that have already "
"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)
Expand Down
9 changes: 9 additions & 0 deletions hr_attendance_manage_own/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
12 changes: 12 additions & 0 deletions hr_attendance_manage_own/tests/test_hr_attendance_manage_own.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand Down
Loading