[FIX] project: fix closing recurring task

to reproduce:
=============
- make a task recureent
- change its state to a closing one
-> Validation Error

Problem:
========
- when creating the next occurence, we insert the followers of the original
task in the new one, but it happens that we create a `mail_followers` twice
which violates an SQL constraint of `mail_followers`.
https://github.com/odoo/odoo/blob/ea170be9089ee6c784664475ac4ec1218d23dccd/addons/mail/models/mail_thread.py#L253-L262

the create method will create `mail_followers` for the task and as the condition
that follows is truthy in this use-case `_insert_followers` will be called
and create `mail_followers` again.

- In previous versions we didn't face this issue because the creation of
occurences was done by a cron, so the condition was never truthy thanks to
`and self.env.user.active`.

Solution:
=========
to make sure the conditon stays falsy, we set `mail_create_nosubscribe`
in context to `True` when creating the next occurence.

opw-3742737

closes odoo/odoo#156945

X-original-commit: 64ca453bc36740ce4afcd46c1afbbb31abffdf7c
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Signed-off-by: Abdelouahab Laaroussi (abla) <abla@odoo.com>
This commit is contained in:
Abdelouahab (abla)
2024-03-08 09:42:57 +00:00
parent 09350ff0e8
commit e94a1dd2f9
2 changed files with 34 additions and 1 deletions
@@ -81,6 +81,8 @@ class ProjectTaskRecurrence(models.Model):
def _create_next_occurrence(self, occurrence_from):
self.ensure_one()
# Prevent double mail_followers creation
self = self.with_context(mail_create_nosubscribe=True)
self.env['project.task'].sudo().create(
self._create_next_occurrence_values(occurrence_from)
)
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from odoo import fields
from odoo.tests import users
from odoo.tests.common import Form, TransactionCase
from datetime import datetime, time
@@ -13,7 +14,19 @@ class TestProjectRecurrence(TransactionCase):
def setUpClass(cls):
super(TestProjectRecurrence, cls).setUpClass()
cls.env.user.groups_id += cls.env.ref('project.group_project_recurring_tasks')
user_group_employee = cls.env.ref('base.group_user')
user_group_project_user = cls.env.ref('project.group_project_user')
user_group_project_recurring_task = cls.env.ref('project.group_project_recurring_tasks')
Users = cls.env['res.users'].with_context({'no_reset_password': True})
cls.env.user.groups_id += user_group_project_recurring_task
cls.user_projectuser = Users.create({
'name': 'Armande ProjectUser',
'login': 'armandel',
'password': 'armandel',
'email': 'armande.projectuser@example.com',
'groups_id': [(6, 0, [user_group_employee.id, user_group_project_user.id, user_group_project_recurring_task.id])]
})
cls.stage_a = cls.env['project.task.type'].create({'name': 'a'})
cls.stage_b = cls.env['project.task.type'].create({'name': 'b'})
@@ -146,3 +159,21 @@ class TestProjectRecurrence(TransactionCase):
self.assertFalse(any((task_a + task_b + task_c).mapped('recurring_task')),
"All tasks in the recurrence should have their recurrence disabled")
@users('armandel')
def test_closed_recurring_task(self):
"""
When an active user closes a recurring task, the next occurrence should be created
"""
form = Form(self.env['project.task'])
form.name = 'test recurring task'
form.project_id = self.project_recurring
form.recurring_task = True
form.repeat_interval = 1
form.repeat_unit = 'day'
form.repeat_type = 'forever'
task = form.save()
self.assertEqual(len(task.recurrence_id.task_ids), 1, "recurrence should have a single task")
task.state = '1_done'
self.assertEqual(len(task.recurrence_id.task_ids), 2, "a new occurrence should have been created")