[FIX] project : traceback with multi-company
How to reproduce:
- Link 2 distinct projects to at least 2 different companies
- Modify and save any setting in project settings (this action
should trigger the write function of the project)
--> Traceback: expected singleton
Why?
- If projects associated with differing companies are updated
collectively, the condition self.company_id.id anticipates a
singular value, but it’s possible for there to be multiple.
Solution:
- When we want to write a company_id on some projects, take back the
ones already with the right companyc(as we don't have to change their
stage) and then write the first stage found on the other records (
by putting self.company_id.ids in order to avoid the singleton
exception).
taskid:3520107
closes odoo/odoo#136614
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
This commit is contained in:
@@ -218,6 +218,16 @@ class Project(models.Model):
|
||||
if not self.alias_enabled:
|
||||
self.alias_name = False
|
||||
|
||||
@api.onchange('company_id')
|
||||
def _onchange_company_id(self):
|
||||
if (self.env.user.has_group('project.group_project_stages') and self.stage_id.company_id
|
||||
and self.stage_id.company_id != self.company_id):
|
||||
self.stage_id = self.env['project.project.stage'].search(
|
||||
[('company_id', 'in', [self.company_id.id, False])],
|
||||
order=f"sequence asc, {self.env['project.project.stage']._order}",
|
||||
limit=1,
|
||||
).id
|
||||
|
||||
def _compute_alias_enabled(self):
|
||||
for project in self:
|
||||
project.alias_enabled = bool(project.alias_email)
|
||||
@@ -463,15 +473,19 @@ class Project(models.Model):
|
||||
def write(self, vals):
|
||||
# Here we modify the project's stage according to the selected company (selecting the first
|
||||
# stage in sequence that is linked to the company).
|
||||
if self.env.user.has_group('project.group_project_stages') and\
|
||||
vals.get('company_id') not in (None, self.company_id.id) and\
|
||||
self.stage_id.company_id:
|
||||
ProjectStage = self.env['project.project.stage']
|
||||
vals['stage_id'] = ProjectStage.search(
|
||||
[('company_id', 'in', (vals['company_id'], False))],
|
||||
order=f"company_id asc, {ProjectStage._order}",
|
||||
limit=1,
|
||||
).id
|
||||
company_id = vals.get('company_id')
|
||||
if self.env.user.has_group('project.group_project_stages') and company_id:
|
||||
projects_already_with_company = self.filtered(lambda p: p.company_id.id == company_id)
|
||||
if projects_already_with_company:
|
||||
projects_already_with_company.write({key: value for key, value in vals.items() if key != 'company_id'})
|
||||
self -= projects_already_with_company
|
||||
if company_id not in (None, *self.company_id.ids) and self.stage_id.company_id:
|
||||
ProjectStage = self.env['project.project.stage']
|
||||
vals["stage_id"] = ProjectStage.search(
|
||||
[('company_id', 'in', (company_id, False))],
|
||||
order=f"sequence asc, {ProjectStage._order}",
|
||||
limit=1,
|
||||
).id
|
||||
|
||||
# directly compute is_favorite to dodge allow write access right
|
||||
if 'is_favorite' in vals:
|
||||
|
||||
@@ -76,12 +76,4 @@ class TestProjectStagesMulticompany(TestMultiCompanyProject):
|
||||
project.company_id = self.company_b.id
|
||||
|
||||
# Check that project was moved to stage_company_b
|
||||
self.assertEqual(self.project_company_a.stage_id, self.stage_company_b, "Project Company A should now be in Stage Company B")
|
||||
|
||||
# Here we remove the company from the stage; then changing the project's company to company A should
|
||||
# move it to the first stage in sequence that is linked to no company, and not in stage company A
|
||||
self.stage_company_a.company_id = False
|
||||
|
||||
project.company_id = self.company_a.id
|
||||
|
||||
self.assertNotEqual(self.project_company_a.stage_id, self.stage_company_a, "Project Company A should not be in Stage Company A")
|
||||
self.assertFalse(self.project_company_a.stage_id.company_id, "Project Company A should now be in a stage without company")
|
||||
|
||||
Reference in New Issue
Block a user