-
-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
301 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
**This file is going to be generated by oca-gen-addon-readme.** | ||
|
||
*Manual changes will be overwritten.* | ||
|
||
Please provide content in the ``readme`` directory: | ||
|
||
* **DESCRIPTION.rst** (required) | ||
* INSTALL.rst (optional) | ||
* CONFIGURE.rst (optional) | ||
* **USAGE.rst** (optional, highly recommended) | ||
* DEVELOP.rst (optional) | ||
* ROADMAP.rst (optional) | ||
* HISTORY.rst (optional, recommended) | ||
* **CONTRIBUTORS.rst** (optional, highly recommended) | ||
* CREDITS.rst (optional) | ||
|
||
Content of this README will also be drawn from the addon manifest, | ||
from keys such as name, authors, maintainers, development_status, | ||
and license. | ||
|
||
A good, one sentence summary in the manifest is also highly recommended. | ||
|
||
|
||
Automatic changelog generation | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
`HISTORY.rst` can be auto generated using `towncrier <https://pypi.org/project/towncrier>`_. | ||
|
||
Just put towncrier compatible changelog fragments into `readme/newsfragments` | ||
and the changelog file will be automatically generated and updated when a new fragment is added. | ||
|
||
Please refer to `towncrier` documentation to know more. | ||
|
||
NOTE: the changelog will be automatically generated when using `/ocabot merge $option`. | ||
If you need to run it manually, refer to `OCA/maintainer-tools README <https://github.com/OCA/maintainer-tools>`_. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Copyright 2023 Hunki Enterprises BV | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0) | ||
|
||
{ | ||
"name": "Overlapping leaves", | ||
"summary": "Allows to configure holidays that overlap with others", | ||
"version": "15.0.1.0.0", | ||
"development_status": "Beta", | ||
"category": "Human Resources/Time Off", | ||
"website": "https://github.com/OCA/hr-holidays", | ||
"author": "Hunki Enterprises BV, Odoo Community Association (OCA)", | ||
"maintainers": ["hbrunn"], | ||
"license": "AGPL-3", | ||
"depends": [ | ||
"hr_holidays", | ||
], | ||
"data": [ | ||
"data/hr_leave_type.xml", | ||
"views/hr_leave_type.xml", | ||
], | ||
"demo": [], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<!-- Copyright 2023 Hunki Enterprises BV | ||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0) --> | ||
<data> | ||
<record id="hr_holidays.holiday_status_sl" model="hr.leave.type"> | ||
<field name="can_overlap" eval="True" /> | ||
</record> | ||
</data> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import hr_leave | ||
from . import hr_leave_type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Copyright 2023 Hunki Enterprises BV | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0) | ||
|
||
|
||
from odoo import api, models | ||
|
||
exclude_sentinel = object() | ||
|
||
|
||
class HrLeave(models.Model): | ||
_inherit = "hr.leave" | ||
|
||
@api.constrains("date_from", "date_to", "employee_id") | ||
def _check_date(self): | ||
"""Allow overlapping if the holiday type allows it""" | ||
return super( | ||
HrLeave, | ||
self.with_context(hr_holidays_overlap_exclude=exclude_sentinel).filtered( | ||
lambda x: not x.holiday_status_id.can_overlap | ||
), | ||
)._check_date() | ||
|
||
@api.model | ||
def search_count(self, args): | ||
"""Inject condition to exclude leaves whose type allows overlaps if asked so""" | ||
if self.env.context.get("hr_holidays_overlap_exclude") == exclude_sentinel: | ||
args += [("holiday_status_id.can_overlap", "=", False)] | ||
return super().search_count(args) | ||
|
||
def _get_leaves_on_public_holiday(self): | ||
"""Don't count leaves with a type that allows overlap""" | ||
return ( | ||
super() | ||
._get_leaves_on_public_holiday() | ||
.filtered(lambda x: not x.holiday_status_id.can_overlap) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Copyright 2023 Hunki Enterprises BV | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0) | ||
|
||
|
||
from odoo import fields, models | ||
|
||
|
||
class HrLeaveType(models.Model): | ||
_inherit = "hr.leave.type" | ||
|
||
can_overlap = fields.Boolean("Allow overlap with other leaves") | ||
|
||
def _get_employees_days_per_allocation(self, employee_ids, date=None): | ||
"""Remove overlapping days""" | ||
HrLeave = self.env["hr.leave"] | ||
|
||
result = super()._get_employees_days_per_allocation(employee_ids, date=date) | ||
|
||
if not date: | ||
date = fields.Date.to_date( | ||
self.env.context.get("default_date_from") | ||
) or fields.Date.context_today(self) | ||
|
||
for employee_id in employee_ids: | ||
for possible_overlap in HrLeave.search( | ||
[ | ||
("employee_id", "=", employee_id), | ||
("state", "not in", ("draft", "refuse")), | ||
("holiday_status_id.can_overlap", "=", True), | ||
] | ||
): | ||
for overlap in HrLeave.search( | ||
[ | ||
("employee_id", "=", employee_id), | ||
("state", "not in", ("draft", "refuse")), | ||
("id", "not in", possible_overlap.ids), | ||
("date_from", "<", possible_overlap.date_to), | ||
("date_to", ">", possible_overlap.date_from), | ||
("holiday_status_id", "in", self.ids), | ||
] | ||
): | ||
allocation_dict = result[employee_id][overlap.holiday_status_id] | ||
number_of_days = overlap.employee_id._get_work_days_data_batch( | ||
possible_overlap.date_from | ||
if possible_overlap.date_from >= overlap.date_from | ||
else overlap.date_from, | ||
possible_overlap.date_to | ||
if possible_overlap.date_to <= overlap.date_to | ||
else overlap.date_to, | ||
compute_leaves=False, | ||
)[employee_id]["days"] | ||
for allocation, allocation_days in allocation_dict.items(): | ||
if ( | ||
allocation | ||
and allocation.date_to | ||
and ( | ||
allocation.date_to < date or allocation.date_from > date | ||
) | ||
): | ||
continue | ||
allocation_days["virtual_remaining_leaves"] += number_of_days | ||
allocation_days["virtual_leaves_taken"] -= number_of_days | ||
allocation_days["remaining_leaves"] += number_of_days | ||
allocation_days["leaves_taken"] -= number_of_days | ||
break | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
To configure this module, you need to: | ||
|
||
1. Go to _Time Off / Configuration / Time Off Types_ | ||
2. Open a type you want to allow to overlap with other types | ||
3. Check the box _Allow overlap with other leaves_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
This module was developed because standard Odoo does not allow overlapping leaves. | ||
|
||
For legislations where being sick during vacation counts as sick day and not a vacation | ||
day, you'd have to cancel the original vacation, and recreate sick leaves / vacation | ||
leaves as necessary. | ||
|
||
With this module, you can simply allow overlapping for sick leaves, and add the sick | ||
leave on top of the vacation leave. This will also deduct the sick days taken from the | ||
vacation days taken. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
- Holger Brunn <[email protected]> (https://hunki-enterprises.com) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!-- | ||
Audience: everybody. | ||
Purpose: thank financial contributors. | ||
⚠️ Cautions: | ||
- DO NOT include contributors. These go into ./CONTRIBUTORS.rst. | ||
- DO NOT include authors. These go in the "author" key in ../__manifest__.py. | ||
- DO NOT include maintainers. These go in the "maintainers" key in ../__manifest__.py. | ||
- Only include other companies or persons that have financed the development | ||
of this module. Maybe through direct funding, crowdfunding, etc. | ||
⛔ REMOVE THIS FILE if there are no other financial supporters. | ||
--> | ||
|
||
The development of this module has been financially supported by: | ||
|
||
- Company 1 name | ||
- Company 2 name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This module makes it possible to have overlapping leaves. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
To use this module, you need to: | ||
|
||
1. Go to the Time Off app | ||
2. Create and approve a paid leave | ||
3. Note that you can create a sick leave for the same employee in the same interval |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import test_hr_holidays_overlap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Copyright 2023 Hunki Enterprises BV | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0) | ||
|
||
|
||
from datetime import timedelta | ||
|
||
from odoo.exceptions import ValidationError | ||
from odoo.tests.common import TransactionCase | ||
|
||
|
||
class TestHrHolidaysOverlap(TransactionCase): | ||
def setUp(self): | ||
super().setUp() | ||
# add our leave after the existing demo sick leave to avoid | ||
# unintended overlaps | ||
demo_sick_leave = self.env.ref("hr_holidays.hr_holidays_cl_qdp") | ||
self.paid_leave = demo_sick_leave.copy( | ||
default={ | ||
"name": "Paid leave", | ||
"state": "confirm", | ||
"holiday_status_id": self.env.ref("hr_holidays.holiday_status_cl").id, | ||
# those two are needed to circumvent hr.leave#copy_data's check | ||
"date_from": demo_sick_leave.date_to, | ||
"date_to": demo_sick_leave.date_to + timedelta(days=2), | ||
} | ||
) | ||
self.paid_leave.action_approve() | ||
self.paid_leave.action_validate() | ||
|
||
def test_overlap(self): | ||
"""Test that sick leaves may overlap paid leaves and deducts amounts""" | ||
sick_leave = self.paid_leave.copy( | ||
default={ | ||
"name": "Sick leave", | ||
"state": "confirm", | ||
"holiday_status_id": self.env.ref("hr_holidays.holiday_status_sl").id, | ||
"date_from": self.paid_leave.date_from, | ||
"date_to": self.paid_leave.date_from + timedelta(days=1), | ||
} | ||
) | ||
sick_leave.action_validate() | ||
paid_leave = self.paid_leave.with_context( | ||
employee_id=self.paid_leave.employee_id.id | ||
) | ||
# allocation is 20, with 2 days of paid leave it was 18, adding the sick day makes it 19 | ||
self.assertEqual( | ||
paid_leave.holiday_status_id.remaining_leaves, | ||
19, | ||
) | ||
|
||
def test_no_overlap(self): | ||
"""Test that we still don't allow overlapping for types not configured accordingly""" | ||
with self.assertRaisesRegex( | ||
ValidationError, "You can not set 2 time off that overlaps" | ||
): | ||
self.paid_leave.copy( | ||
default={ | ||
"state": "confirm", | ||
"holiday_status_id": self.env.ref( | ||
"hr_holidays.holiday_status_unpaid" | ||
).id, | ||
"date_from": self.paid_leave.date_from, | ||
"date_to": self.paid_leave.date_to, | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<!-- Copyright 2023 Hunki Enterprises BV | ||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0) --> | ||
<data> | ||
<record id="edit_holiday_status_form" model="ir.ui.view"> | ||
<field name="model">hr.leave.type</field> | ||
<field name="inherit_id" ref="hr_holidays.edit_holiday_status_form" /> | ||
<field name="arch" type="xml"> | ||
<field name="time_type" position="after"> | ||
<field | ||
name="can_overlap" | ||
attrs="{'invisible': [('time_type', '!=', 'leave')]}" | ||
/> | ||
</field> | ||
</field> | ||
</record> | ||
</data> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../hr_holidays_overlap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import setuptools | ||
|
||
setuptools.setup( | ||
setup_requires=['setuptools-odoo'], | ||
odoo_addon=True, | ||
) |