From 070174658da1705def9bbd24d6de73c4013d662c Mon Sep 17 00:00:00 2001 From: jem-odoo Date: Tue, 13 Aug 2019 15:03:20 +0000 Subject: [PATCH] [IMP] project: default company of a task In Project app, we now ensure the company of a task. Indeed, since that model can be billed, and is important in some business, we need to ensure its link to a company. A task can live outside a project, so the company of a task can not be related. Task company can be set by user, but must be the same as the project (is set), as the task can be billed depending on project properties. Task-1999686 --- addons/project/models/project.py | 17 ++++++++++++++++- addons/sale_timesheet/models/project.py | 3 ++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/addons/project/models/project.py b/addons/project/models/project.py index 11f1c838d50..ce9c41be45f 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -454,6 +454,12 @@ class Task(models.Model): return False return self.stage_find(project_id, [('fold', '=', False)]) + @api.model + def _default_company_id(self): + if self._context.get('default_project_id'): + return self.env['project.project'].browse(self._context['default_project_id']).company_id + return self.env.company + @api.model def _read_group_stage_ids(self, stages, domain, order): search_domain = [('id', 'in', stages.ids)] @@ -508,7 +514,7 @@ class Task(models.Model): default=lambda self: self._get_default_partner(), domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") manager_id = fields.Many2one('res.users', string='Project Manager', related='project_id.user_id', readonly=True, related_sudo=False) - company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company) + company_id = fields.Many2one('res.company', string='Company', required=True, default=_default_company_id) color = fields.Integer(string='Color Index') user_email = fields.Char(related='user_id.email', string='User Email', readonly=True, related_sudo=False) attachment_ids = fields.One2many('ir.attachment', compute='_compute_attachment_ids', string="Main Attachments", @@ -616,6 +622,8 @@ class Task(models.Model): self.partner_id = self.project_id.partner_id if self.project_id not in self.stage_id.project_ids: self.stage_id = self.stage_find(self.project_id.id, [('fold', '=', False)]) + # keep multi company consistency + self.company_id = self.project_id.company_id else: self.stage_id = False @@ -625,6 +633,13 @@ class Task(models.Model): if task.parent_id and task.child_ids: raise ValidationError(_('Task %s cannot have several subtask levels.' % (task.name,))) + @api.constrains('company_id', 'project_id') + def _check_multi_company(self): + for task in self: + if task.project_id: + if task.project_id.company_id != task.company_id: + raise ValidationError(_('Your task must beo in the same company as its project.')) + @api.returns('self', lambda value: value.id) def copy(self, default=None): if default is None: diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index 17c80bf21b2..ed54d749a3c 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -183,7 +183,8 @@ class ProjectTask(models.Model): @api.onchange('project_id') def _onchange_project(self): result = super(ProjectTask, self)._onchange_project() - self.sale_line_id = self.project_id.sale_line_id + if self.project_id.sale_line_id: + self.sale_line_id = self.project_id.sale_line_id if not self.parent_id and not self.partner_id: self.partner_id = self.sale_line_id.order_partner_id # set domain on SO: on non billable project, all SOL of customer, otherwise the one from the SO