From 3c15d6a5e27a7fb2c74b1741b4ec030f55e97855 Mon Sep 17 00:00:00 2001 From: Marc Durepos Date: Wed, 10 Jan 2024 09:51:06 -0500 Subject: [PATCH] [FIX] bemade_fsm: propagate assignment checkbox on tasks Fixes a problem where the propagate assignment checkbox on project tasks was not effectively propagating task assignment to descendants. Also added some intelligence around checking / unchecking the box such that the setting change propagates to children. This allows for interesting configurations for assignment propagation, such as limiting propagation only to one level or only starting it at a given level of subtasks. --- bemade_fsm/__manifest__.py | 2 +- bemade_fsm/models/task.py | 3 ++ bemade_fsm/tests/test_task.py | 58 ++++++++++++++++++++++------------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/bemade_fsm/__manifest__.py b/bemade_fsm/__manifest__.py index fa6c83b..8cd38f7 100644 --- a/bemade_fsm/__manifest__.py +++ b/bemade_fsm/__manifest__.py @@ -20,7 +20,7 @@ ######################################################################################## { 'name': 'Improved Field Service Management', - 'version': '15.0.1.0.6', + 'version': '15.0.1.0.7', 'summary': 'Adds functionality necessary for managing field service operations at Durpro.', 'description': 'Adds functionality necessary for managing field service operations at Durpro.', 'category': 'Services/Field Service', diff --git a/bemade_fsm/models/task.py b/bemade_fsm/models/task.py index 43a147d..b7f2fb0 100644 --- a/bemade_fsm/models/task.py +++ b/bemade_fsm/models/task.py @@ -102,6 +102,9 @@ class Task(models.Model): super().write(vals) if not self: # End recursion on empty RecordSet return + if 'propagate_assignment' in vals: + # When a user sets propagate assignment, it should propagate that setting all the way down the chain + self.child_ids.write({'propagate_assignment': vals['propagate_assignment']}) if 'user_ids' in vals: to_propagate = self.filtered(lambda task: task.propagate_assignment) # Here we use child_ids instead of _get_all_subtasks() so as to allow for setting propagate_assignment diff --git a/bemade_fsm/tests/test_task.py b/bemade_fsm/tests/test_task.py index 63185de..c2b5543 100644 --- a/bemade_fsm/tests/test_task.py +++ b/bemade_fsm/tests/test_task.py @@ -6,35 +6,49 @@ from odoo import Command @tagged('post_install', '-at_install') class TaskTest(BemadeFSMBaseTest): + @classmethod + def setUpClass(cls): + # Chose to set up all tests the same way since this code was becoming very redundant + super().setUpClass() + cls.so = cls._generate_sale_order() + cls.template = cls._generate_task_template(names=['Parent', 'Child', 'Grandchild'], structure=[2, 1]) + cls.product = cls._generate_product(task_template=cls.template) + cls.sol = cls._generate_sale_order_line(sale_order=cls.so, product=cls.product) + cls.user = cls._generate_project_manager_user('Bob', 'Bob') + cls.so.action_confirm() + cls.task = cls.sol.task_id + def test_reassigning_assignment_propagating_task_changes_subtasks(self): - # This creation step is a bit lazy - we use defaults to make tasks with a hierachy and settings we want - so = self._generate_sale_order() - template = self._generate_task_template(names=['Parent', 'Child'], structure=[2]) - product = self._generate_product(task_template=template) - sol = self._generate_sale_order_line(sale_order=so, product=product) - user = self._generate_project_manager_user('Bob', 'Bob') - so.action_confirm() - task = sol.task_id + task = self.task + task.propagate_assignment = True task.write({ - 'user_ids': [Command.set([user.id])] + 'user_ids': [Command.set([self.user.id])] }) - self.assertTrue(all([t.user_ids == user for t in task | task._get_all_subtasks()])) - - def test_reassigning_assignment_non_propagating_task_doesnt_change_subtasks(self): - so = self._generate_sale_order() - template = self._generate_task_template(names=['Parent', 'Child', 'Grandchild'], structure=[2, 1]) - product = self._generate_product(task_template=template) - sol = self._generate_sale_order_line(sale_order=so, product=product) - user = self._generate_project_manager_user('Bob', 'Bob') - so.action_confirm() - task = sol.task_id - task.child_ids.write({'propagate_assignment': False}) # Stop propagation after the first level + self.assertTrue(all([t.user_ids == self.user for t in task | task._get_all_subtasks()])) + def test_reassigning_task_doesnt_propagate_by_default(self): + task = self.task task.write({ - 'user_ids': [Command.set([user.id])] + 'user_ids': [Command.set([self.user.id])] }) - self.assertTrue(all([t.user_ids == user for t in task | task.child_ids])) self.assertFalse(any([t.user_ids for t in task.child_ids.child_ids])) + + def test_unset_propagate_assignment_unsets_for_all_children(self): + task = self.task + # First, set propagation and assign + task.propagate_assignment = True + task.write({ + 'user_ids': [Command.set([self.user.id])] + }) + # Then, unset propagation for the children and re-set assignment + task.child_ids.write({'propagate_assignment': False}) + self.assertFalse(any([t.propagate_assignment for t in task._get_all_subtasks()])) + # Then, test that assigning the parent only assigns its children, not its grandchildren + task.write({ + 'user_ids': [Command.set([])] + }) + self.assertTrue(all([not t.user_ids for t in task | task.child_ids])) + self.assertTrue(all([t.user_ids == self.user for t in task.child_ids.child_ids]))