137 lines
5.5 KiB
Python
137 lines
5.5 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from collections import defaultdict
|
|
|
|
from odoo import api, fields, models
|
|
from odoo.fields import Domain
|
|
|
|
|
|
class PlanningSlot(models.Model):
|
|
_inherit = 'planning.slot'
|
|
|
|
project_id = fields.Many2one(
|
|
'project.project', string="Project", compute='_compute_project_id', domain=[('is_template', '=', False)], store=True,
|
|
readonly=False, copy=True, check_company=True, group_expand='_read_group_project_id',
|
|
)
|
|
|
|
@api.depends('template_id.project_id')
|
|
def _compute_project_id(self):
|
|
for slot in self:
|
|
if slot.template_id:
|
|
slot.previous_template_id = slot.template_id
|
|
if slot.template_id.project_id:
|
|
slot.project_id = slot.template_id.project_id
|
|
elif slot.previous_template_id and not slot.template_id and slot.previous_template_id.project_id == slot.project_id:
|
|
slot.project_id = False
|
|
elif self.env.context.get('default_project_id'):
|
|
slot.project_id = self.env["project.project"].browse(self.env.context['default_project_id'])
|
|
|
|
def _read_group_project_id(self, projects, domain):
|
|
domain = Domain(domain)
|
|
dom_tuples = [(cond.field_expr, cond.operator) for cond in domain.iter_conditions()]
|
|
if self.env.context.get('planning_expand_project') and ('start_datetime', '<') in dom_tuples and ('end_datetime', '>') in dom_tuples:
|
|
if ('project_id', '=') in dom_tuples or ('project_id', 'ilike') in dom_tuples:
|
|
filter_domain = self._expand_domain_m2o_groupby(domain, 'project_id')
|
|
return self.env['project.project'].search(filter_domain)
|
|
filters = Domain.AND([[('project_id.active', '=', True)], self._expand_domain_dates(domain)])
|
|
return self.env['planning.slot'].search(filters).mapped('project_id')
|
|
return projects
|
|
|
|
def _get_fields_breaking_publication(self):
|
|
""" Fields list triggering the `publication_warning` to True when updating shifts """
|
|
result = super()._get_fields_breaking_publication()
|
|
result.append('project_id')
|
|
return result
|
|
|
|
def _display_name_fields(self):
|
|
return super()._display_name_fields() + ['project_id']
|
|
|
|
def _prepare_template_values(self):
|
|
result = super()._prepare_template_values()
|
|
return {
|
|
'project_id': self.project_id.id,
|
|
**result
|
|
}
|
|
|
|
@api.model
|
|
def _get_template_fields(self):
|
|
values = super()._get_template_fields()
|
|
return {'project_id': 'project_id', **values}
|
|
|
|
def _get_domain_template_slots(self):
|
|
domain = Domain(super()._get_domain_template_slots())
|
|
domain &= Domain('company_id', '=', [False, self.company_id.id])
|
|
if self.project_id:
|
|
domain &= Domain('project_id', '=', self.project_id.id)
|
|
return domain
|
|
|
|
@api.depends('role_id', 'employee_id', 'project_id', 'company_id')
|
|
def _compute_template_autocomplete_ids(self):
|
|
super()._compute_template_autocomplete_ids()
|
|
|
|
@api.depends('project_id')
|
|
def _compute_template_id(self):
|
|
super()._compute_template_id()
|
|
|
|
@api.depends('template_id', 'role_id', 'allocated_hours', 'project_id')
|
|
def _compute_allow_template_creation(self):
|
|
super()._compute_allow_template_creation()
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
return super().create(vals_list)
|
|
|
|
def write(self, vals):
|
|
return super().write(vals)
|
|
|
|
def _prepare_shift_vals(self):
|
|
return {
|
|
**super()._prepare_shift_vals(),
|
|
'project_id': self.project_id.id,
|
|
}
|
|
|
|
def _get_ics_description_data(self):
|
|
return {
|
|
**super()._get_ics_description_data(),
|
|
'project': self.project_id.sudo().display_name if self.project_id else '',
|
|
}
|
|
|
|
def _get_open_shifts_resources(self):
|
|
# Get all resources of planned shifts having the same projects
|
|
resources, resources_dicts = super()._get_open_shifts_resources()
|
|
resource_ids_per_project = defaultdict(list)
|
|
domain = [
|
|
('project_id', 'in', self.project_id.ids),
|
|
('employee_id', '!=', False),
|
|
('start_datetime', '!=', False),
|
|
]
|
|
if self.role_id:
|
|
domain += [('role_id', '=', self.role_id.id)]
|
|
now = fields.Datetime.now()
|
|
for project, slots in self._read_group(
|
|
domain=domain,
|
|
groupby=['project_id'],
|
|
aggregates=['id:recordset']
|
|
):
|
|
# Sort them and add them to the resources recordset and dictionaries
|
|
slots_resources = slots.sorted(key=lambda s: abs(s.end_datetime - now)).resource_id
|
|
resource_ids_per_project[project] = slots_resources.ids
|
|
resources |= slots_resources
|
|
resources_dicts.insert(0, resource_ids_per_project)
|
|
return resources, resources_dicts
|
|
|
|
def _get_resources_dict_values(self, resource_dict):
|
|
self.ensure_one()
|
|
return resource_dict.get(self.project_id, super()._get_resources_dict_values(resource_dict))
|
|
|
|
def _print_planning_get_fields_to_copy(self):
|
|
return super()._print_planning_get_fields_to_copy() + ['project_id']
|
|
|
|
def _print_planning_get_slot_title(self, slot_start, slot_end, tz_info, group_by):
|
|
res = super()._print_planning_get_slot_title(slot_start, slot_end, tz_info, group_by)
|
|
|
|
if group_by != 'project_id' and self.project_id:
|
|
res += ' - ' + self.project_id.name
|
|
|
|
return res
|