[FIX]hr_employee_stats_sheet:fix identification of public holidays according to employee TZ
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import logging
|
||||
import pytz
|
||||
|
||||
from odoo import api, fields, models
|
||||
from datetime import timedelta
|
||||
from pytz import utc
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -169,8 +171,40 @@ class HrEmployeeStats(models.Model):
|
||||
stat.is_public_holiday = False
|
||||
continue
|
||||
stat.dayofweek = int(stat.date.strftime("%u")) - 1
|
||||
stat.is_public_holiday = bool(stat.sheet_id.employee_id._get_public_holidays(stat.date, stat.date - timedelta(days=1)))
|
||||
stat.is_public_holiday = stat._is_public_holiday_accordig_to_employe_tz()
|
||||
|
||||
def _convert_to_employee_tz(self, date):
|
||||
"""Convert a UTC datetime to the employee's timezone datetime."""
|
||||
self.ensure_one()
|
||||
if not date:
|
||||
return None
|
||||
employee_tz = pytz.timezone(self.employee_id.tz or "UTC")
|
||||
if date.tzinfo is None:
|
||||
dt = pytz.utc.localize(date)
|
||||
return dt.astimezone(employee_tz)
|
||||
|
||||
def _is_public_holiday_accordig_to_employe_tz(self):
|
||||
self.ensure_one()
|
||||
if not self.date or not self.employee_id:
|
||||
return False
|
||||
#get public holidays for the employee
|
||||
public_holidays = self.employee_id._get_public_holidays(
|
||||
self.date, self.date
|
||||
)
|
||||
if not public_holidays:
|
||||
return False
|
||||
ph = public_holidays[0]
|
||||
# Convert public holiday to the employee timezone
|
||||
ph_datetime_from_tz = self._convert_to_employee_tz(ph.date_from)
|
||||
ph_datetime_to_tz = self._convert_to_employee_tz(ph.date_to)
|
||||
# Convert datetime to date
|
||||
ph_date_from = ph_datetime_from_tz.date()
|
||||
ph_date_to = ph_datetime_to_tz.date()
|
||||
# Check if the stat date falls within the public holiday range after conversion in employee tz
|
||||
if ph_date_from <= self.date <= ph_date_to:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def _get_gap_hours(self, total_hours, total_recovery_hours, total_leave_hours, total_planned_hours):
|
||||
self.ensure_one()
|
||||
balance = (
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tests import tagged
|
||||
from datetime import date, timedelta
|
||||
from datetime import date, timedelta, datetime
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.fields import Date
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestHrEmployeeStatsRecovery(TransactionCase):
|
||||
@@ -19,6 +20,7 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
|
||||
self.employee = self.env['hr.employee'].create({
|
||||
'name': 'Camille',
|
||||
'user_id': self.user.id,
|
||||
'tz': 'Europe/Paris',
|
||||
})
|
||||
self.base_calendar = self.env['resource.calendar'].create({
|
||||
'name': 'Default Calendar',
|
||||
@@ -242,6 +244,33 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
|
||||
recovery_allocation = self.env["hr.leave.allocation"].search([("timesheet_sheet_id","=",timesheet_sheet_2.id)])
|
||||
self.assertEqual(len(recovery_allocation), 1, "There should be one recovery")
|
||||
|
||||
def test_public_holiday(self):
|
||||
# create a public holiday
|
||||
self.env["resource.calendar.leaves"].create(
|
||||
{
|
||||
"name": "1 mai 2025",
|
||||
"date_from": datetime(2025,4,30,22,0,0),
|
||||
"date_to": datetime(2025,5,1,21,0,0),
|
||||
}
|
||||
)
|
||||
#create 5 stats of 7h each including the public holiday on 1st may
|
||||
stats = self._create_stats(Date.to_date("2025-04-28"), 5, 7)
|
||||
for stat in stats:
|
||||
stat._compute_dayofweek()
|
||||
stat._compute_hours()
|
||||
#create 1 timesheet sheet from monday to friday including the public holiday on 1st may
|
||||
timesheet_sheet = self.env['hr_timesheet.sheet'].create({
|
||||
'employee_id': self.employee.id,
|
||||
'date_start': "2025-04-28",
|
||||
'date_end': "2025-05-04",
|
||||
})
|
||||
self.assertEqual(timesheet_sheet.timesheet_sheet_gap_hours, 7, "timesheet_sheet_gap_hours should be 7",)
|
||||
self.assertEqual(timesheet_sheet.timesheet_sheet_recovery_hours, 8.75, "timesheet_sheet_recovery_hours should be 8,75",)
|
||||
|
||||
timesheet_sheet.action_generate_recovery_allocation()
|
||||
recovery_allocation = self.env["hr.leave.allocation"].search([("timesheet_sheet_id","=",timesheet_sheet.id)])
|
||||
self.assertEqual(len(recovery_allocation), 1, "Il doit y avoir une allocation de récupération générée")
|
||||
self.assertEqual(recovery_allocation.number_of_days,1.25, "The recovery allocation should be 1,25 days")
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user