diff --git a/addons/hr_timesheet/views/project_views.xml b/addons/hr_timesheet/views/project_views.xml index 9d2fc6a4845..a54f429a15c 100644 --- a/addons/hr_timesheet/views/project_views.xml +++ b/addons/hr_timesheet/views/project_views.xml @@ -196,6 +196,15 @@ + + + + + + + + + diff --git a/addons/project/models/project.py b/addons/project/models/project.py index ff2bb37a754..66ccaabbf23 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -650,6 +650,10 @@ class Task(models.Model): # customer portal: include comment and incoming emails in communication history website_message_ids = fields.One2many(domain=lambda self: [('model', '=', self._name), ('message_type', 'in', ['email', 'comment'])]) + # Task Dependencies fields + allow_task_dependencies = fields.Boolean(related='project_id.allow_task_dependencies') + depend_on_ids = fields.Many2many('project.task', relation="task_dependencies_rel", column1="task_id", column2="depends_on_id", string="Blocked By") + # recurrence fields allow_recurring_tasks = fields.Boolean(related='project_id.allow_recurring_tasks') recurring_task = fields.Boolean(string="Recurrent") @@ -1172,7 +1176,7 @@ class Task(models.Model): if task.project_id.partner_id: task.partner_id = task.project_id.partner_id else: - task.partner_id = task.project_id.partner_id or task.parent_id.partner_id + task.partner_id = task.project_id.partner_id or task.parent_id.partner_id @api.depends('partner_id.email', 'parent_id.email_from') def _compute_email_from(self): @@ -1393,6 +1397,16 @@ class Task(models.Model): # Actions # ------------ + def action_open_task_form(self): + """ Opens the form view of the task """ + return { + 'view_mode': 'form', + 'res_model': 'project.task', + 'res_id': self.id, + 'type': 'ir.actions.act_window', + 'context': dict(self._context, create=False) + } + def action_recurring_tasks(self): return { 'name': 'Tasks in Recurrence', diff --git a/addons/project/static/src/scss/project_form.scss b/addons/project/static/src/scss/project_form.scss new file mode 100644 index 00000000000..b81797fde42 --- /dev/null +++ b/addons/project/static/src/scss/project_form.scss @@ -0,0 +1,3 @@ +.o_form_project_tasks div.o_field_many2many[name=depend_on_ids] tr.o_selected_row td.o_list_button { + background-color: $table-border-color !important; +} diff --git a/addons/project/tests/__init__.py b/addons/project/tests/__init__.py index d5c89ac7b9d..0be5e1c075d 100644 --- a/addons/project/tests/__init__.py +++ b/addons/project/tests/__init__.py @@ -7,3 +7,4 @@ from . import test_project_flow from . import test_project_recurrence from . import test_project_ui from . import test_multicompany +from . import test_task_dependencies diff --git a/addons/project/tests/test_task_dependencies.py b/addons/project/tests/test_task_dependencies.py new file mode 100644 index 00000000000..5650780d3fc --- /dev/null +++ b/addons/project/tests/test_task_dependencies.py @@ -0,0 +1,42 @@ +# -*- 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 + + +@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_id': cls.user_projectuser.id, + 'project_id': cls.project_pigs.id, + }) + + 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.") diff --git a/addons/project/views/project_assets.xml b/addons/project/views/project_assets.xml index 76c047170b5..fdec23a8dfd 100644 --- a/addons/project/views/project_assets.xml +++ b/addons/project/views/project_assets.xml @@ -11,6 +11,7 @@ + diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml index e91d50ddd45..97d81f72a88 100644 --- a/addons/project/views/project_views.xml +++ b/addons/project/views/project_views.xml @@ -658,6 +658,7 @@ +