-
-
Notifications
You must be signed in to change notification settings - Fork 98
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
1 parent
44abe81
commit 32696bf
Showing
21 changed files
with
1,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,91 @@ | ||
======================== | ||
Calendar Holidays Public | ||
======================== | ||
|
||
.. | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! source digest: sha256:323fe101af3ba04c9322fb644c273896c1fb66484ed662a3ca0984279d457570 | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png | ||
:target: https://odoo-community.org/page/development-status | ||
:alt: Beta | ||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png | ||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html | ||
:alt: License: AGPL-3 | ||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fcalendar-lightgray.png?logo=github | ||
:target: https://github.com/OCA/calendar/tree/18.0/calendar_public_holiday | ||
:alt: OCA/calendar | ||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
:target: https://translation.odoo-community.org/projects/calendar-18-0/calendar-18-0-calendar_public_holiday | ||
:alt: Translate me on Weblate | ||
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png | ||
:target: https://runboat.odoo-community.org/builds?repo=OCA/calendar&target_branch=18.0 | ||
:alt: Try me on Runboat | ||
|
||
|badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
||
This module handles public holidays. | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Usage | ||
===== | ||
|
||
For adding public holidays: | ||
|
||
1. Go to the menu *Calendar > Public Holidays > Public Holidays*. | ||
2. Create your public holidays. | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/calendar/issues>`_. | ||
In case of trouble, please check there if your issue has already been reported. | ||
If you spotted it first, help us to smash it by providing a detailed and welcomed | ||
`feedback <https://github.com/OCA/calendar/issues/new?body=module:%20calendar_public_holiday%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Credits | ||
======= | ||
|
||
Authors | ||
------- | ||
|
||
* Camptocamp | ||
|
||
Contributors | ||
------------ | ||
|
||
- [Trobz](https://trobz.com): | ||
|
||
- Do Anh Duy <<duyda@trobz.com>> | ||
|
||
Other credits | ||
------------- | ||
|
||
The creation of this module was financially supported by Camptocamp | ||
|
||
Maintainers | ||
----------- | ||
|
||
This module is maintained by the OCA. | ||
|
||
.. image:: https://odoo-community.org/logo.png | ||
:alt: Odoo Community Association | ||
:target: https://odoo-community.org | ||
|
||
OCA, or the Odoo Community Association, is a nonprofit organization whose | ||
mission is to support the collaborative development of Odoo features and | ||
promote its widespread use. | ||
|
||
This module is part of the `OCA/calendar <https://github.com/OCA/calendar/tree/18.0/calendar_public_holiday>`_ project on GitHub. | ||
|
||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
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 models | ||
from . import wizards |
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,21 @@ | ||
# Copyright 2024 Camptocamp | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
{ | ||
"name": "Calendar Holidays Public", | ||
"summary": """ | ||
Manage Public Holidays | ||
""", | ||
"version": "18.0.1.0.0", | ||
"license": "AGPL-3", | ||
"category": "HR/Calendar", | ||
"author": "Camptocamp," "Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/calendar", | ||
"depends": ["calendar"], | ||
"data": [ | ||
"data/data.xml", | ||
"security/ir.model.access.csv", | ||
"views/calendar_public_holiday_view.xml", | ||
"wizards/calendar_public_holiday_next_year_wizard.xml", | ||
], | ||
} |
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 2024 Camptocamp | ||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).--> | ||
<odoo> | ||
<record id="event_type_holiday" model="calendar.event.type"> | ||
<field name="name">Holidays</field> | ||
</record> | ||
</odoo> |
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 calendar_public_holiday | ||
from . import calendar_public_holiday_line |
124 changes: 124 additions & 0 deletions
124
calendar_public_holiday/models/calendar_public_holiday.py
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,124 @@ | ||
# Copyright 2024 Camptocamp | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
import datetime | ||
|
||
from odoo import api, fields, models | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class ResourceCalendarPublicHoliday(models.Model): | ||
_name = "calendar.public.holiday" | ||
_description = "Calendar Public Holiday" | ||
_rec_name = "year" | ||
_order = "year" | ||
|
||
year = fields.Integer( | ||
"Calendar Year", required=True, default=fields.Date.today().year | ||
) | ||
line_ids = fields.One2many( | ||
"calendar.public.holiday.line", | ||
"public_holiday_id", | ||
"Holiday Dates", | ||
) | ||
country_id = fields.Many2one("res.country", "Country") | ||
|
||
@api.constrains("year", "country_id") | ||
def _check_year(self): | ||
for line in self: | ||
line._check_year_one() | ||
|
||
def _check_year_one(self): | ||
if self.search_count( | ||
[ | ||
("year", "=", self.year), | ||
("country_id", "=", self.country_id.id), | ||
("id", "!=", self.id), | ||
] | ||
): | ||
raise ValidationError( | ||
self.env._( | ||
"You can't create duplicate public holiday per year and/or" | ||
" country" | ||
) | ||
) | ||
return True | ||
|
||
@api.depends("country_id") | ||
def _compute_display_name(self): | ||
for line in self: | ||
if line.country_id: | ||
line.display_name = f"{line.year} ({line.country_id.name})" | ||
else: | ||
line.display_name = line.year | ||
|
||
def _get_domain_states_filter(self, pholidays, start_dt, end_dt, partner_id=None): | ||
partner = self.env["res.partner"].browse(partner_id) | ||
states_filter = [ | ||
("public_holiday_id", "in", pholidays.ids), | ||
("date", ">=", start_dt), | ||
("date", "<=", end_dt), | ||
] | ||
if partner and partner.state_id: | ||
states_filter.extend( | ||
[ | ||
"|", | ||
("state_ids", "in", partner.state_id.ids), | ||
("state_ids", "=", False), | ||
] | ||
) | ||
else: | ||
states_filter.append(("state_ids", "=", False)) | ||
return states_filter | ||
|
||
@api.model | ||
@api.returns("calendar.public.holiday.line") | ||
def get_holidays_list(self, year=None, start_dt=None, end_dt=None, partner_id=None): | ||
"""Returns recordset of calendar.public.holiday.line | ||
for the specified year and employee | ||
:param year: year as string (optional if start_dt and end_dt defined) | ||
:param start_dt: start_dt as date | ||
:param end_dt: end_dt as date | ||
:param partner_id: ID of the partner | ||
:return: recordset of calendar.public.holiday.line | ||
""" | ||
partner = self.env["res.partner"].browse(partner_id) | ||
if not start_dt and not end_dt: | ||
start_dt = datetime.date(year, 1, 1) | ||
end_dt = datetime.date(year, 12, 31) | ||
years = list(range(start_dt.year, end_dt.year + 1)) | ||
holidays_filter = [("year", "in", years)] | ||
if partner: | ||
if partner.country_id: | ||
holidays_filter.append( | ||
("country_id", "in", (False, partner.country_id.id)) | ||
) | ||
else: | ||
holidays_filter.append(("country_id", "=", False)) | ||
public_holidays = self.search(holidays_filter) | ||
public_holiday_line = self.env["calendar.public.holiday.line"] | ||
if not public_holidays: | ||
return public_holiday_line | ||
states_filter = self._get_domain_states_filter( | ||
public_holidays, start_dt, end_dt, partner_id=partner.id | ||
) | ||
return public_holiday_line.search(states_filter) | ||
|
||
@api.model | ||
def is_public_holiday(self, selected_date, partner_id=None): | ||
""" | ||
Returns True if selected_date is a public holiday for the employee | ||
:param selected_date: datetime object | ||
:param partner_id: ID of the partner | ||
:return: bool | ||
""" | ||
partner = self.env["res.partner"].browse(partner_id) | ||
partner_id = partner.id if partner else None | ||
holidays_lines = self.get_holidays_list( | ||
year=selected_date.year, partner_id=partner_id | ||
) | ||
if holidays_lines: | ||
hol_date = holidays_lines.filtered(lambda r: r.date == selected_date) | ||
if hol_date: | ||
return True | ||
return False |
123 changes: 123 additions & 0 deletions
123
calendar_public_holiday/models/calendar_public_holiday_line.py
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,123 @@ | ||
# Copyright 2024 Camptocamp | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import SUPERUSER_ID, api, fields, models | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class CalendarHolidaysPublicLine(models.Model): | ||
_name = "calendar.public.holiday.line" | ||
_description = "Calendar Public Holiday Line" | ||
_order = "date, name desc" | ||
|
||
name = fields.Char(required=True) | ||
date = fields.Date(required=True) | ||
public_holiday_id = fields.Many2one( | ||
"calendar.public.holiday", | ||
"Calendar Year", | ||
required=True, | ||
ondelete="cascade", | ||
) | ||
variable_date = fields.Boolean("Date may change", default=True) | ||
state_ids = fields.Many2many( | ||
"res.country.state", | ||
"public_holiday_state_rel", | ||
"public_holiday_line_id", | ||
"state_id", | ||
"Related States", | ||
) | ||
meeting_id = fields.Many2one( | ||
"calendar.event", | ||
string="Meeting", | ||
copy=False, | ||
) | ||
|
||
@api.constrains("date", "state_ids") | ||
def _check_date_state(self): | ||
for line in self: | ||
line._check_date_state_one() | ||
|
||
def _get_domain_check_date_state_one_state_ids(self): | ||
return [ | ||
("date", "=", self.date), | ||
("public_holiday_id", "=", self.public_holiday_id.id), | ||
("state_ids", "!=", False), | ||
("id", "!=", self.id), | ||
] | ||
|
||
def _get_domain_check_date_state_one(self): | ||
return [ | ||
("date", "=", self.date), | ||
("public_holiday_id", "=", self.public_holiday_id.id), | ||
("state_ids", "=", False), | ||
] | ||
|
||
def _check_date_state_one(self): | ||
if self.date.year != self.public_holiday_id.year: | ||
raise ValidationError( | ||
self.env._( | ||
"Dates of holidays should be the same year as the calendar" | ||
" year they are being assigned to" | ||
) | ||
) | ||
|
||
if self.state_ids: | ||
domain = self._get_domain_check_date_state_one_state_ids() | ||
holidays = self.search(domain) | ||
|
||
for holiday in holidays: | ||
if self.state_ids & holiday.state_ids: | ||
raise ValidationError( | ||
self.env._( | ||
"You can't create duplicate public holiday per date" | ||
f" {self.date} and one of the country states." | ||
) | ||
) | ||
domain = self._get_domain_check_date_state_one() | ||
if self.search_count(domain) > 1: | ||
raise ValidationError( | ||
self.env._( | ||
f"You can't create duplicate public holiday per date {self.date}." | ||
) | ||
) | ||
return True | ||
|
||
def _prepare_holidays_meeting_values(self): | ||
self.ensure_one() | ||
categ_id = self.env.ref("calendar_public_holiday.event_type_holiday", False) | ||
meeting_values = { | ||
"name": ( | ||
f"{self.name} ({self.public_holiday_id.country_id.name})" | ||
if self.public_holiday_id.country_id | ||
else self.name | ||
), | ||
"description": ", ".join(self.state_ids.mapped("name")), | ||
"start": self.date, | ||
"stop": self.date, | ||
"allday": True, | ||
"user_id": SUPERUSER_ID, | ||
"privacy": "confidential", | ||
"show_as": "busy", | ||
} | ||
if categ_id: | ||
meeting_values.update({"categ_ids": [(6, 0, categ_id.ids)]}) | ||
return meeting_values | ||
|
||
@api.constrains("date", "name", "public_holiday_id", "state_ids") | ||
def _update_calendar_event(self): | ||
for rec in self: | ||
if rec.meeting_id: | ||
rec.meeting_id.write(rec._prepare_holidays_meeting_values()) | ||
|
||
@api.model_create_multi | ||
def create(self, vals_list): | ||
res = super().create(vals_list) | ||
for record in res: | ||
record.meeting_id = self.env["calendar.event"].create( | ||
record._prepare_holidays_meeting_values() | ||
) | ||
return res | ||
|
||
def unlink(self): | ||
self.mapped("meeting_id").unlink() | ||
return super().unlink() |
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,3 @@ | ||
[build-system] | ||
requires = ["whool"] | ||
build-backend = "whool.buildapi" |
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,3 @@ | ||
- \[Trobz\](<https://trobz.com>): | ||
|
||
- Do Anh Duy \<\<<duyda@trobz.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 @@ | ||
The creation of this module was financially supported by Camptocamp |
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 handles public holidays. |
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,4 @@ | ||
For adding public holidays: | ||
|
||
1. Go to the menu *Calendar \> Public Holidays \> Public Holidays*. | ||
2. Create your public holidays. |
Oops, something went wrong.