Skip to content

Commit

Permalink
Merge pull request #104 from hbrunn/15.0-103-overtime_factor_sat_sun
Browse files Browse the repository at this point in the history
[ADD] #103 allow to configure holiday overtime for sat, sun, holidays
  • Loading branch information
albig authored Jan 29, 2024
2 parents 0f90651 + 850500d commit 5c28cb9
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 3 deletions.
30 changes: 28 additions & 2 deletions verdigado_attendance/models/hr_employee.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ class HrEmployee(models.Model):
help="When activated on holidays/weekends, overtime is multiplied with this factor",
groups="hr.group_hr_user",
)
holiday_overtime_holidays = fields.Boolean(
string="On Holidays", default=True, groups="hr.group_hr_user"
)
holiday_overtime_saturday = fields.Boolean(
string="On Saturdays", default=True, groups="hr.group_hr_user"
)
holiday_overtime_sunday = fields.Boolean(
string="On Sundays", default=True, groups="hr.group_hr_user"
)

def _get_effective_holiday_overtime_factor(self, date=None):
"""Return an employee's effective overtime factor for some date"""
Expand All @@ -27,15 +36,32 @@ def _get_effective_holiday_overtime_factor(self, date=None):
fields.Datetime.now(),
)[1]
)
weekday = date.isoweekday()
return (
(
self.custom_holiday_overtime_factor
and self.holiday_overtime_factor
or self.company_id.holiday_overtime_factor
)
if (
date.isoweekday() >= 6
or self.env["hr.holidays.public"].is_public_holiday(date, self.id)
self.custom_holiday_overtime_factor
and (
self.holiday_overtime_saturday
and weekday == 6
or self.holiday_overtime_sunday
and weekday == 7
or self.holiday_overtime_holidays
and self.env["hr.holidays.public"].is_public_holiday(date, self.id)
)
or not self.custom_holiday_overtime_factor
and (
self.company_id.holiday_overtime_saturday
and weekday == 6
or self.company_id.holiday_overtime_sunday
and weekday == 7
or self.company_id.holiday_overtime_holidays
and self.env["hr.holidays.public"].is_public_holiday(date, self.id)
)
)
else 1
)
Expand Down
3 changes: 3 additions & 0 deletions verdigado_attendance/models/res_company.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class ResCompany(models.Model):
default=1,
help="When activated on holidays/weekends, overtime is multiplied with this factor",
)
holiday_overtime_holidays = fields.Boolean(string="Holidays", default=True)
holiday_overtime_saturday = fields.Boolean(string="Saturdays", default=True)
holiday_overtime_sunday = fields.Boolean(string="Sundays", default=True)

def write(self, vals):
"""Don't delete overtime records that are adjustments when changing overtime settings"""
Expand Down
9 changes: 9 additions & 0 deletions verdigado_attendance/models/res_config_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,12 @@ class ResConfigSettings(models.TransientModel):
holiday_overtime_factor = fields.Float(
related="company_id.holiday_overtime_factor", readonly=False
)
holiday_overtime_holidays = fields.Boolean(
related="company_id.holiday_overtime_holidays", readonly=False
)
holiday_overtime_saturday = fields.Boolean(
related="company_id.holiday_overtime_saturday", readonly=False
)
holiday_overtime_sunday = fields.Boolean(
related="company_id.holiday_overtime_sunday", readonly=False
)
39 changes: 38 additions & 1 deletion verdigado_attendance/tests/test_overtime_calculation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ def setUpClass(cls):
"country_id": cls.env.ref("base.de").id,
}
).action_run()
cls.env["hr.holidays.public.generator"].create(
{
"year": 2024,
"country_id": cls.env.ref("base.de").id,
}
).action_run()
cls.employeeA.company_id.write(
{
# TODO: fix odoo's off-by-one error here in hr.attendance#_get_attendances_dates
Expand Down Expand Up @@ -160,6 +166,29 @@ def test_calculation_employeeA(self):
self.assertOvertime(employeeA, "2023-08-06", 0, 0)
self.assertOvertime(employeeA, "2023-08-06", 0, 0, adjustment=True)

# overtime on an excluded weekend day with a holiday
employeeA.holiday_overtime_saturday = False
self.record_time(
employeeA,
"2024-01-06",
"09:30:00",
"13:30:00",
apply_holiday_overtime_factor=True,
)
self.assertOvertime(employeeA, "2024-01-06", 4 * 60)
self.assertOvertime(employeeA, "2024-01-06", 1.5 * 4 * 60, adjustment=True)

# but no extra overtime on excluded weekend day without a holiday
self.record_time(
employeeA,
"2024-01-13",
"09:30:00",
"13:30:00",
apply_holiday_overtime_factor=True,
)
self.assertOvertime(employeeA, "2024-01-13", 4 * 60)
self.assertOvertime(employeeA, "2024-01-13", 0, adjustment=True)

def to_time(self, time_string):
if isinstance(time_string, str):
return datetime.strptime(time_string, "%H:%M:%S").time()
Expand All @@ -174,7 +203,14 @@ def local_date_to_utc_datetime(self, employee, date_string):
.replace(tzinfo=None)
)

def record_time(self, employee, date, checkin_time, checkout_time):
def record_time(
self,
employee,
date,
checkin_time,
checkout_time,
apply_holiday_overtime_factor=False,
):
date = fields.Date.to_date(date)
checkin_time = self.to_time(checkin_time)
checkout_time = self.to_time(checkout_time)
Expand All @@ -192,6 +228,7 @@ def record_time(self, employee, date, checkin_time, checkout_time):
"check_out": tz.localize(datetime.combine(date, checkout_time))
.astimezone(pytz.utc)
.replace(tzinfo=None),
"apply_holiday_overtime_factor": apply_holiday_overtime_factor,
}
)
)
Expand Down
12 changes: 12 additions & 0 deletions verdigado_attendance/views/hr_employee.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@
name="holiday_overtime_factor"
attrs="{'invisible': [('custom_holiday_overtime_factor', '=', False)]}"
/>
<field
name="holiday_overtime_holidays"
attrs="{'invisible': [('custom_holiday_overtime_factor', '=', False)]}"
/>
<field
name="holiday_overtime_saturday"
attrs="{'invisible': [('custom_holiday_overtime_factor', '=', False)]}"
/>
<field
name="holiday_overtime_sunday"
attrs="{'invisible': [('custom_holiday_overtime_factor', '=', False)]}"
/>
</field>
</field>
</record>
Expand Down
39 changes: 39 additions & 0 deletions verdigado_attendance/views/res_config_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,45 @@
</div>
</div>
</div>
<div class="row mt16 o_settings_container" name="break_settings">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="holiday_overtime_holidays" />
</div>
<div class="o_setting_right_pane">
<label for="holiday_overtime_holidays" />
<div class="text-muted">
Overtime factor is applied on holidays
</div>
</div>
</div>
</div>
<div class="row mt16 o_settings_container" name="break_settings">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="holiday_overtime_saturday" />
</div>
<div class="o_setting_right_pane">
<label for="holiday_overtime_saturday" />
<div class="text-muted">
Overtime factor is applied on Saturdays
</div>
</div>
</div>
</div>
<div class="row mt16 o_settings_container" name="break_settings">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="holiday_overtime_sunday" />
</div>
<div class="o_setting_right_pane">
<label for="holiday_overtime_sunday" />
<div class="text-muted">
Overtime factor is applied on Sundays
</div>
</div>
</div>
</div>
</div>
</field>
</record>
Expand Down

0 comments on commit 5c28cb9

Please sign in to comment.