hr_contract/models/resource_resource.py

57 lines
3.1 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import defaultdict
from datetime import datetime
from pytz import timezone
from odoo import models
from odoo.addons.resource.models.utils import Intervals
class ResourceResource(models.Model):
_inherit = 'resource.resource'
def _get_calendars_validity_within_period(self, start, end, default_company=None):
assert start.tzinfo and end.tzinfo
if not self:
return super()._get_calendars_validity_within_period(start, end, default_company=default_company)
calendars_within_period_per_resource = defaultdict(lambda: defaultdict(Intervals)) # keys are [resource id:integer][calendar:self.env['resource.calendar']]
# Employees that have ever had an active contract
employee_ids_with_active_contracts = {
employee.id for [employee] in
self.env['hr.contract']._read_group(
domain=[
('employee_id', 'in', self.employee_id.ids),
'|', ('state', '=', 'open'),
'|', ('state', '=', 'close'),
'&', ('state', '=', 'draft'), ('kanban_state', '=', 'done')
],
groupby=['employee_id'],
)
}
resource_without_contract = self.filtered(
lambda r: not r.employee_id\
or not r.employee_id.id in employee_ids_with_active_contracts\
or r.employee_id.employee_type not in ['employee', 'student']
)
if resource_without_contract:
calendars_within_period_per_resource.update(
super(ResourceResource, resource_without_contract)._get_calendars_validity_within_period(start, end, default_company=default_company)
)
resource_with_contract = self - resource_without_contract
if not resource_with_contract:
return calendars_within_period_per_resource
timezones = {resource.tz for resource in resource_with_contract}
date_start = min(start.astimezone(timezone(tz)).date() for tz in timezones)
date_end = max(end.astimezone(timezone(tz)).date() for tz in timezones)
contracts = resource_with_contract.employee_id._get_contracts(
date_start, date_end, states=['open', 'draft', 'close']
).filtered(lambda c: c.state in ['open', 'close'] or c.kanban_state == 'done')
for contract in contracts:
tz = timezone(contract.employee_id.tz)
calendars_within_period_per_resource[contract.employee_id.resource_id.id][contract.resource_calendar_id] |= Intervals([(
tz.localize(datetime.combine(contract.date_start, datetime.min.time())) if contract.date_start > start.astimezone(tz).date() else start,
tz.localize(datetime.combine(contract.date_end, datetime.max.time())) if contract.date_end and contract.date_end < end.astimezone(tz).date() else end,
self.env['resource.calendar.attendance']
)])
return calendars_within_period_per_resource