Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][IMP] hr_holidays_natural_period: exclude public holidays in natural days computation #149

Open
wants to merge 1 commit into
base: 16.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
Loading