From 9cf3d551b0c1b8b9d2dea055794a35f734cb0aa3 Mon Sep 17 00:00:00 2001 From: Patrick Wilson <36892066+patrickrwilson@users.noreply.github.com> Date: Tue, 4 May 2021 11:38:03 -0600 Subject: [PATCH 1/2] [14.0][MIG] agreement_legal (Version 12.0 to 14.0) [MIG] Black & Cleanup [IMP] Reviewer Requested Changes [IMP] Black [IMP] Reviewer Suggestion [FIX] Tests [FIX] Multiple Issues - Added 'is_old_version' field to better display old versions. Before these were marked as inactive therefore not showing in the agreement. - 'is_template' field now copies when making a template revision or copying a template. - New Versions now retain original create date. - Moved version/revision and created on/by fields out of footer to top in order to have the save buttons when creating children. - Moved demo data out of data folder into the demo.xml [FIX] demo data [FIX] Revert back to only migration [FIX] Report dynamic field rendering [FIX] Test --- agreement_legal/__init__.py | 10 -- agreement_legal/__manifest__.py | 2 - agreement_legal/data/agreement_stage.xml | 2 +- agreement_legal/data/agreement_type.xml | 2 +- agreement_legal/data/demo.xml | 0 agreement_legal/data/ir_sequence.xml | 2 +- agreement_legal/data/module_category.xml | 2 +- agreement_legal/demo/demo.xml | 2 +- agreement_legal/models/agreement.py | 159 +++++++++--------- agreement_legal/models/agreement_appendix.py | 55 ++++-- agreement_legal/models/agreement_clause.py | 57 +++++-- agreement_legal/models/agreement_line.py | 10 +- agreement_legal/models/agreement_recital.py | 55 ++++-- agreement_legal/models/agreement_section.py | 58 +++++-- agreement_legal/models/agreement_subtype.py | 4 +- agreement_legal/models/agreement_type.py | 4 +- agreement_legal/models/product_template.py | 2 +- agreement_legal/models/res_partner.py | 4 +- agreement_legal/report/agreement.xml | 34 ++-- .../static/src/js/domain_widget_ext.js | 13 +- .../static/src/xml/domain_widget_view.xml | 11 -- agreement_legal/tests/__init__.py | 7 + agreement_legal/tests/test_agreement.py | 115 ++++++++++++- .../tests/test_agreement_appendix.py | 69 ++++++++ .../tests/test_agreement_clause.py | 69 ++++++++ agreement_legal/tests/test_agreement_line.py | 42 +++++ .../tests/test_agreement_recital.py | 69 ++++++++ .../tests/test_agreement_section.py | 69 ++++++++ agreement_legal/views/agreement.xml | 48 +++--- agreement_legal/views/agreement_appendix.xml | 52 +++--- agreement_legal/views/agreement_clause.xml | 52 +++--- .../views/agreement_increasetype.xml | 2 +- agreement_legal/views/agreement_recital.xml | 52 +++--- .../views/agreement_renewaltype.xml | 2 +- agreement_legal/views/agreement_section.xml | 52 +++--- agreement_legal/views/agreement_stages.xml | 2 +- agreement_legal/views/agreement_subtype.xml | 2 +- agreement_legal/views/agreement_type.xml | 2 +- agreement_legal/views/menu.xml | 2 +- agreement_legal/views/res_config_settings.xml | 58 ++++--- agreement_legal/views/res_partner.xml | 2 +- 41 files changed, 892 insertions(+), 364 deletions(-) create mode 100644 agreement_legal/data/demo.xml create mode 100644 agreement_legal/tests/test_agreement_appendix.py create mode 100644 agreement_legal/tests/test_agreement_clause.py create mode 100644 agreement_legal/tests/test_agreement_line.py create mode 100644 agreement_legal/tests/test_agreement_recital.py create mode 100644 agreement_legal/tests/test_agreement_section.py diff --git a/agreement_legal/__init__.py b/agreement_legal/__init__.py index e6104d924..073035d16 100644 --- a/agreement_legal/__init__.py +++ b/agreement_legal/__init__.py @@ -1,14 +1,4 @@ # Copyright (C) 2018 - TODAY, Pavlov Media # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, SUPERUSER_ID from . import models - - -def post_init_agreement_legal(cr, registry): - env = api.Environment(cr, SUPERUSER_ID, dict()) - cr.execute( - "UPDATE agreement SET stage_id = %s WHERE stage_id IS NULL;", - (env.ref("agreement_legal.agreement_stage_new").id,), - ) - return True diff --git a/agreement_legal/__manifest__.py b/agreement_legal/__manifest__.py index a519c5978..42e33a2c4 100644 --- a/agreement_legal/__manifest__.py +++ b/agreement_legal/__manifest__.py @@ -36,8 +36,6 @@ "views/menu.xml", ], "demo": ["demo/demo.xml"], - "qweb": ["static/src/xml/domain_widget_view.xml"], - "post_init_hook": "post_init_agreement_legal", "application": True, "development_status": "Beta", "maintainers": ["max3903", "ygol"], diff --git a/agreement_legal/data/agreement_stage.xml b/agreement_legal/data/agreement_stage.xml index f59013acd..a9902ec87 100644 --- a/agreement_legal/data/agreement_stage.xml +++ b/agreement_legal/data/agreement_stage.xml @@ -1,4 +1,4 @@ - + New diff --git a/agreement_legal/data/agreement_type.xml b/agreement_legal/data/agreement_type.xml index b0a85e21a..2e00eead8 100644 --- a/agreement_legal/data/agreement_type.xml +++ b/agreement_legal/data/agreement_type.xml @@ -1,4 +1,4 @@ - + Agreement diff --git a/agreement_legal/data/demo.xml b/agreement_legal/data/demo.xml new file mode 100644 index 000000000..e69de29bb diff --git a/agreement_legal/data/ir_sequence.xml b/agreement_legal/data/ir_sequence.xml index 17eb8f1a1..e0026dcd1 100644 --- a/agreement_legal/data/ir_sequence.xml +++ b/agreement_legal/data/ir_sequence.xml @@ -1,4 +1,4 @@ - + diff --git a/agreement_legal/data/module_category.xml b/agreement_legal/data/module_category.xml index 13b4ccf0b..1070cae38 100644 --- a/agreement_legal/data/module_category.xml +++ b/agreement_legal/data/module_category.xml @@ -1,4 +1,4 @@ - + Agreement diff --git a/agreement_legal/demo/demo.xml b/agreement_legal/demo/demo.xml index cab092f59..290eb8eb4 100644 --- a/agreement_legal/demo/demo.xml +++ b/agreement_legal/demo/demo.xml @@ -1,4 +1,4 @@ - + diff --git a/agreement_legal/tests/__init__.py b/agreement_legal/tests/__init__.py index b636caa99..b1ea60b55 100644 --- a/agreement_legal/tests/__init__.py +++ b/agreement_legal/tests/__init__.py @@ -1 +1,8 @@ +# License LGPLv3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). + from . import test_agreement +from . import test_agreement_appendix +from . import test_agreement_clause +from . import test_agreement_line +from . import test_agreement_recital +from . import test_agreement_section diff --git a/agreement_legal/tests/test_agreement.py b/agreement_legal/tests/test_agreement.py index be3a56f3d..17f94c1f9 100644 --- a/agreement_legal/tests/test_agreement.py +++ b/agreement_legal/tests/test_agreement.py @@ -1,13 +1,116 @@ -# Copyright 2021 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo.addons.agreement.tests import test_agreement + +from datetime import timedelta + +from odoo import fields +from odoo.tests.common import TransactionCase -class TestAgreement(test_agreement.TestAgreement): +class TestAgreement(TransactionCase): def setUp(self): super().setUp() + self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"}) + self.agreement_type = self.env["agreement.type"].create( + {"name": "Test Agreement Type", "domain": "sale"} + ) + self.test_agreement = self.env["agreement"].create( + { + "name": "TestAgreement", + "description": "Test", + "special_terms": "Test", + "partner_id": self.test_customer.id, + "start_date": fields.Date.today(), + "end_date": fields.Date.today() + timedelta(days=365), + "state": "active", + } + ) + + # TEST 01: Set 'Field' for dynamic placeholder, test onchange method + def test_onchange_copyvalue(self): + agreement_01 = self.test_agreement + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement"), ("name", "=", "active")] + ) + agreement_01.field_id = field_01.id + agreement_01.onchange_copyvalue() + self.assertEqual(agreement_01.copyvalue, "${object.active or ''}") + + # TEST 02: Set related 'Field' for dynamic placeholder to + # test onchange method + def test_onchange_copyvalue2(self): + agreement_01 = self.test_agreement + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement"), ("name", "=", "agreement_type_id")] + ) + sub_field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.type"), ("name", "=", "active")] + ) + agreement_01.field_id = field_01.id + agreement_01.onchange_copyvalue() + self.assertEqual(agreement_01.sub_object_id.model, "agreement.type") + agreement_01.sub_model_object_field_id = sub_field_01.id + agreement_01.onchange_copyvalue() + self.assertEqual( + agreement_01.copyvalue, "${object.agreement_type_id.active or ''}" + ) + + # TEST 03: Create New Version + def test_create_new_version(self): + agreement_01 = self.test_agreement + agreement_01.create_new_version() + old_agreement = self.env["agreement"].search( + [("code", "=", agreement_01.code + "-V1"), ("active", "=", False)] + ) + self.assertEqual(len(old_agreement), 1) + new_agreement = self.env["agreement"].search( + [("name", "=", "TestAgreement"), ("version", "=", 2)] + ) + self.assertEqual(len(new_agreement), 1) + + # TEST 04: Create New Agreement + def test_create_new_agreement(self): + agreement_01 = self.test_agreement + agreement_01.create_new_agreement() + new_agreement = self.env["agreement"].search([("name", "=", "New")]) + self.assertEqual(len(new_agreement), 1) + + # TEST 05: Test Description Dynamic Field + def test_compute_dynamic_description(self): + agreement_01 = self.test_agreement + agreement_01.description = "${object.name}" + self.assertEqual( + agreement_01.dynamic_description, "TestAgreement", + ) + + # TEST 06: Test Parties Dynamic Field + def test_compute_dynamic_parties(self): + agreement_01 = self.test_agreement + agreement_01.parties = "${object.name}" + self.assertEqual( + agreement_01.dynamic_parties, + "

