Skip to content

Commit

Permalink
[IMP] hr_holidays_natural_period: exclude public holidays in natural …
Browse files Browse the repository at this point in the history
…days computation
  • Loading branch information
LauraCForgeFlow committed Nov 14, 2024
1 parent 757cdef commit 1768a5f
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 11 deletions.
2 changes: 2 additions & 0 deletions hr_holidays_natural_period/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ For using natural period on leaves:
#. If no leave type is yet specified, then default configuration is to exclude
public holidays.
#. The number of days will be computed without employee calendar used.
#. The computation can exclude public holidays or not, depending on the configuration
of the leave type.

Bug Tracker
===========
Expand Down
3 changes: 2 additions & 1 deletion hr_holidays_natural_period/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"author": "Tecnativa, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["hr_holidays"],
"depends": ["hr_holidays_public"],
"maintainers": ["victoralmau"],
"demo": ["demo/hr_leave_type_data.xml"],
"data": ["views/hr_leave_views.xml"],
}
1 change: 1 addition & 0 deletions hr_holidays_natural_period/demo/hr_leave_type_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<field name="request_unit">natural_day</field>
<field name="responsible_id" ref="base.user_admin" />
<field name="employee_requests">yes</field>
<field name="exclude_public_holidays">False</field>
</record>
</odoo>
8 changes: 5 additions & 3 deletions hr_holidays_natural_period/models/resource_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ def _attendance_intervals_batch(
start_dt=start_dt, end_dt=end_dt, resources=resources, domain=domain, tz=tz
)
if self.env.context.get("natural_period"):
return self._natural_period_intervals_batch(
start_dt, end_dt, res, resources
)
res = self._natural_period_intervals_batch(start_dt, end_dt, res, resources)
if self.env.context.get("exclude_public_holidays") and resources:
return self._attendance_intervals_batch_exclude_public_holidays(
start_dt, end_dt, res, resources, tz
)
return res
2 changes: 2 additions & 0 deletions hr_holidays_natural_period/readme/USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ For using natural period on leaves:
#. If no leave type is yet specified, then default configuration is to exclude
public holidays.
#. The number of days will be computed without employee calendar used.
#. The computation can exclude public holidays or not, depending on the configuration
of the leave type.
2 changes: 2 additions & 0 deletions hr_holidays_natural_period/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<li>If no leave type is yet specified, then default configuration is to exclude
public holidays.</li>
<li>The number of days will be computed without employee calendar used.</li>
<li>The computation can exclude public holidays or not, depending on the configuration
of the leave type.</li>
</ol>
</div>
<div class="section" id="bug-tracker">
Expand Down
113 changes: 106 additions & 7 deletions hr_holidays_natural_period/tests/test_hr_leave.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ def setUpClass(cls):
"user_id": cls.user.id,
}
)
cls.public_holiday = cls.env["hr.holidays.public"].create(
{
"year": 2023,
"country_id": False,
}
)

