19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-25 12:00:11 +01:00
parent e1d89e11e3
commit a1f02d8cc7
225 changed files with 2335 additions and 775 deletions

View file

@ -182,8 +182,8 @@ class HrAttendance(models.Model):
calendar = self._get_employee_calendar()
resource = self.employee_id.resource_id
tz = timezone(resource.tz) if not calendar else timezone(calendar.tz)
start_dt_tz = max(self.check_in, start_dt).astimezone(tz)
end_dt_tz = min(self.check_out, end_dt).astimezone(tz)
start_dt_tz = utc.localize(max(self.check_in, start_dt)).astimezone(tz)
end_dt_tz = utc.localize(min(self.check_out, end_dt)).astimezone(tz)
if end_dt_tz < start_dt_tz:
return 0.0
@ -268,11 +268,19 @@ class HrAttendance(models.Model):
def _get_overtimes_to_update_domain(self):
if not self:
return Domain.FALSE
domain_list = [Domain.AND([
Domain('employee_id', '=', employee.id),
Domain('date', '<=', max(attendances.mapped('check_out')).date() + relativedelta(SU)),
Domain('date', '>=', min(attendances.mapped('check_in')).date() + relativedelta(MO(-1))),
]) for employee, attendances in self.filtered(lambda att: att.check_out).grouped('employee_id').items()]
domain_list = []
for employee, attendances in self.filtered(lambda att: att.check_out).grouped('employee_id').items():
tz = timezone(employee._get_tz())
local_check_in = utc.localize(min(attendances.mapped('check_in'))).astimezone(tz)
local_check_out = utc.localize(max(attendances.mapped('check_out'))).astimezone(tz)
date_from = local_check_in.date() + relativedelta(weekday=MO(-1))
date_to = local_check_out.date() + relativedelta(weekday=SU)
domain_list.append(Domain.AND([
Domain('employee_id', '=', employee.id),
Domain('date', '<=', date_to),
Domain('date', '>=', date_from),
]))
if not domain_list:
return Domain.FALSE
return Domain.OR(domain_list) if len(domain_list) > 1 else domain_list[0]
@ -280,7 +288,11 @@ class HrAttendance(models.Model):
def _update_overtime(self, attendance_domain=None):
if not attendance_domain:
attendance_domain = self._get_overtimes_to_update_domain()
self.env['hr.attendance.overtime.line'].search(attendance_domain).unlink()
all_overtime_lines = self.env['hr.attendance.overtime.line'].search(attendance_domain)
manual_overtimes = set(all_overtime_lines.filtered(
lambda l: l.manual_duration != l.duration or l.status == 'to_approve'
).mapped(lambda l: (l.employee_id.id, l.date)))
all_overtime_lines.unlink()
all_attendances = (self | self.env['hr.attendance'].search(attendance_domain)).filtered_domain([('check_out', '!=', False)])
if not all_attendances:
return
@ -305,9 +317,13 @@ class HrAttendance(models.Model):
overtime_vals_list = []
for ruleset_sudo, ruleset_attendances in attendances_by_ruleset.items():
attendances_dates = list(chain(*ruleset_attendances._get_dates().values()))
overtime_vals_list.extend(
ruleset_sudo.rule_ids._generate_overtime_vals_v2(min(attendances_dates), max(attendances_dates), ruleset_attendances, schedules_intervals_by_employee)
)
overtime_vals_list.extend([
{
**val,
'status': 'to_approve'
} if (val['employee_id'], val['date']) in manual_overtimes else val
for val in ruleset_sudo.rule_ids._generate_overtime_vals_v2(min(attendances_dates), max(attendances_dates), ruleset_attendances, schedules_intervals_by_employee)
])
self.env['hr.attendance.overtime.line'].create(overtime_vals_list)
self.env.add_to_compute(self._fields['overtime_hours'], all_attendances)
self.env.add_to_compute(self._fields['validated_overtime_hours'], all_attendances)