From 74e95be281b8d2f97db68df020da82b493a2058a Mon Sep 17 00:00:00 2001 From: Marc Durepos Date: Wed, 5 Jul 2023 09:55:00 -0400 Subject: [PATCH] bemade_fsm: Added logic to prevent child FSM tasks from trying to create sales orders. Fixes #5. --- bemade_fsm/__manifest__.py | 3 +-- bemade_fsm/models/task.py | 12 ++++++++++++ bemade_fsm/tests/test_sale_order.py | 16 ++++++++++++++++ bemade_fsm/tests/test_task_template.py | 16 ++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/bemade_fsm/__manifest__.py b/bemade_fsm/__manifest__.py index c441c01..39b3ed7 100644 --- a/bemade_fsm/__manifest__.py +++ b/bemade_fsm/__manifest__.py @@ -32,8 +32,7 @@ 'sale', 'sale_project', 'sale_stock', - 'industry_fsm', - 'industry_fsm_sale', + 'industry_fsm_stock', 'industry_fsm_report', 'bemade_partner_root_ancestor', 'mail', diff --git a/bemade_fsm/models/task.py b/bemade_fsm/models/task.py index 360d582..ce5c99d 100644 --- a/bemade_fsm/models/task.py +++ b/bemade_fsm/models/task.py @@ -23,6 +23,10 @@ class Task(models.Model): inverse="_inverse_contacts", store=True) + # Override related field to make it return false if this is an FSM subtask + allow_billable = fields.Boolean(string="Can be billed", + related=False, + compute="_compute_allow_billable",) @api.depends('sale_line_id.order_id.site_contacts', 'sale_line_id.order_id.work_order_contacts') def _compute_contacts(self): """ The work order contacts and site contacts for a given task are taken from the sale order if the task @@ -45,3 +49,11 @@ class Task(models.Model): 'work_order_contacts': [Command.set(rec.work_order_contacts.ids)], 'site_contacts': [Command.set(rec.site_contacts.ids)], }) + + @api.depends('parent_id', 'project_id') + def _compute_allow_billable(self): + for rec in self: + if rec.parent_id and rec.project_id and rec.project_id.is_fsm: + rec.allow_billable = False + else: + rec.allow_billable = rec.project_id.allow_billable diff --git a/bemade_fsm/tests/test_sale_order.py b/bemade_fsm/tests/test_sale_order.py index 8eb2266..7db9e33 100644 --- a/bemade_fsm/tests/test_sale_order.py +++ b/bemade_fsm/tests/test_sale_order.py @@ -14,6 +14,7 @@ class TestSalesOrder(TestTaskTemplateCommon): cls.sale_order1 = cls.env['sale.order'].create({ 'partner_id': cls.partner.id, 'client_order_ref': 'TEST ORDER', + 'state': 'draft', }) cls.sol_serv_order = cls.env['sale.order.line'].create({ 'name': cls.product_task_global_project.name, @@ -36,6 +37,7 @@ class TestSalesOrder(TestTaskTemplateCommon): cls.sale_order2 = cls.env['sale.order'].create({ 'partner_id': cls.partner.id, 'client_order_ref': 'TEST ORDER', + 'state': 'draft', }) cls.sol_tree_order = cls.env['sale.order.line'].create({ 'name': cls.product_task_tree_global_project.name, @@ -95,3 +97,17 @@ class TestSalesOrder(TestTaskTemplateCommon): so.action_confirm() task = so.order_line[0].task_id self.assertTrue(task.equipment_id == equipment) + + def test_task_mark_done(self): + so = self.sale_order2 + so.action_confirm() + sol = so.order_line[0] + parent_task = sol.task_id + child_task = parent_task.child_ids[0] + # Marking the top-level tasks done should set the delivered quantity to some non-zero value based on the UOM + parent_task.action_fsm_validate() + sol._compute_qty_delivered() + self.assertTrue(sol.qty_delivered != 0) + # Marking a child task done should not create a sale order + child_task.action_fsm_validate() + self.assertFalse(child_task.sale_order_id) \ No newline at end of file diff --git a/bemade_fsm/tests/test_task_template.py b/bemade_fsm/tests/test_task_template.py index c0bce51..ba5a25c 100644 --- a/bemade_fsm/tests/test_task_template.py +++ b/bemade_fsm/tests/test_task_template.py @@ -20,6 +20,12 @@ class TestTaskTemplateCommon(FSMManagerUserTransactionCase): cls.project = cls.env['project.project'].create({ 'name': 'Test Project', + 'allow_material': True, + 'allow_timesheets': True, + 'allow_subtasks': True, + 'allow_quotations': True, + 'allow_worksheets': True, + 'is_fsm': True, }) cls.product_task_global_project = cls.env['product.product'].create({ 'name': 'Test Product 1', @@ -29,9 +35,16 @@ class TestTaskTemplateCommon(FSMManagerUserTransactionCase): 'task_template_id': cls.task1.id, 'uom_id': hours_uom.id, 'uom_po_id': hours_uom.id, + 'service_policy': 'delivered_manual', }) cls.project_template = cls.env['project.project'].create({ 'name': 'Test Project Template', + 'allow_material': True, + 'allow_timesheets': True, + 'allow_subtasks': True, + 'allow_quotations': True, + 'allow_worksheets': True, + 'is_fsm': True, }) cls.product_task_in_project = cls.env['product.product'].create({ 'name': 'Test Product 2', @@ -41,6 +54,7 @@ class TestTaskTemplateCommon(FSMManagerUserTransactionCase): 'project_template_id': cls.project_template.id, 'uom_po_id': hours_uom.id, 'uom_id': hours_uom.id, + 'service_policy': 'delivered_manual', }) # Set up a task template tree with 2 children and 1 grandchild @@ -70,6 +84,7 @@ class TestTaskTemplateCommon(FSMManagerUserTransactionCase): 'service_tracking': 'task_global_project', 'project_id': cls.project.id, 'task_template_id': cls.parent_task.id, + 'service_policy': 'delivered_manual', 'uom_id': hours_uom.id, 'uom_po_id': hours_uom.id, }) @@ -81,6 +96,7 @@ class TestTaskTemplateCommon(FSMManagerUserTransactionCase): 'project_template_id': cls.project_template.id, 'uom_po_id': hours_uom.id, 'uom_id': hours_uom.id, + 'service_policy': 'delivered_manual', })