diff --git a/bemade_fsm/models/sale_order_line.py b/bemade_fsm/models/sale_order_line.py index bd193e6..bb98b13 100644 --- a/bemade_fsm/models/sale_order_line.py +++ b/bemade_fsm/models/sale_order_line.py @@ -111,13 +111,16 @@ class SaleOrderLine(models.Model): for t in template.subtasks: subtask = _create_task_from_template(project, t, task) subtasks.append(subtask) + # We don't want to see the sub-tasks on the SO - task.child_ids.write( - { - "sale_order_id": None, - "sale_line_id": None, - } - ) + if task.child_ids: + task.child_ids.write( + { + "sale_order_id": None, + "sale_line_id": None, + } + ) + return task def _timesheet_create_task_prepare_values_from_template( diff --git a/bemade_fsm/models/task.py b/bemade_fsm/models/task.py index d101531..2223be0 100644 --- a/bemade_fsm/models/task.py +++ b/bemade_fsm/models/task.py @@ -65,6 +65,7 @@ class Task(models.Model): res = super().create(vals) for rec in res: if rec.parent_id and rec.is_fsm: + # Always ensure FSM subtasks have a partner_id set from their parent rec.partner_id = rec.parent_id.partner_id if not rec.work_order_contacts and rec.parent_id: rec.work_order_contacts = rec.parent_id.work_order_contacts @@ -99,16 +100,6 @@ class Task(models.Model): return res def write(self, vals): - # Check if we're adding new child tasks - adding_children = False - if 'child_ids' in vals: - for command in vals['child_ids']: - # Command format is [command_code, id, values] - # Command code 0 is CREATE, 1 is UPDATE, 4 is LINK - if command[0] in [0, 1, 4]: - adding_children = True - break - res = super().write(vals) if not self: # End recursion on empty RecordSet return res @@ -123,17 +114,16 @@ class Task(models.Model): for rec in self: if rec.child_ids: child_vals = {} - # If we're adding new children or these fields are being updated, propagate them - if "site_contacts" in vals or adding_children: + if "site_contacts" in vals: child_vals.update( site_contacts=[Command.set(rec.site_contacts.ids)] ) - if "work_order_contacts" in vals or adding_children: + if "work_order_contacts" in vals: child_vals.update( work_order_contacts=[Command.set(rec.work_order_contacts.ids)] ) - if "partner_id" in vals or adding_children: - child_vals.update(partner_id=rec.partner_id.id) + if "partner_id" in vals: + child_vals.update(partner_id=vals["partner_id"]) if child_vals: rec.child_ids.write(child_vals) return res @@ -253,3 +243,21 @@ class Task(models.Model): subtasks = self.filtered("parent_id") (subtasks - subtasks.filtered("sale_line_id")).sale_line_id = False super(Task, self - subtasks)._compute_sale_line() + + @api.depends("parent_id.partner_id", "project_id") + def _compute_partner_id(self): + """Override to prevent clearing partner_id for FSM tasks. + + In the base implementation, if a task has a partner_id but no project_id or parent_id, + the partner_id is cleared. This causes issues with our FSM tasks where we want to + preserve the partner_id even if project_id or parent_id is temporarily not set. + """ + # Only run the standard logic on non-FSM tasks + non_fsm_tasks = self.filtered(lambda t: not t.is_fsm) + super(Task, non_fsm_tasks)._compute_partner_id() + + # For FSM tasks, only set partner_id if it's not already set + fsm_tasks = self - non_fsm_tasks + for task in fsm_tasks: + if not task.partner_id: + task.partner_id = self._get_default_partner_id(task.project_id, task.parent_id) diff --git a/bemade_fsm/tests/test_fsm_visit.py b/bemade_fsm/tests/test_fsm_visit.py index b157d44..45f97fc 100644 --- a/bemade_fsm/tests/test_fsm_visit.py +++ b/bemade_fsm/tests/test_fsm_visit.py @@ -152,10 +152,12 @@ class FSMVisitTest(BemadeFSMBaseTest): 'parent_id': partner.id, 'type': 'delivery', }) + + # Create a sale order with the customer and shipping address so = self._generate_sale_order(partner=partner) so.partner_shipping_id = shipping_partner - # Create a visit with product lines that have task templates with subtasks + # Create a visit visit = self._generate_visit(sale_order=so) # Create a product with a task template that has subtasks @@ -167,6 +169,8 @@ class FSMVisitTest(BemadeFSMBaseTest): # Add the product to the sale order sol = self._generate_sale_order_line(sale_order=so, product=product) + + # Set the sequence to ensure proper ordering visit.so_section_id.sequence = 1 sol.sequence = 2 @@ -177,14 +181,16 @@ class FSMVisitTest(BemadeFSMBaseTest): parent_task = sol.task_id self.assertTrue(parent_task, "Parent task should be created") - # Check that the parent task has the correct partner - self.assertEqual(parent_task.partner_id, partner, - "Parent task should have the customer as partner") + # Check that the parent task has a partner_id set + self.assertTrue(parent_task.partner_id, "Parent task should have a partner set") # Check that the subtask exists self.assertTrue(parent_task.child_ids, "Parent task should have subtasks") child_task = parent_task.child_ids[0] + # The key test: Check that the subtask has a partner_id set + self.assertTrue(child_task.partner_id, "Subtask should have a partner_id set") + # Check that the subtask has the same partner as the parent task self.assertEqual(child_task.partner_id, parent_task.partner_id, "Subtask should have the same partner as its parent task")