194 lines
6.4 KiB
Python
194 lines
6.4 KiB
Python
# © 2015 2011,2013 Michael Telahun Makonnen <mmakonnen@gmail.com>
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
|
|
from datetime import date
|
|
|
|
from odoo import api, fields, models, _
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class HrHolidaysPublic(models.Model):
|
|
_name = 'hr.holidays.public'
|
|
_description = 'Public Holidays'
|
|
_rec_name = 'year'
|
|
_order = "year"
|
|
|
|
display_name = fields.Char(
|
|
"Name",
|
|
compute="_compute_display_name",
|
|
readonly=True,
|
|
store=True,
|
|
)
|
|
year = fields.Integer(
|
|
"Calendar Year",
|
|
required=True,
|
|
default=date.today().year
|
|
)
|
|
line_ids = fields.One2many(
|
|
'hr.holidays.public.line',
|
|
'year_id',
|
|
'Holiday Dates'
|
|
)
|
|
country_id = fields.Many2one(
|
|
'res.country',
|
|
'Country'
|
|
)
|
|
|
|
@api.multi
|
|
@api.constrains('year', 'country_id')
|
|
def _check_year(self):
|
|
for line in self:
|
|
line._check_year_one()
|
|
|
|
def _check_year_one(self):
|
|
if self.country_id:
|
|
domain = [('year', '=', self.year),
|
|
('country_id', '=', self.country_id.id),
|
|
('id', '!=', self.id)]
|
|
else:
|
|
domain = [('year', '=', self.year),
|
|
('country_id', '=', False),
|
|
('id', '!=', self.id)]
|
|
if self.search_count(domain):
|
|
raise UserError(_('You can\'t create duplicate public holiday '
|
|
'per year and/or country'))
|
|
return True
|
|
|
|
@api.multi
|
|
@api.depends('year', 'country_id')
|
|
def _compute_display_name(self):
|
|
for line in self:
|
|
if line.country_id:
|
|
line.display_name = '%s (%s)' % (line.year,
|
|
line.country_id.name)
|
|
else:
|
|
line.display_name = line.year
|
|
|
|
@api.multi
|
|
def name_get(self):
|
|
result = []
|
|
for rec in self:
|
|
result.append((rec.id, rec.display_name))
|
|
return result
|
|
|
|
@api.model
|
|
@api.returns('hr.holidays.public.line')
|
|
def get_holidays_list(self, year, employee_id=None):
|
|
"""
|
|
Returns recordset of hr.holidays.public.line
|
|
for the specified year and employee
|
|
:param year: year as string
|
|
:param employee_id: ID of the employee
|
|
:return: recordset of hr.holidays.public.line
|
|
"""
|
|
holidays_filter = [('year', '=', year)]
|
|
employee = False
|
|
if employee_id:
|
|
employee = self.env['hr.employee'].browse(employee_id)
|
|
if employee.address_id and employee.address_id.country_id:
|
|
holidays_filter.append('|')
|
|
holidays_filter.append(('country_id', '=', False))
|
|
holidays_filter.append(('country_id',
|
|
'=',
|
|
employee.address_id.country_id.id))
|
|
else:
|
|
holidays_filter.append(('country_id', '=', False))
|
|
pholidays = self.search(holidays_filter)
|
|
if not pholidays:
|
|
return list()
|
|
|
|
states_filter = [('year_id', 'in', pholidays.ids)]
|
|
if employee and employee.address_id and employee.address_id.state_id:
|
|
states_filter += ['|',
|
|
('state_ids', '=', False),
|
|
('state_ids', '=',
|
|
employee.address_id.state_id.id)]
|
|
else:
|
|
states_filter.append(('state_ids', '=', False))
|
|
hhplo = self.env['hr.holidays.public.line']
|
|
holidays_lines = hhplo.search(states_filter)
|
|
return holidays_lines
|
|
|
|
@api.model
|
|
def is_public_holiday(self, selected_date, employee_id=None):
|
|
"""
|
|
Returns True if selected_date is a public holiday for the employee
|
|
:param selected_date: datetime object or string
|
|
:param employee_id: ID of the employee
|
|
:return: bool
|
|
"""
|
|
if isinstance(selected_date, str):
|
|
selected_date = fields.Date.from_string(selected_date)
|
|
holidays_lines = self.get_holidays_list(
|
|
selected_date.year, employee_id=employee_id)
|
|
if holidays_lines:
|
|
hol_date = holidays_lines.filtered(
|
|
lambda r: r.date == fields.Date.to_string(
|
|
selected_date))
|
|
if hol_date.ids:
|
|
return True
|
|
return False
|
|
|
|
|
|
class HrHolidaysPublicLine(models.Model):
|
|
_name = 'hr.holidays.public.line'
|
|
_description = 'Public Holidays Lines'
|
|
_order = "date, name desc"
|
|
|
|
name = fields.Char(
|
|
'Name',
|
|
required=True,
|
|
)
|
|
date = fields.Date(
|
|
'Date',
|
|
required=True
|
|
)
|
|
year_id = fields.Many2one(
|
|
'hr.holidays.public',
|
|
'Calendar Year',
|
|
required=True,
|
|
)
|
|
variable_date = fields.Boolean('Date may change', oldname='variable',
|
|
default=True)
|
|
state_ids = fields.Many2many(
|
|
'res.country.state',
|
|
'hr_holiday_public_state_rel',
|
|
'line_id',
|
|
'state_id',
|
|
'Related States'
|
|
)
|
|
|
|
@api.multi
|
|
@api.constrains('date', 'state_ids')
|
|
def _check_date_state(self):
|
|
for line in self:
|
|
line._check_date_state_one()
|
|
|
|
def _check_date_state_one(self):
|
|
if fields.Date.from_string(self.date).year != self.year_id.year:
|
|
raise UserError(_(
|
|
'Dates of holidays should be the same year '
|
|
'as the calendar year they are being assigned to'
|
|
))
|
|
|
|
if self.state_ids:
|
|
domain = [('date', '=', self.date),
|
|
('year_id', '=', self.year_id.id),
|
|
('state_ids', '!=', False),
|
|
('id', '!=', self.id)]
|
|
holidays = self.search(domain)
|
|
|
|
for holiday in holidays:
|
|
|
|
if self.state_ids & holiday.state_ids:
|
|
raise UserError(_('You can\'t create duplicate public '
|
|
'holiday per date %s and one of the '
|
|
'country states.') % self.date)
|
|
domain = [('date', '=', self.date),
|
|
('year_id', '=', self.year_id.id),
|
|
('state_ids', '=', False)]
|
|
if self.search_count(domain) > 1:
|
|
raise UserError(_('You can\'t create duplicate public holiday '
|
|
'per date %s.') % self.date)
|
|
return True
|