{" + str(agreement_01.id) + ": '

TestAgreement

'}", + ) + + # TEST 07: Test Special Terms Dynamic Field + def test_compute_dynamic_special_terms(self): + agreement_01 = self.test_agreement + agreement_01.special_terms = "${object.name}" + self.assertEqual( + agreement_01.dynamic_special_terms, + "{" + str(agreement_01.id) + ": 'TestAgreement'}", + ) + + # TEST 02: Check Read Stages + def test_read_group_stage_ids(self): + agreement_01 = self.test_agreement + self.assertEqual( + agreement_01._read_group_stage_ids(self.env["agreement.stage"], [], "id"), + self.env["agreement.stage"].search( + [("stage_type", "=", "agreement")], order="id", + ), + ) def test_action_create_new_version(self): - self.agreement.create_new_version() - self.assertEqual(self.agreement.state, "draft") - self.assertEqual(len(self.agreement.previous_version_agreements_ids), 1) + self.test_agreement.create_new_version() + self.assertEqual(self.test_agreement.state, "draft") + self.assertEqual(len(self.test_agreement.previous_version_agreements_ids), 1) diff --git a/agreement_legal/tests/test_agreement_appendix.py b/agreement_legal/tests/test_agreement_appendix.py new file mode 100644 index 000000000..a8542c904 --- /dev/null +++ b/agreement_legal/tests/test_agreement_appendix.py @@ -0,0 +1,69 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from datetime import timedelta + +from odoo import fields +from odoo.tests.common import TransactionCase + + +class TestAgreementAppendices(TransactionCase): + def setUp(self): + super().setUp() + self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"}) + self.agreement_type = self.env["agreement.type"].create( + {"name": "Test Agreement Type", "domain": "sale"} + ) + self.test_agreement = self.env["agreement"].create( + { + "name": "TestAgreement", + "description": "Test", + "special_terms": "Test", + "partner_id": self.test_customer.id, + "start_date": fields.Date.today(), + "end_date": fields.Date.today() + timedelta(days=365), + } + ) + self.test_appendices = self.env["agreement.appendix"].create( + { + "name": "TestAppendices", + "title": "Test", + "content": "Test", + "agreement_id": self.test_agreement.id, + } + ) + + # TEST 01: Set 'Field' for dynamic placeholder, test onchange method + def test_onchange_copyvalue(self): + appendix_01 = self.test_appendices + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.appendix"), ("name", "=", "active")] + ) + appendix_01.field_id = field_01.id + appendix_01.onchange_copyvalue() + self.assertEqual(appendix_01.copyvalue, "${object.active or ''}") + + # TEST 02: Set related 'Field' for dynamic placeholder to + # test onchange method + def test_onchange_copyvalue2(self): + appendix_01 = self.test_appendices + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.appendix"), ("name", "=", "agreement_id")] + ) + sub_field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement"), ("name", "=", "active")] + ) + appendix_01.field_id = field_01.id + appendix_01.onchange_copyvalue() + self.assertEqual(appendix_01.sub_object_id.model, "agreement") + appendix_01.sub_model_object_field_id = sub_field_01.id + appendix_01.onchange_copyvalue() + self.assertEqual(appendix_01.copyvalue, "${object.agreement_id.active or ''}") + + # TEST 03: Test Dynamic Field + def test_compute_dynamic_content(self): + appendix_01 = self.test_appendices + appendix_01.content = "${object.name}" + self.assertEqual( + appendix_01.dynamic_content, + "

{" + str(appendix_01.id) + ": '

TestAppendices

'}", + ) diff --git a/agreement_legal/tests/test_agreement_clause.py b/agreement_legal/tests/test_agreement_clause.py new file mode 100644 index 000000000..ae9646f22 --- /dev/null +++ b/agreement_legal/tests/test_agreement_clause.py @@ -0,0 +1,69 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from datetime import timedelta + +from odoo import fields +from odoo.tests.common import TransactionCase + + +class TestAgreementClauses(TransactionCase): + def setUp(self): + super().setUp() + self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"}) + self.agreement_type = self.env["agreement.type"].create( + {"name": "Test Agreement Type", "domain": "sale"} + ) + self.test_agreement = self.env["agreement"].create( + { + "name": "TestAgreement", + "description": "Test", + "special_terms": "Test", + "partner_id": self.test_customer.id, + "start_date": fields.Date.today(), + "end_date": fields.Date.today() + timedelta(days=365), + } + ) + self.test_clause = self.env["agreement.clause"].create( + { + "name": "TestClause", + "title": "Test", + "content": "Test", + "agreement_id": self.test_agreement.id, + } + ) + + # TEST 01: Set 'Field' for dynamic placeholder, test onchange method + def test_onchange_copyvalue(self): + clause_01 = self.test_clause + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.clause"), ("name", "=", "active")] + ) + clause_01.field_id = field_01.id + clause_01.onchange_copyvalue() + self.assertEqual(clause_01.copyvalue, "${object.active or ''}") + + # TEST 02: Set related 'Field' for dynamic placeholder to + # test onchange method + def test_onchange_copyvalue2(self): + clause_01 = self.test_clause + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.clause"), ("name", "=", "agreement_id")] + ) + sub_field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement"), ("name", "=", "active")] + ) + clause_01.field_id = field_01.id + clause_01.onchange_copyvalue() + self.assertEqual(clause_01.sub_object_id.model, "agreement") + clause_01.sub_model_object_field_id = sub_field_01.id + clause_01.onchange_copyvalue() + self.assertEqual(clause_01.copyvalue, "${object.agreement_id.active or ''}") + + # TEST 03: Test Dynamic Field + def test_compute_dynamic_content(self): + clause_01 = self.test_clause + clause_01.content = "${object.name}" + self.assertEqual( + clause_01.dynamic_content, + "

{" + str(clause_01.id) + ": '

TestClause

'}", + ) diff --git a/agreement_legal/tests/test_agreement_line.py b/agreement_legal/tests/test_agreement_line.py new file mode 100644 index 000000000..c8a3319e0 --- /dev/null +++ b/agreement_legal/tests/test_agreement_line.py @@ -0,0 +1,42 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from datetime import timedelta + +from odoo import fields +from odoo.tests.common import TransactionCase + + +class TestAgreementLine(TransactionCase): + def setUp(self): + super().setUp() + self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"}) + self.agreement_type = self.env["agreement.type"].create( + {"name": "Test Agreement Type", "domain": "sale"} + ) + self.test_agreement = self.env["agreement"].create( + { + "name": "TestAgreement", + "description": "Test", + "special_terms": "Test", + "partner_id": self.test_customer.id, + "start_date": fields.Date.today(), + "end_date": fields.Date.today() + timedelta(days=365), + } + ) + self.test_product1 = self.env["product.product"].create({"name": "TEST1"}) + self.test_product2 = self.env["product.product"].create({"name": "TEST2"}) + self.test_line = self.env["agreement.line"].create( + { + "product_id": self.test_product1.id, + "name": "Test", + "uom_id": 1, + "agreement_id": self.test_agreement.id, + } + ) + + # TEST 01: Set line product onchange method + def test_onchange_product_id(self): + line_01 = self.test_line + line_01.product_id = self.test_product2.id + line_01._onchange_product_id() + self.assertEqual(line_01.name, "TEST2") diff --git a/agreement_legal/tests/test_agreement_recital.py b/agreement_legal/tests/test_agreement_recital.py new file mode 100644 index 000000000..a83c46016 --- /dev/null +++ b/agreement_legal/tests/test_agreement_recital.py @@ -0,0 +1,69 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from datetime import timedelta + +from odoo import fields +from odoo.tests.common import TransactionCase + + +class TestAgreementRectical(TransactionCase): + def setUp(self): + super().setUp() + self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"}) + self.agreement_type = self.env["agreement.type"].create( + {"name": "Test Agreement Type", "domain": "sale"} + ) + self.test_agreement = self.env["agreement"].create( + { + "name": "TestAgreement", + "description": "Test", + "special_terms": "Test", + "partner_id": self.test_customer.id, + "start_date": fields.Date.today(), + "end_date": fields.Date.today() + timedelta(days=365), + } + ) + self.test_recital = self.env["agreement.recital"].create( + { + "name": "TestRecital", + "title": "Test", + "content": "Test", + "agreement_id": self.test_agreement.id, + } + ) + + # TEST 01: Set 'Field' for dynamic placeholder, test onchange method + def test_onchange_copyvalue(self): + recital_01 = self.test_recital + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.recital"), ("name", "=", "active")] + ) + recital_01.field_id = field_01.id + recital_01.onchange_copyvalue() + self.assertEqual(recital_01.copyvalue, "${object.active or ''}") + + # TEST 02: Set related 'Field' for dynamic placeholder to + # test onchange method + def test_onchange_copyvalue2(self): + recital_01 = self.test_recital + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.recital"), ("name", "=", "agreement_id")] + ) + sub_field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement"), ("name", "=", "active")] + ) + recital_01.field_id = field_01.id + recital_01.onchange_copyvalue() + self.assertEqual(recital_01.sub_object_id.model, "agreement") + recital_01.sub_model_object_field_id = sub_field_01.id + recital_01.onchange_copyvalue() + self.assertEqual(recital_01.copyvalue, "${object.agreement_id.active or ''}") + + # TEST 03: Test Dynamic Field + def test_compute_dynamic_content(self): + recital_01 = self.test_recital + recital_01.content = "${object.name}" + self.assertEqual( + recital_01.dynamic_content, + "

{" + str(recital_01.id) + ": '

TestRecital

'}", + ) diff --git a/agreement_legal/tests/test_agreement_section.py b/agreement_legal/tests/test_agreement_section.py new file mode 100644 index 000000000..1971aa38a --- /dev/null +++ b/agreement_legal/tests/test_agreement_section.py @@ -0,0 +1,69 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from datetime import timedelta + +from odoo import fields +from odoo.tests.common import TransactionCase + + +class TestAgreementSection(TransactionCase): + def setUp(self): + super().setUp() + self.test_customer = self.env["res.partner"].create({"name": "TestCustomer"}) + self.agreement_type = self.env["agreement.type"].create( + {"name": "Test Agreement Type", "domain": "sale"} + ) + self.test_agreement = self.env["agreement"].create( + { + "name": "TestAgreement", + "description": "Test", + "special_terms": "Test", + "partner_id": self.test_customer.id, + "start_date": fields.Date.today(), + "end_date": fields.Date.today() + timedelta(days=365), + } + ) + self.test_section = self.env["agreement.section"].create( + { + "name": "TestSection", + "title": "Test", + "content": "Test", + "agreement_id": self.test_agreement.id, + } + ) + + # TEST 01: Set 'Field' for dynamic placeholder, test onchange method + def test_onchange_copyvalue(self): + section_01 = self.test_section + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.section"), ("name", "=", "active")] + ) + section_01.field_id = field_01.id + section_01.onchange_copyvalue() + self.assertEqual(section_01.copyvalue, "${object.active or ''}") + + # TEST 02: Set related 'Field' for dynamic placeholder to + # test onchange method + def test_onchange_copyvalue2(self): + section_01 = self.test_section + field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement.section"), ("name", "=", "agreement_id")] + ) + sub_field_01 = self.env["ir.model.fields"].search( + [("model", "=", "agreement"), ("name", "=", "active")] + ) + section_01.field_id = field_01.id + section_01.onchange_copyvalue() + self.assertEqual(section_01.sub_object_id.model, "agreement") + section_01.sub_model_object_field_id = sub_field_01.id + section_01.onchange_copyvalue() + self.assertEqual(section_01.copyvalue, "${object.agreement_id.active or ''}") + + # TEST 03: Test Dynamic Field + def test_compute_dynamic_content(self): + section_01 = self.test_section + section_01.content = "${object.name}" + self.assertEqual( + section_01.dynamic_content, + "

{" + str(section_01.id) + ": '

TestSection

'}", + ) diff --git a/agreement_legal/views/agreement.xml b/agreement_legal/views/agreement.xml index db911c4da..7aa6976ff 100644 --- a/agreement_legal/views/agreement.xml +++ b/agreement_legal/views/agreement.xml @@ -1,17 +1,5 @@ - + -