160 lines
6.0 KiB
Python
160 lines
6.0 KiB
Python
# Copyright 2017-2018 Tecnativa - Pedro M. Baeza
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
|
|
from odoo import api, fields, models
|
|
from datetime import time
|
|
from dateutil import tz
|
|
|
|
|
|
class HrHolidays(models.Model):
|
|
_inherit = 'hr.holidays'
|
|
|
|
def _default_from_full_day(self):
|
|
"""Detect if we have select full day in calendar and return the
|
|
full day option accordingly.
|
|
"""
|
|
context = self.env.context
|
|
if context.get('default_date_from'):
|
|
dt = fields.Datetime.from_string(
|
|
context['default_date_from']
|
|
).replace(tzinfo=tz.gettz(self.env.user.tz)).astimezone(tz.tzutc())
|
|
return dt.hour == 5 and dt.minute == 0 and dt.second == 0
|
|
return False
|
|
|
|
def _default_to_full_day(self):
|
|
"""Detect if we have select full day in calendar and return the
|
|
full day option accordingly.
|
|
"""
|
|
context = self.env.context
|
|
if context.get('default_date_to'):
|
|
dt = fields.Datetime.from_string(
|
|
context['default_date_to']
|
|
).replace(tzinfo=tz.gettz(self.env.user.tz)).astimezone(tz.tzutc())
|
|
return dt.hour == 17 and dt.minute == 0 and dt.second == 0
|
|
return False
|
|
|
|
from_full_day = fields.Boolean(
|
|
default=lambda self: self._default_from_full_day(),
|
|
readonly=True,
|
|
copy=False,
|
|
states={
|
|
'draft': [('readonly', False)],
|
|
'confirm': [('readonly', False)]
|
|
},
|
|
)
|
|
to_full_day = fields.Boolean(
|
|
default=lambda self: self._default_to_full_day(),
|
|
readonly=True,
|
|
copy=False,
|
|
states={
|
|
'draft': [('readonly', False)],
|
|
'confirm': [('readonly', False)]
|
|
},
|
|
)
|
|
date_from_full = fields.Date(
|
|
compute="_compute_date_from_full",
|
|
inverse="_inverse_date_from_full",
|
|
readonly=True,
|
|
states={
|
|
'draft': [('readonly', False)],
|
|
'confirm': [('readonly', False)]
|
|
},
|
|
)
|
|
date_to_full = fields.Date(
|
|
compute="_compute_date_to_full",
|
|
inverse="_inverse_date_to_full",
|
|
readonly=True,
|
|
states={
|
|
'draft': [('readonly', False)],
|
|
'confirm': [('readonly', False)]
|
|
},
|
|
)
|
|
# Supporting field for avoiding limitation on storing readonly fields
|
|
number_of_days_temp_related = fields.Float(
|
|
related="number_of_days_temp", readonly=True,
|
|
)
|
|
|
|
@api.depends('date_from')
|
|
def _compute_date_from_full(self):
|
|
"""Put day in employee's user timezone, or user timezone as fallback"""
|
|
for record in self.filtered('date_from'):
|
|
tz_name = record.employee_id.user_id.tz or record.env.user.tz
|
|
dt = fields.Datetime.from_string(record.date_from).replace(
|
|
tzinfo=tz.tzutc(),
|
|
).astimezone(tz.gettz(tz_name)).date()
|
|
record.date_from_full = fields.Date.to_string(dt)
|
|
|
|
@api.depends('date_to')
|
|
def _compute_date_to_full(self):
|
|
"""Put day in employee's user timezone, or user timezone as fallback"""
|
|
for record in self.filtered('date_to'):
|
|
tz_name = record.employee_id.user_id.tz or record.env.user.tz
|
|
dt = fields.Datetime.from_string(record.date_to).replace(
|
|
tzinfo=tz.tzutc(),
|
|
).astimezone(tz.gettz(tz_name)).date()
|
|
record.date_to_full = fields.Date.to_string(dt)
|
|
|
|
def _inverse_date_from_full(self):
|
|
"""Put start of the day in employee's user timezone, or user timezone
|
|
as fallback.
|
|
"""
|
|
for record in self.filtered('from_full_day'):
|
|
tz_name = record.employee_id.user_id.tz or record.env.user.tz
|
|
dt = fields.Datetime.from_string(record.date_from_full).replace(
|
|
hour=0, minute=0, second=0, microsecond=0,
|
|
tzinfo=tz.gettz(tz_name),
|
|
).astimezone(tz.tzutc())
|
|
record.date_from = fields.Datetime.to_string(dt)
|
|
|
|
def _inverse_date_to_full(self):
|
|
"""Put end of the day in employee's user timezone, or user timezone
|
|
as fallback.
|
|
"""
|
|
for record in self.filtered('to_full_day'):
|
|
tz_name = record.employee_id.user_id.tz or record.env.user.tz
|
|
dt = fields.Datetime.from_string(record.date_to_full).replace(
|
|
hour=23, minute=59, second=59, microsecond=999999,
|
|
tzinfo=tz.gettz(tz_name),
|
|
).astimezone(tz.tzutc())
|
|
record.date_to = fields.Datetime.to_string(dt)
|
|
|
|
@api.onchange('date_from_full', 'from_full_day')
|
|
def _onchange_date_from_full(self):
|
|
"""As inverse methods only works on save, we have to add an onchange"""
|
|
self._inverse_date_from_full()
|
|
|
|
@api.onchange('date_to_full', 'to_full_day')
|
|
def _onchange_date_to_full(self):
|
|
"""As inverse methods only works on save, we have to add an onchange"""
|
|
self._inverse_date_to_full()
|
|
|
|
def _onchange_data_hr_holidays_compute_days(self):
|
|
"""Trigger the number of days computation also when you change the
|
|
employee or the leave type.
|
|
"""
|
|
self._onchange_date_to()
|
|
|
|
def _get_number_of_days(self, date_from, date_to, employee_id):
|
|
"""Pass context variable for including rest days or change passed dates
|
|
when computing full days.
|
|
"""
|
|
obj = self.with_context(
|
|
include_rest_days=not self.holiday_status_id.exclude_rest_days,
|
|
)
|
|
if self.holiday_status_id.compute_full_days:
|
|
dt_from = fields.Datetime.from_string(date_from)
|
|
date_from = fields.Datetime.to_string(
|
|
dt_from.combine(
|
|
dt_from.date(), time(hour=0, minute=0, second=0),
|
|
),
|
|
)
|
|
dt_to = fields.Datetime.from_string(date_to)
|
|
date_to = fields.Datetime.to_string(
|
|
dt_to.combine(
|
|
dt_to.date(), time(hour=23, minute=59, second=59),
|
|
),
|
|
)
|
|
return super(HrHolidays, obj)._get_number_of_days(
|
|
date_from, date_to, employee_id,
|
|
)
|