Files
enterprise-addons/project_forecast/models/project_project.py
T

83 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import ast
import datetime
import json
from odoo import api, fields, models
from odoo.exceptions import UserError
class ProjectProject(models.Model):
_inherit = 'project.project'
total_forecast_time = fields.Integer(compute='_compute_total_forecast_time', groups='planning.group_planning_user', export_string_translation=False)
def _compute_total_forecast_time(self):
shifts_read_group = self.env['planning.slot']._read_group(
[('start_datetime', '!=', False), ('end_datetime', '!=', False), ('project_id', 'in', self.ids)],
['project_id'],
['allocated_hours:sum'],
)
shifts_per_project = {project.id: int(round(allocated_hours_sum)) for project, allocated_hours_sum in shifts_read_group}
for project in self:
project.total_forecast_time = shifts_per_project.get(project.id, 0)
@api.constrains('company_id')
def _check_company_id(self):
for project, slots in self.env['planning.slot']._read_group(
domain=[('project_id', 'in', self.ids)],
groupby=['project_id'],
aggregates=['id:recordset'],
):
if not project.company_id:
continue
different_company_slots = slots.filtered(lambda slot: slot.company_id != project.company_id)
if not different_company_slots:
continue
raise UserError(self.env._(
"You cannot update the company for the %(project_name)s project because it’s tied to shifts in another company.\n"
"To change it, first clear the company field for the project. Then move the shifts to the new company, and update the project's company.",
project_name=project.name,
))
def action_project_forecast_from_project(self):
action = self.env["ir.actions.actions"]._for_xml_id("project_forecast.project_forecast_action_from_project")
first_slot = self.env['planning.slot'].search([('start_datetime', '>=', datetime.datetime.now()), ('project_id', '=', self.id)], limit=1, order="start_datetime")
context = {
'default_project_id': self.id,
'search_default_project_id': [self.id],
**ast.literal_eval(action['context']),
'search_default_group_by_resource': False,
}
if first_slot:
context['initialDate'] = first_slot.start_datetime
elif self.date_start and self.date_start >= datetime.date.today():
context['initialDate'] = self.date_start
action.update(
context=context,
domain=[('start_datetime', '!=', False), ('end_datetime', '!=', False)],
)
return action
# ----------------------------
# Project Updates
# ----------------------------
def _get_stat_buttons(self):
buttons = super()._get_stat_buttons()
if self.env.user.has_group("planning.group_planning_user"):
buttons.append({
'icon': 'tasks',
'text': self.env._('Planned'),
'number': self.env._('%s Hours', self.total_forecast_time),
'action_type': 'object',
'action': 'action_project_forecast_from_project',
'additional_context': json.dumps({
'active_id': self.id,
}),
'show': True,
'sequence': 12,
})
return buttons