Files
enterprise-addons/planning/wizard/planning_preview.py
T

100 lines
3.8 KiB
Python

from odoo import models, fields, api
from odoo.exceptions import ValidationError
from odoo.fields import Domain
import pytz
class PlanningPreview(models.TransientModel):
_name = 'planning.preview'
_description = 'Planning Preview'
employee_id = fields.Many2one(
'hr.employee',
string="Employee",
required=True,
domain="['|', ('company_id', '=', False), ('company_id', 'in', allowed_company_ids)]"
)
slot_count = fields.Integer(compute="_compute_slot_count")
def _get_datetimes(self):
start_str = self.env.context.get('default_start_datetime')
end_str = self.env.context.get('default_end_datetime')
if not start_str or not end_str:
raise ValidationError(self.env._("Missing start or end datetime in context."))
return start_str, end_str
@api.depends('employee_id')
def _compute_slot_count(self):
for record in self:
employee = record.employee_id
if not employee:
record.slot_count = 0
continue
# Get start and end datetimes
start_str, end_str = record._get_datetimes()
# Search all relevant slots within timeframe
employee = record.employee_id
planning_roles = employee.planning_role_ids
open_shift_domain = Domain([
('resource_id', '=', False),
('end_datetime', '>=', fields.Datetime.now()),
])
# Role filtering: if employee has roles, restrict to those; else, no restriction
if planning_roles:
role_domain = Domain([
'|',
('role_id', 'in', planning_roles.ids),
('role_id', '=', False),
])
else:
role_domain = Domain.TRUE
open_shift_domain &= role_domain
request_to_switch_domain = Domain('request_to_switch', '=', True) & role_domain
domain = Domain([
('state', '=', 'published'),
('start_datetime', '>', start_str),
('end_datetime', '<', end_str),
])
domain &= Domain('employee_id', '=', employee.id) | open_shift_domain | request_to_switch_domain
slots = self.env['planning.slot'].search(domain)
# Apply attendance filtering if employee is not flexible
if not employee.is_flexible:
start = pytz.utc.localize(fields.Datetime.from_string(start_str))
end = pytz.utc.localize(fields.Datetime.from_string(end_str))
resource_work_intervals, _ = employee.resource_id._get_valid_work_intervals(start, end)
attendance_intervals = resource_work_intervals.get(employee.resource_id.id, [])
slots = slots.filtered(
lambda s:
s.employee_id
or any(
pytz.utc.localize(s.start_datetime) < end
and pytz.utc.localize(s.end_datetime) > start
for start, end, _dummy in attendance_intervals._items
)
)
record.slot_count = len(slots)
def action_preview_shift(self):
self.ensure_one()
default_start_str, default_end_str = self._get_datetimes()
default_start = fields.Datetime.to_datetime(default_start_str)
default_end = fields.Datetime.to_datetime(default_end_str)
planning = self.env['planning.planning']._get_preview_planning(default_start, default_end, True)
planning.is_planning_preview = True
planning_url = '/planning/%s/%s' % (planning.access_token, self.employee_id.employee_token)
return {
'type': 'ir.actions.act_url',
'url': planning_url,
'target': 'new',
}