Adds personal stages to tasks. Users assigned to tasks will be able to have their own pipeline to handle their tasks independently of the project's pipeline. The assignee field on Tasks has also been changed to a Many2many to support multiple assignees on one task. The same table is used to store those information, essentially a triplet (task, user, stage), to ensure that: 1) personal stages only apply to tasks to which you are assigned to. 2) synchronizing to make sure that you don't have a personal stage for a task on which you are not assigned anymore. Alongside those changes, some minor changes have also been made: - Modified the task's tree view. - Renamed the Tasks menu to 'My Tasks'. - The default view is now the kanban view for the 'My Tasks' action. - project_id is not required anymore, tasks with no project are considered 'private', those tasks are only visible to those that are assigned to it. - Added tracking of both user_ids and depend_on_ids in the chatter. Closes odoo/odoo#74087 Task ID: 2398734
131 lines
5.8 KiB
Python
131 lines
5.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.fields import Command
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.tests import tagged
|
|
|
|
from odoo.addons.project.tests.test_project_base import TestProjectCommon
|
|
|
|
from datetime import date
|
|
|
|
@tagged('-at_install', 'post_install', 'task_dependencies')
|
|
class TestTaskDependencies(TestProjectCommon):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
|
|
cls.project_pigs.write({
|
|
'allow_task_dependencies': True,
|
|
})
|
|
cls.task_3 = cls.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
|
'name': 'Pigs UserTask 2',
|
|
'user_ids': cls.user_projectuser,
|
|
'project_id': cls.project_pigs.id,
|
|
})
|
|
|
|
def flush_tracking(self):
|
|
""" Force the creation of tracking values. """
|
|
self.env['base'].flush()
|
|
self.cr.precommit.run()
|
|
|
|
def test_task_dependencies(self):
|
|
""" Test the task dependencies feature
|
|
|
|
Test Case:
|
|
=========
|
|
1) Add task2 as dependency in task1
|
|
2) Checks if the task1 has the task in depend_on_ids field.
|
|
"""
|
|
self.assertEqual(len(self.task_1.depend_on_ids), 0, "The task 1 should not have any dependency.")
|
|
self.task_1.write({
|
|
'depend_on_ids': [Command.link(self.task_2.id)],
|
|
})
|
|
self.assertEqual(len(self.task_1.depend_on_ids), 1, "The task 1 should have a dependency.")
|
|
self.task_1.write({
|
|
'depend_on_ids': [Command.link(self.task_3.id)],
|
|
})
|
|
self.assertEqual(len(self.task_1.depend_on_ids), 2, "The task 1 should have two dependencies.")
|
|
|
|
def test_cyclic_dependencies(self):
|
|
""" Test the cyclic dependencies
|
|
|
|
Test Case:
|
|
=========
|
|
1) Check initial setting on three tasks
|
|
2) Add task2 as dependency in task1
|
|
3) Add task3 as dependency in task2
|
|
4) Add task1 as dependency in task3 and check a validation error is raised
|
|
5) Add task1 as dependency in task2 and check a validation error is raised
|
|
"""
|
|
# 1) Check initial setting on three tasks
|
|
self.assertTrue(
|
|
len(self.task_1.depend_on_ids) == len(self.task_2.depend_on_ids) == len(self.task_3.depend_on_ids) == 0,
|
|
"The three tasks should depend on no tasks.")
|
|
self.assertTrue(self.task_1.allow_task_dependencies, 'The task dependencies feature should be enable.')
|
|
self.assertTrue(self.task_2.allow_task_dependencies, 'The task dependencies feature should be enable.')
|
|
self.assertTrue(self.task_3.allow_task_dependencies, 'The task dependencies feature should be enable.')
|
|
|
|
# 2) Add task2 as dependency in task1
|
|
self.task_1.write({
|
|
'depend_on_ids': [Command.link(self.task_2.id)],
|
|
})
|
|
self.assertEqual(len(self.task_1.depend_on_ids), 1, 'The task 1 should have one dependency.')
|
|
|
|
# 3) Add task3 as dependency in task2
|
|
self.task_2.write({
|
|
'depend_on_ids': [Command.link(self.task_3.id)],
|
|
})
|
|
self.assertEqual(len(self.task_2.depend_on_ids), 1, "The task 2 should have one dependency.")
|
|
|
|
# 4) Add task1 as dependency in task3 and check a validation error is raised
|
|
with self.assertRaises(ValidationError), self.cr.savepoint():
|
|
self.task_3.write({
|
|
'depend_on_ids': [Command.link(self.task_1.id)],
|
|
})
|
|
self.assertEqual(len(self.task_3.depend_on_ids), 0, "The dependency should not be added in the task 3 because of a cyclic dependency.")
|
|
|
|
# 5) Add task1 as dependency in task2 and check a validation error is raised
|
|
with self.assertRaises(ValidationError), self.cr.savepoint():
|
|
self.task_2.write({
|
|
'depend_on_ids': [Command.link(self.task_1.id)],
|
|
})
|
|
self.assertEqual(len(self.task_2.depend_on_ids), 1, "The number of dependencies should no change in the task 2 because of a cyclic dependency.")
|
|
|
|
def test_tracking_dependencies(self):
|
|
# Enable the company setting
|
|
self.env['res.config.settings'].create({
|
|
'group_project_task_dependencies': True
|
|
}).execute()
|
|
# `depend_on_ids` is tracked
|
|
self.task_1.with_context(mail_notrack=True).write({
|
|
'depend_on_ids': [Command.link(self.task_2.id)]
|
|
})
|
|
self.cr.precommit.clear()
|
|
# Check that changing a dependency tracked field in task_2 logs a message in task_1.
|
|
self.task_2.write({'date_deadline': date(1983, 3, 1)}) # + 1 message in task_1 and task_2
|
|
self.flush_tracking()
|
|
self.assertEqual(len(self.task_1.message_ids), 1,
|
|
'Changing the deadline on task 2 should have logged a message in task 1.')
|
|
|
|
# Check that changing a dependency tracked field in task_1 does not log a message in task_2.
|
|
self.task_1.date_deadline = date(2020, 1, 2) # + 1 message in task_1
|
|
self.flush_tracking()
|
|
self.assertEqual(len(self.task_2.message_ids), 1,
|
|
'Changing the deadline on task 1 should not have logged a message in task 2.')
|
|
|
|
# Check that changing a field that is not tracked at all on task 2 does not impact task 1.
|
|
self.task_2.color = 100 # no new message
|
|
self.flush_tracking()
|
|
self.assertEqual(len(self.task_1.message_ids), 2,
|
|
'Changing the color on task 2 should not have logged a message in task 1 since it is not tracked.')
|
|
|
|
# Check that changing multiple fields does not log more than one message.
|
|
self.task_2.write({
|
|
'date_deadline': date(2020, 1, 1),
|
|
'kanban_state': 'blocked',
|
|
}) # + 1 message in task_1 and task_2
|
|
self.flush_tracking()
|
|
self.assertEqual(len(self.task_1.message_ids), 3,
|
|
'Changing multiple fields on task 2 should only log one message in task 1.')
|