From 44ca041db43755c06b30ff22bc8049b6c5be674b Mon Sep 17 00:00:00 2001 From: Fernando Date: Thu, 30 Apr 2026 17:36:24 -0400 Subject: [PATCH 1/3] [FIX] fieldservice_sale: preserve FSM template type --- fieldservice_sale/models/sale_order.py | 13 ++++++------- fieldservice_sale/tests/test_fsm_sale_common.py | 6 ++++++ fieldservice_sale/tests/test_fsm_sale_order.py | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/fieldservice_sale/models/sale_order.py b/fieldservice_sale/models/sale_order.py index 9a97511db8..32f686ae2a 100644 --- a/fieldservice_sale/models/sale_order.py +++ b/fieldservice_sale/models/sale_order.py @@ -66,7 +66,7 @@ def _prepare_line_fsm_values(self, line): self.ensure_one() templates = line.product_id.fsm_order_template_id vals = self._prepare_fsm_values( - so_id=self.id, sol_id=line.id, template_id=templates.id + so_id=self.id, sol_id=line.id, templates=templates ) return vals @@ -75,9 +75,8 @@ def _prepare_fsm_values(self, **kwargs): Prepare the values to create a new FSM Order from a sale order. """ self.ensure_one() - template_id = kwargs.get("template_id", False) - template_ids = kwargs.get("template_ids", [template_id]) - templates = self.env["fsm.template"].search([("id", "in", template_ids)]) + templates = kwargs.get("templates", self.env["fsm.template"]) + template_id = templates.id if len(templates) == 1 else False note = "" hours = 0.0 categories = self.env["fsm.category"] @@ -85,6 +84,7 @@ def _prepare_fsm_values(self, **kwargs): note += template.instructions or "" hours += template.duration categories |= template.category_ids + order_types = templates.mapped("type_id") return { "location_id": self.fsm_location_id.id, "location_directions": self.fsm_location_id.direction, @@ -96,6 +96,7 @@ def _prepare_fsm_values(self, **kwargs): "sale_id": kwargs.get("so_id", False), "sale_line_id": kwargs.get("sol_id", False), "template_id": template_id, + "type": order_types.id if len(order_types) == 1 else False, "company_id": self.company_id.id, } @@ -112,9 +113,7 @@ def _field_service_generate_sale_fsm_orders(self, new_fsm_sol): ) if not fsm_by_sale: templates = new_fsm_sol.product_id.fsm_order_template_id - vals = self._prepare_fsm_values( - so_id=self.id, template_ids=templates.ids - ) + vals = self._prepare_fsm_values(so_id=self.id, templates=templates) fsm_by_sale = self.env["fsm.order"].sudo().create(vals) new_fsm_orders |= fsm_by_sale new_fsm_sol.write({"fsm_order_id": fsm_by_sale.id}) diff --git a/fieldservice_sale/tests/test_fsm_sale_common.py b/fieldservice_sale/tests/test_fsm_sale_common.py index 57d1e57f9d..7cbf912d16 100644 --- a/fieldservice_sale/tests/test_fsm_sale_common.py +++ b/fieldservice_sale/tests/test_fsm_sale_common.py @@ -13,6 +13,11 @@ def setUpClass(cls): def setUpFSMTemplates(cls): # Create some templates to use on the FSM products FSMTemplate = cls.env["fsm.template"] + cls.fsm_order_type = cls.env["fsm.order.type"].create( + { + "name": "Test FSM Order Type", + } + ) # Template 1 cls.fsm_template_1 = FSMTemplate.create( @@ -20,6 +25,7 @@ def setUpFSMTemplates(cls): "name": "Test FSM Template #1", "instructions": "These are the instructions for Template #1", "duration": 2.25, + "type_id": cls.fsm_order_type.id, } ) # Template 2 diff --git a/fieldservice_sale/tests/test_fsm_sale_order.py b/fieldservice_sale/tests/test_fsm_sale_order.py index d6dbaa5e8b..c9f87cca28 100644 --- a/fieldservice_sale/tests/test_fsm_sale_order.py +++ b/fieldservice_sale/tests/test_fsm_sale_order.py @@ -260,6 +260,8 @@ def test_sale_order_1(self): self.assertEqual( len(fsm_order.ids), 1, "FSM Sale: Sale Order not linked to FSM Order" ) + self.assertEqual(fsm_order.template_id, self.fsm_template_1) + self.assertEqual(fsm_order.type, self.fsm_template_1.type_id) # Complete the FSM order if self._isp_account_installed(): From 0bba73ff556aab72ac454760de899246cf9a0ad2 Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 19 May 2026 21:11:42 -0400 Subject: [PATCH 2/3] [FIX] fieldservice: stabilize flaky test_order_sign --- fieldservice/tests/test_fsm_order.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/fieldservice/tests/test_fsm_order.py b/fieldservice/tests/test_fsm_order.py index c1a5db6441..6a95768017 100644 --- a/fieldservice/tests/test_fsm_order.py +++ b/fieldservice/tests/test_fsm_order.py @@ -3,6 +3,8 @@ from datetime import timedelta +from freezegun import freeze_time + from odoo import fields from odoo.exceptions import UserError, ValidationError from odoo.tests import Form @@ -332,13 +334,14 @@ def test_order_sign(self): ) order.stage_id.require_signature = True # Sign it - Wizard = self.env["fsm.order.sign.wizard"].with_context( - active_model=order._name, active_id=order.id - ) - with Form(Wizard) as wizard_form: - wizard_form.signed_by = "Test Customer" - wizard_form.signature = TEST_IMAGE_BASE64 - wizard_form.record.action_sign() - # Check that the signature has been updated - self.assertEqual(order.signed_by, "Test Customer") - self.assertEqual(order.signed_on, fields.Datetime.now()) + with freeze_time(fields.Datetime.now()): + Wizard = self.env["fsm.order.sign.wizard"].with_context( + active_model=order._name, active_id=order.id + ) + with Form(Wizard) as wizard_form: + wizard_form.signed_by = "Test Customer" + wizard_form.signature = TEST_IMAGE_BASE64 + wizard_form.record.action_sign() + # Check that the signature has been updated + self.assertEqual(order.signed_by, "Test Customer") + self.assertEqual(order.signed_on, fields.Datetime.now()) From 42f9b9206f0cd5b8fc806f16e59147d68969e588 Mon Sep 17 00:00:00 2001 From: Fernando Date: Wed, 20 May 2026 09:29:48 -0400 Subject: [PATCH 3/3] [FIX] fieldservice_sale: use active record assignment for fsm_order_id --- fieldservice_sale/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fieldservice_sale/models/sale_order.py b/fieldservice_sale/models/sale_order.py index 32f686ae2a..dea3da95e9 100644 --- a/fieldservice_sale/models/sale_order.py +++ b/fieldservice_sale/models/sale_order.py @@ -116,7 +116,7 @@ def _field_service_generate_sale_fsm_orders(self, new_fsm_sol): vals = self._prepare_fsm_values(so_id=self.id, templates=templates) fsm_by_sale = self.env["fsm.order"].sudo().create(vals) new_fsm_orders |= fsm_by_sale - new_fsm_sol.write({"fsm_order_id": fsm_by_sale.id}) + new_fsm_sol.fsm_order_id = fsm_by_sale.id return new_fsm_orders @@ -132,7 +132,7 @@ def _field_service_generate_line_fsm_orders(self, new_fsm_sol): for line in new_fsm_sol: vals = self._prepare_line_fsm_values(line) fsm_by_line = self.env["fsm.order"].sudo().create(vals) - line.write({"fsm_order_id": fsm_by_line.id}) + line.fsm_order_id = fsm_by_line.id new_fsm_orders |= fsm_by_line return new_fsm_orders