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
 |