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
107 lines
4.6 KiB
Python
107 lines
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.tests.common import TransactionCase
|
|
from odoo.exceptions import UserError
|
|
|
|
class TestProjectCommon(TransactionCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestProjectCommon, cls).setUpClass()
|
|
|
|
user_group_employee = cls.env.ref('base.group_user')
|
|
user_group_project_user = cls.env.ref('project.group_project_user')
|
|
user_group_project_manager = cls.env.ref('project.group_project_manager')
|
|
|
|
cls.partner_1 = cls.env['res.partner'].create({
|
|
'name': 'Valid Lelitre',
|
|
'email': 'valid.lelitre@agrolait.com'})
|
|
cls.partner_2 = cls.env['res.partner'].create({
|
|
'name': 'Valid Poilvache',
|
|
'email': 'valid.other@gmail.com'})
|
|
cls.partner_3 = cls.env['res.partner'].create({
|
|
'name': 'Valid Poilboeuf',
|
|
'email': 'valid.poilboeuf@gmail.com'})
|
|
|
|
# Test users to use through the various tests
|
|
Users = cls.env['res.users'].with_context({'no_reset_password': True})
|
|
cls.user_public = Users.create({
|
|
'name': 'Bert Tartignole',
|
|
'login': 'bert',
|
|
'email': 'b.t@example.com',
|
|
'signature': 'SignBert',
|
|
'notification_type': 'email',
|
|
'groups_id': [(6, 0, [cls.env.ref('base.group_public').id])]})
|
|
cls.user_portal = Users.create({
|
|
'name': 'Chell Gladys',
|
|
'login': 'chell',
|
|
'email': 'chell@gladys.portal',
|
|
'signature': 'SignChell',
|
|
'notification_type': 'email',
|
|
'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])]})
|
|
cls.user_projectuser = Users.create({
|
|
'name': 'Armande ProjectUser',
|
|
'login': 'Armande',
|
|
'email': 'armande.projectuser@example.com',
|
|
'groups_id': [(6, 0, [user_group_employee.id, user_group_project_user.id])]
|
|
})
|
|
cls.user_projectmanager = Users.create({
|
|
'name': 'Bastien ProjectManager',
|
|
'login': 'bastien',
|
|
'email': 'bastien.projectmanager@example.com',
|
|
'groups_id': [(6, 0, [user_group_employee.id, user_group_project_manager.id])]})
|
|
|
|
# Test 'Pigs' project
|
|
cls.project_pigs = cls.env['project.project'].with_context({'mail_create_nolog': True}).create({
|
|
'name': 'Pigs',
|
|
'privacy_visibility': 'employees',
|
|
'alias_name': 'project+pigs',
|
|
'partner_id': cls.partner_1.id})
|
|
# Already-existing tasks in Pigs
|
|
cls.task_1 = cls.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
|
'name': 'Pigs UserTask',
|
|
'user_ids': cls.user_projectuser,
|
|
'project_id': cls.project_pigs.id})
|
|
cls.task_2 = cls.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
|
'name': 'Pigs ManagerTask',
|
|
'user_ids': cls.user_projectmanager,
|
|
'project_id': cls.project_pigs.id})
|
|
|
|
# Test 'Goats' project, same as 'Pigs', but with 2 stages
|
|
cls.project_goats = cls.env['project.project'].with_context({'mail_create_nolog': True}).create({
|
|
'name': 'Goats',
|
|
'privacy_visibility': 'followers',
|
|
'alias_name': 'project+goats',
|
|
'partner_id': cls.partner_1.id,
|
|
'type_ids': [
|
|
(0, 0, {
|
|
'name': 'New',
|
|
'sequence': 1,
|
|
}),
|
|
(0, 0, {
|
|
'name': 'Won',
|
|
'sequence': 10,
|
|
})]
|
|
})
|
|
|
|
def format_and_process(self, template, to='groups@example.com, other@gmail.com', subject='Frogs',
|
|
extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
|
|
cc='', msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
|
|
model=None, target_model='project.task', target_field='name'):
|
|
self.assertFalse(self.env[target_model].search([(target_field, '=', subject)]))
|
|
mail = template.format(to=to, subject=subject, cc=cc, extra=extra, email_from=email_from, msg_id=msg_id)
|
|
self.env['mail.thread'].message_process(model, mail)
|
|
return self.env[target_model].search([(target_field, '=', subject)])
|
|
|
|
def test_delete_project_with_tasks(self):
|
|
"""User should never be able to delete a project with tasks"""
|
|
|
|
with self.assertRaises(UserError):
|
|
self.project_pigs.unlink()
|
|
|
|
# click on the archive button
|
|
self.project_pigs.write({'active': False})
|
|
|
|
with self.assertRaises(UserError):
|
|
self.project_pigs.unlink()
|