resource/models/resource_calendar_leaves.py

79 lines
4.0 KiB
Python
Raw Normal View History

2024-05-03 15:16:16 +03:00
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime, time
from dateutil.relativedelta import relativedelta
from pytz import timezone, utc
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class ResourceCalendarLeaves(models.Model):
_name = "resource.calendar.leaves"
_description = "Resource Time Off Detail"
_order = "date_from"
def default_get(self, fields_list):
res = super().default_get(fields_list)
if 'date_from' in fields_list and 'date_to' in fields_list and not res.get('date_from') and not res.get('date_to'):
# Then we give the current day and we search the begin and end hours for this day in resource.calendar of the current company
today = fields.Datetime.now()
user_tz = timezone(self.env.user.tz or self._context.get('tz') or self.company_id.resource_calendar_id.tz or 'UTC')
date_from = user_tz.localize(datetime.combine(today, time.min))
date_to = user_tz.localize(datetime.combine(today, time.max))
intervals = self.env.company.resource_calendar_id._work_intervals_batch(date_from.replace(tzinfo=utc), date_to.replace(tzinfo=utc))[False]
if intervals: # Then we stop and return the dates given in parameter
list_intervals = [(start, stop) for start, stop, records in intervals] # Convert intervals in interval list
date_from = list_intervals[0][0] # We take the first date in the interval list
date_to = list_intervals[-1][1] # We take the last date in the interval list
res.update(
date_from=date_from.astimezone(utc).replace(tzinfo=None),
date_to=date_to.astimezone(utc).replace(tzinfo=None)
)
return res
name = fields.Char('Reason')
company_id = fields.Many2one(
'res.company', string="Company", readonly=True, store=True,
default=lambda self: self.env.company, compute='_compute_company_id')
calendar_id = fields.Many2one('resource.calendar', 'Working Hours', domain="[('company_id', 'in', [company_id, False])]", check_company=True, index=True)
date_from = fields.Datetime('Start Date', required=True)
date_to = fields.Datetime('End Date', compute="_compute_date_to", readonly=False, required=True, store=True)
resource_id = fields.Many2one(
"resource.resource", 'Resource', index=True,
help="If empty, this is a generic time off for the company. If a resource is set, the time off is only for this resource")
time_type = fields.Selection([('leave', 'Time Off'), ('other', 'Other')], default='leave',
help="Whether this should be computed as a time off or as work time (eg: formation)")
@api.depends('calendar_id')
def _compute_company_id(self):
for leave in self:
leave.company_id = leave.calendar_id.company_id or self.env.company
@api.depends('date_from')
def _compute_date_to(self):
user_tz = timezone(self.env.user.tz or self._context.get('tz') or self.company_id.resource_calendar_id.tz or 'UTC')
for leave in self:
date_to_tz = user_tz.localize(leave.date_from) + relativedelta(hour=23, minute=59, second=59)
leave.date_to = date_to_tz.astimezone(utc).replace(tzinfo=None)
@api.constrains('date_from', 'date_to')
def check_dates(self):
if self.filtered(lambda leave: leave.date_from > leave.date_to):
raise ValidationError(_('The start date of the time off must be earlier than the end date.'))
@api.onchange('resource_id')
def onchange_resource(self):
if self.resource_id:
self.calendar_id = self.resource_id.calendar_id
def _copy_leave_vals(self):
self.ensure_one()
return {
'name': self.name,
'date_from': self.date_from,
'date_to': self.date_to,
'time_type': self.time_type,
}