From c7365b028fa5e8a10a6234e2f6551bae0da0b793 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Fri, 20 Dec 2019 11:03:38 +0100 Subject: [PATCH 1/3] [12.0][IMP] - add new option: create_new_line_at_contract_line_renew Add a company config option to decide whether to create or to extend contract line at renew action --- contract/__manifest__.py | 1 + .../migrations/12.0.5.0.1/post-migration.py | 7 +++++ contract/models/__init__.py | 2 ++ contract/models/contract_line.py | 22 +++++++++++---- contract/models/res_company.py | 17 +++++++++++ contract/models/res_config_settings.py | 19 +++++++++++++ contract/tests/test_contract.py | 1 + contract/views/res_config_settings.xml | 28 +++++++++++++++++++ 8 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 contract/migrations/12.0.5.0.1/post-migration.py create mode 100644 contract/models/res_company.py create mode 100644 contract/models/res_config_settings.py create mode 100644 contract/views/res_config_settings.xml diff --git a/contract/__manifest__.py b/contract/__manifest__.py index 2851e545..fdd9cdb8 100644 --- a/contract/__manifest__.py +++ b/contract/__manifest__.py @@ -35,6 +35,7 @@ 'views/contract_template.xml', 'views/contract_template_line.xml', 'views/res_partner_view.xml', + 'views/res_config_settings.xml', ], 'installable': True, } diff --git a/contract/migrations/12.0.5.0.1/post-migration.py b/contract/migrations/12.0.5.0.1/post-migration.py new file mode 100644 index 00000000..9e3ada14 --- /dev/null +++ b/contract/migrations/12.0.5.0.1/post-migration.py @@ -0,0 +1,7 @@ +def migrate(cr, version): + cr.execute( + """\ + UPDATE res_company + SET create_new_line_at_contract_line_renew = true + """ + ) diff --git a/contract/models/__init__.py b/contract/models/__init__.py index b7382c2d..6d46b4b6 100644 --- a/contract/models/__init__.py +++ b/contract/models/__init__.py @@ -10,3 +10,5 @@ from . import account_invoice from . import account_invoice_line from . import res_partner from . import contract_tag +from . import res_company +from . import res_config_settings diff --git a/contract/models/contract_line.py b/contract/models/contract_line.py index c9d475bd..fee07014 100644 --- a/contract/models/contract_line.py +++ b/contract/models/contract_line.py @@ -1164,17 +1164,27 @@ class ContractLine(models.Model): ) return date_start, date_end + @api.multi + def _renew_create_line(self, date_start, date_end): + self.ensure_one() + is_auto_renew = self.is_auto_renew + self.stop(self.date_end, post_message=False) + new_line = self.plan_successor( + date_start, date_end, is_auto_renew, post_message=False + ) + new_line._onchange_date_start() + return new_line + @api.multi def renew(self): res = self.env['contract.line'] for rec in self: - is_auto_renew = rec.is_auto_renew - rec.stop(rec.date_end, post_message=False) + company = rec.contract_id.company_id date_start, date_end = rec._get_renewal_dates() - new_line = rec.plan_successor( - date_start, date_end, is_auto_renew, post_message=False - ) - new_line._onchange_date_start() + if company.create_new_line_at_contract_line_renew: + new_line = rec._renew_create_line(date_start, date_end) + else: + raise NotImplementedError res |= new_line msg = _( """Contract line for {product} diff --git a/contract/models/res_company.py b/contract/models/res_company.py new file mode 100644 index 00000000..ce53ded8 --- /dev/null +++ b/contract/models/res_company.py @@ -0,0 +1,17 @@ +# Copyright 2019 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResCompany(models.Model): + + _inherit = 'res.company' + + create_new_line_at_contract_line_renew = fields.Boolean( + string="Create New Line At Contract Line Renew", + help="If checked, a new line will be generated at contract line renew " + "and linked to the original one as successor. The default " + "behavior is to extend the end date of the contract by a new " + "subscription period", + ) diff --git a/contract/models/res_config_settings.py b/contract/models/res_config_settings.py new file mode 100644 index 00000000..7ab0e91d --- /dev/null +++ b/contract/models/res_config_settings.py @@ -0,0 +1,19 @@ +# Copyright 2019 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + + _inherit = 'res.config.settings' + + create_new_line_at_contract_line_renew = fields.Boolean( + related="company_id.create_new_line_at_contract_line_renew", + readonly=False, + string="Create New Line At Contract Line Renew", + help="If checked, a new line will be generated at contract line renew " + "and linked to the original one as successor. The default " + "behavior is to extend the end date of the contract by a new " + "subscription period", + ) diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index e406a45e..81d38a7a 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -109,6 +109,7 @@ class TestContractBase(common.SavepointCase): cls.line_vals ) cls.acct_line.product_id.is_auto_renew = True + cls.contract.company_id.create_new_line_at_contract_line_renew = True class TestContract(TestContractBase): diff --git a/contract/views/res_config_settings.xml b/contract/views/res_config_settings.xml new file mode 100644 index 00000000..097aec3e --- /dev/null +++ b/contract/views/res_config_settings.xml @@ -0,0 +1,28 @@ + + + + + + + res.config.settings + + + +

Contract

+
+
+
+ +
+
+
+
+
+
+
+
+ + +
From 61737ea920b22ad2dc85af66ed8bb40ba44c29af Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Fri, 20 Dec 2019 11:12:51 +0100 Subject: [PATCH 2/3] [12.0][IMP] - extend contract line at renewal --- contract/models/contract_line.py | 8 +++++++- contract/tests/test_contract.py | 27 ++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/contract/models/contract_line.py b/contract/models/contract_line.py index fee07014..502b9321 100644 --- a/contract/models/contract_line.py +++ b/contract/models/contract_line.py @@ -1175,6 +1175,12 @@ class ContractLine(models.Model): new_line._onchange_date_start() return new_line + @api.multi + def _renew_extend_line(self, date_end): + self.ensure_one() + self.date_end = date_end + return self + @api.multi def renew(self): res = self.env['contract.line'] @@ -1184,7 +1190,7 @@ class ContractLine(models.Model): if company.create_new_line_at_contract_line_renew: new_line = rec._renew_create_line(date_start, date_end) else: - raise NotImplementedError + new_line = rec._renew_extend_line(date_end) res |= new_line msg = _( """Contract line for {product} diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index 81d38a7a..3253716e 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -1669,7 +1669,7 @@ class TestContract(TestContractBase): self.assertTrue(line_3.successor_contract_line_id) self.assertFalse(line_4.successor_contract_line_id) - def test_renew(self): + def test_renew_create_new_line(self): date_start = self.today - relativedelta(months=9) date_end = ( date_start + relativedelta(months=12) - relativedelta(days=1) @@ -1694,6 +1694,31 @@ class TestContract(TestContractBase): new_line.date_end, date_end + relativedelta(months=12) ) + def test_renew_extend_original_line(self): + self.contract.company_id.create_new_line_at_contract_line_renew = False + date_start = self.today - relativedelta(months=9) + date_end = ( + date_start + relativedelta(months=12) - relativedelta(days=1) + ) + self.acct_line.write( + { + 'is_auto_renew': True, + 'date_start': date_start, + 'recurring_next_date': date_start, + 'date_end': self.today, + } + ) + self.acct_line._onchange_is_auto_renew() + self.assertEqual(self.acct_line.date_end, date_end) + self.acct_line.renew() + self.assertTrue(self.acct_line.is_auto_renew) + self.assertEqual( + self.acct_line.date_start, date_start + ) + self.assertEqual( + self.acct_line.date_end, date_end + relativedelta(months=12) + ) + def test_cron_recurring_create_invoice(self): self.acct_line.date_start = '2018-01-01' self.acct_line.recurring_invoicing_type = 'post-paid' From 74d7f4202fc84c953bf9a505bdf42fb6f5ea8e4e Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Fri, 20 Dec 2019 14:14:20 +0100 Subject: [PATCH 3/3] [IMP] - improve code: unify methods argument _renew_create_line and _renew_extend_line --- contract/models/contract_line.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/contract/models/contract_line.py b/contract/models/contract_line.py index 502b9321..8104b65e 100644 --- a/contract/models/contract_line.py +++ b/contract/models/contract_line.py @@ -1156,17 +1156,18 @@ class ContractLine(models.Model): } @api.multi - def _get_renewal_dates(self): + def _get_renewal_new_date_end(self): self.ensure_one() date_start = self.date_end + relativedelta(days=1) date_end = self._get_first_date_end( date_start, self.auto_renew_rule_type, self.auto_renew_interval ) - return date_start, date_end + return date_end @api.multi - def _renew_create_line(self, date_start, date_end): + def _renew_create_line(self, date_end): self.ensure_one() + date_start = self.date_end + relativedelta(days=1) is_auto_renew = self.is_auto_renew self.stop(self.date_end, post_message=False) new_line = self.plan_successor( @@ -1186,9 +1187,10 @@ class ContractLine(models.Model): res = self.env['contract.line'] for rec in self: company = rec.contract_id.company_id - date_start, date_end = rec._get_renewal_dates() + date_end = rec._get_renewal_new_date_end() + date_start = rec.date_end + relativedelta(days=1) if company.create_new_line_at_contract_line_renew: - new_line = rec._renew_create_line(date_start, date_end) + new_line = rec._renew_create_line(date_end) else: new_line = rec._renew_extend_line(date_end) res |= new_line