def _create_leave_allocation(self, leave_type, days):
leave_allocation_form = Form(
Expand All @@ -76,21 +82,114 @@ def _create_hr_leave(self, leave_type, date_from, date_to):
leave_form.request_date_to = date_to
return leave_form.save()

def _create_public_holiday_line(self, name, date, year):
public_holiday_line = Form(self.env["hr.holidays.public.line"].sudo())
public_holiday_line.name = name
public_holiday_line.date = date
public_holiday_line.year_id = year
return public_holiday_line.save()

@users("test-user")
def test_hr_leave_natural_day(self):
leave_allocation = self._create_leave_allocation(self.leave_type, 5)
leave_allocation = self._create_leave_allocation(self.leave_type, 10)
leave_allocation.action_confirm()
leave_allocation.sudo().action_validate()
res_leave_type = self.env["hr.leave.type"].get_days_all_request()[0][1]
self.assertEqual(res_leave_type["remaining_leaves"], "5")
self.assertEqual(res_leave_type["virtual_remaining_leaves"], "5")
self.assertEqual(res_leave_type["max_leaves"], "5")
self.assertEqual(res_leave_type["remaining_leaves"], "10")
self.assertEqual(res_leave_type["virtual_remaining_leaves"], "10")
self.assertEqual(res_leave_type["max_leaves"], "10")
self.assertEqual(res_leave_type["leaves_taken"], "0")
self.assertEqual(res_leave_type["virtual_leaves_taken"], "0")
self.assertEqual(res_leave_type["request_unit"], "natural_day")
leave = self._create_hr_leave(self.leave_type, "2023-01-08", "2023-01-15")
self.assertEqual(leave.number_of_days, 8)
self.assertEqual(leave.number_of_days_display, 8)

@users("test-user")
def test_hr_leave_natural_day_public_holiday_01(self):
leave_allocation = self._create_leave_allocation(self.leave_type, 10)
leave_allocation.action_confirm()
leave_allocation.sudo().action_validate()
self._create_public_holiday_line(
"Public holiday 1", "2023-01-09", self.public_holiday
)

res_leave_type = self.env["hr.leave.type"].get_days_all_request()[0][1]
self.assertEqual(res_leave_type["remaining_leaves"], "10")
self.assertEqual(res_leave_type["virtual_remaining_leaves"], "10")
self.assertEqual(res_leave_type["max_leaves"], "10")
self.assertEqual(res_leave_type["leaves_taken"], "0")
self.assertEqual(res_leave_type["virtual_leaves_taken"], "0")
self.assertEqual(res_leave_type["request_unit"], "natural_day")
self.assertEqual(self.leave_type.exclude_public_holidays, False)
leave = self._create_hr_leave(self.leave_type, "2023-01-08", "2023-01-15")
self.assertEqual(leave.number_of_days, 8)
self.assertEqual(leave.number_of_days_display, 8)

@users("test-user")
def test_hr_leave_natural_day_public_holiday_02(self):
leave_allocation = self._create_leave_allocation(self.leave_type, 10)
leave_allocation.action_confirm()
leave_allocation.sudo().action_validate()
self._create_public_holiday_line(
"Public holiday 1", "2023-01-09", self.public_holiday
)
self.leave_type.write({"exclude_public_holidays": True})

res_leave_type = self.env["hr.leave.type"].get_days_all_request()[0][1]
self.assertEqual(res_leave_type["remaining_leaves"], "10")
self.assertEqual(res_leave_type["virtual_remaining_leaves"], "10")
self.assertEqual(res_leave_type["max_leaves"], "10")
self.assertEqual(res_leave_type["leaves_taken"], "0")
self.assertEqual(res_leave_type["virtual_leaves_taken"], "0")
self.assertEqual(res_leave_type["request_unit"], "natural_day")
self.assertEqual(self.leave_type.exclude_public_holidays, True)
leave = self._create_hr_leave(self.leave_type, "2023-01-08", "2023-01-15")
self.assertEqual(leave.number_of_days, 7)
self.assertEqual(leave.number_of_days_display, 7)

@users("test-user")
def test_hr_leave_natural_day_public_holiday_weekend_01(self):
leave_allocation = self._create_leave_allocation(self.leave_type, 10)
leave_allocation.action_confirm()
leave_allocation.sudo().action_validate()
self._create_public_holiday_line(
"Public holiday 1", "2023-01-14", self.public_holiday
)

res_leave_type = self.env["hr.leave.type"].get_days_all_request()[0][1]
self.assertEqual(res_leave_type["remaining_leaves"], "10")
self.assertEqual(res_leave_type["virtual_remaining_leaves"], "10")
self.assertEqual(res_leave_type["max_leaves"], "10")
self.assertEqual(res_leave_type["leaves_taken"], "0")
self.assertEqual(res_leave_type["virtual_leaves_taken"], "0")
self.assertEqual(res_leave_type["request_unit"], "natural_day")
self.assertEqual(self.leave_type.exclude_public_holidays, False)
leave = self._create_hr_leave(self.leave_type, "2023-01-08", "2023-01-15")
self.assertEqual(leave.number_of_days, 8)
self.assertEqual(leave.number_of_days_display, 8)

@users("test-user")
def test_hr_leave_natural_day_public_holiday_weekend_02(self):
leave_allocation = self._create_leave_allocation(self.leave_type, 10)
leave_allocation.action_confirm()
leave_allocation.sudo().action_validate()
self._create_public_holiday_line(
"Public holiday 1", "2023-01-14", self.public_holiday
)
self.leave_type.write({"exclude_public_holidays": True})

res_leave_type = self.env["hr.leave.type"].get_days_all_request()[0][1]
self.assertEqual(res_leave_type["remaining_leaves"], "10")
self.assertEqual(res_leave_type["virtual_remaining_leaves"], "10")
self.assertEqual(res_leave_type["max_leaves"], "10")
self.assertEqual(res_leave_type["leaves_taken"], "0")
self.assertEqual(res_leave_type["virtual_leaves_taken"], "0")
self.assertEqual(res_leave_type["request_unit"], "natural_day")
leave = self._create_hr_leave(self.leave_type, "2023-01-02", "2023-01-05")
self.assertEqual(leave.number_of_days, 4.0)
self.assertEqual(leave.number_of_days_display, 4.0)
self.assertEqual(self.leave_type.exclude_public_holidays, True)
leave = self._create_hr_leave(self.leave_type, "2023-01-08", "2023-01-15")
self.assertEqual(leave.number_of_days, 7)
self.assertEqual(leave.number_of_days_display, 7)

@users("test-user")
def test_hr_leave_day(self):
Expand Down
27 changes: 27 additions & 0 deletions hr_holidays_natural_period/views/hr_leave_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>

<record id="hr_leave_view_form" model="ir.ui.view">
<field name="name">hr.leave.view.form</field>
<field name="model">hr.leave</field>
<field name="inherit_id" ref="hr_holidays.hr_leave_view_form" />
<field name="arch" type="xml">
<xpath expr="//label[@for='request_unit_half']" position="attributes">
<attribute
name="attrs"
>{'invisible': [('leave_type_request_unit', 'in', ['day', 'natural_day'])]}</attribute>
</xpath>
<xpath expr="//field[@name='request_unit_half']" position="attributes">
<attribute
name="attrs"
>{'readonly': [('state', 'not in', ('draft', 'confirm'))], 'invisible': [('leave_type_request_unit', 'in', ['day', 'natural_day'])]}</attribute>
</xpath>
<xpath expr="//div[field[@name='request_unit_half']]" position="attributes">
<attribute
name="attrs"
>{'invisible': [('leave_type_request_unit', 'in', ['day', 'natural_day'])]}</attribute>
</xpath>
</field>
</record>

</odoo>

0 comments on commit 1768a5f

Please sign in to comment.