oca-technical/odoo-bringout-oca-hr-attendance-hr_attendance_autoclose/hr_attendance_autoclose/models/hr_attendance.py
2025-08-29 15:43:03 +02:00

57 lines
2.1 KiB
Python

# Copyright 2018 ForgeFlow, S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from datetime import datetime, timedelta
from odoo import api, fields, models
class HrAttendance(models.Model):
_inherit = "hr.attendance"
open_worked_hours = fields.Float(
string="Worked hours",
compute="_compute_open_worked_hours",
)
@api.depends("check_out", "check_in")
def _compute_open_worked_hours(self):
for item in self:
item_from = item.check_out if item.check_out else datetime.now()
delta = item_from - item.check_in
item.open_worked_hours = delta.total_seconds() / 3600.0
def autoclose_attendance(self, reason):
self.ensure_one()
max_hours = self.employee_id.company_id.attendance_maximum_hours_per_day
leave_time = self.check_in + timedelta(hours=max_hours)
vals = {"check_out": leave_time}
if reason:
vals["attendance_reason_ids"] = [(4, reason.id)]
self.write(vals)
def needs_autoclose(self):
self.ensure_one()
max_hours = self.employee_id.company_id.attendance_maximum_hours_per_day
close = not self.employee_id.no_autoclose
return close and max_hours and self.open_worked_hours > max_hours
@api.model
def check_for_incomplete_attendances(self):
stale_attendances = self.search([("check_out", "=", False)])
reason = self.env.company.hr_attendance_autoclose_reason
for att in stale_attendances.filtered(lambda a: a.needs_autoclose()):
att.autoclose_attendance(reason)
@api.constrains("check_in", "check_out", "employee_id")
def _check_validity(self):
"""If this is an automatic checkout the constraint is invalid
as there may be old attendances not closed
"""
reason = self.env.company.hr_attendance_autoclose_reason
if reason and self.filtered(
lambda att: att.attendance_reason_ids
and reason in att.attendance_reason_ids
):
return True
return super()._check_validity()