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
 |