diff --git a/agreement_legal/__init__.py b/agreement_legal/__init__.py index e6104d924..c1cfe3914 100644 --- a/agreement_legal/__init__.py +++ b/agreement_legal/__init__.py @@ -1,14 +1,5 @@ # 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 +from . import wizards diff --git a/agreement_legal/__manifest__.py b/agreement_legal/__manifest__.py index a519c5978..5694e210f 100644 --- a/agreement_legal/__manifest__.py +++ b/agreement_legal/__manifest__.py @@ -15,7 +15,6 @@ "depends": ["contacts", "agreement", "product"], "data": [ "data/ir_sequence.xml", - "data/module_category.xml", "data/agreement_stage.xml", "data/agreement_type.xml", "security/res_groups.xml", @@ -29,15 +28,14 @@ "views/agreement_stages.xml", "views/agreement_type.xml", "views/agreement_subtype.xml", - "views/agreement_renewaltype.xml", - "views/agreement_increasetype.xml", "views/res_partner.xml", "views/agreement.xml", "views/menu.xml", + "views/assets.xml", + "wizards/create_agreement_wizard.xml", ], "demo": ["demo/demo.xml"], - "qweb": ["static/src/xml/domain_widget_view.xml"], - "post_init_hook": "post_init_agreement_legal", + "qweb": ["static/src/xml/agreement.xml"], "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..3217ac1f5 100644 --- a/agreement_legal/data/agreement_stage.xml +++ b/agreement_legal/data/agreement_stage.xml @@ -1,4 +1,4 @@ - + New @@ -40,6 +40,12 @@ 80 agreement + + Terminated + 90 + True + agreement + Cancelled 100 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/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 deleted file mode 100644 index 13b4ccf0b..000000000 --- a/agreement_legal/data/module_category.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - Agreement - 80 - - 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 @@ - + - - - -
- - - Invalid domain - -
-
Select a model to add a filter.
-
- -
- - - SMatch all records - - - -
- Please navigate below and select field: - - SSMatch records with - - of the following rules: - -
-
- - - - - Match all records - - - -
- Match records with the following rule: - - Match records with - - of the following rules: - -
-
- - - -
- - - - - - - - -
- -
- - -
- - -
-
- - - - - -
- - - - -
-
- -
-
- - - -
-
-
-
-
- - - - - - "" - - - - - - - "" - or - - - - - - - - - - - - is - not - set - -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
    -
- -
-
- diff --git a/agreement_legal/tests/__init__.py b/agreement_legal/tests/__init__.py index b636caa99..07cd93b88 100644 --- a/agreement_legal/tests/__init__.py +++ b/agreement_legal/tests/__init__.py @@ -1 +1,9 @@ +# 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 +from . import test_create_agreement_wizard diff --git a/agreement_legal/tests/test_agreement.py b/agreement_legal/tests/test_agreement.py index be3a56f3d..d836a2185 100644 --- a/agreement_legal/tests/test_agreement.py +++ b/agreement_legal/tests/test_agreement.py @@ -1,13 +1,128 @@ -# 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 lxml import etree + +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, "

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, "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", + ), + ) + + # Test fields_view_get + def test_agreement_fields_view_get(self): + res = self.env["agreement"].fields_view_get( + view_id=self.ref("agreement_legal.partner_agreement_form_view"), + view_type="form", + ) + doc = etree.XML(res["arch"]) + field = doc.xpath("//field[@name='partner_contact_id']") + self.assertEqual( + field[0].get("modifiers", ""), '{"readonly": [["readonly", "=", true]]}' + ) 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..9505ca8a2 --- /dev/null +++ b/agreement_legal/tests/test_agreement_appendix.py @@ -0,0 +1,68 @@ +# 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, "

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..55597225b --- /dev/null +++ b/agreement_legal/tests/test_agreement_clause.py @@ -0,0 +1,68 @@ +# 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, "

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..f4b4b0937 --- /dev/null +++ b/agreement_legal/tests/test_agreement_recital.py @@ -0,0 +1,68 @@ +# 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, "

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..347b29c27 --- /dev/null +++ b/agreement_legal/tests/test_agreement_section.py @@ -0,0 +1,68 @@ +# 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, "

TestSection

", + ) diff --git a/agreement_legal/tests/test_create_agreement_wizard.py b/agreement_legal/tests/test_create_agreement_wizard.py new file mode 100644 index 000000000..577246541 --- /dev/null +++ b/agreement_legal/tests/test_create_agreement_wizard.py @@ -0,0 +1,74 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from odoo.tests.common import TransactionCase + + +class TestCreateAgreementWizard(TransactionCase): + def setUp(self): + super().setUp() + self.agreement_type = self.env["agreement.type"].create( + {"name": "Test Agreement Type", "domain": "sale"} + ) + # Create Agreement Template + self.agreement_template = self.env["agreement"].create( + { + "name": "Test Agreement Template", + "description": "Test", + "state": "active", + "agreement_type_id": self.agreement_type.id, + "is_template": True, + } + ) + # Create Recital + self.env["agreement.recital"].create( + { + "name": "Test Recital", + "title": "Test", + "content": "Test", + "agreement_id": self.agreement_template.id, + } + ) + # Create Section + self.section = self.env["agreement.section"].create( + { + "name": "Test Section", + "title": "Test", + "content": "Test", + "agreement_id": self.agreement_template.id, + } + ) + # Create Clause + self.env["agreement.clause"].create( + { + "name": "Test Clause", + "title": "Test", + "content": "Test", + "agreement_id": self.agreement_template.id, + "section_id": self.section.id, + } + ) + # Create Appendix + self.env["agreement.appendix"].create( + { + "name": "Test Appendices", + "title": "Test", + "content": "Test", + "agreement_id": self.agreement_template.id, + } + ) + + # Test create agreement from template + def test_create_agreement(self): + template = self.agreement_template + wizard = self.env["create.agreement.wizard"].create( + {"template_id": self.agreement_template.id, "name": "Test Agreement"} + ) + res = wizard.create_agreement() + agreement = self.env[res["res_model"]].browse(res["res_id"]) + self.assertEqual(agreement.template_id, template) + self.assertEqual(agreement.is_template, False) + self.assertEqual(agreement.recital_ids.name, template.recital_ids.name) + self.assertEqual(agreement.sections_ids.name, template.sections_ids.name) + self.assertEqual(agreement.clauses_ids.name, template.clauses_ids.name) + self.assertEqual(agreement.clauses_ids.section_id, agreement.sections_ids) + self.assertEqual(agreement.appendix_ids.name, template.appendix_ids.name) diff --git a/agreement_legal/views/agreement.xml b/agreement_legal/views/agreement.xml index db911c4da..3771c9a51 100644 --- a/agreement_legal/views/agreement.xml +++ b/agreement_legal/views/agreement.xml @@ -1,29 +1,19 @@ - + -