From 389201cad634c6ab9a68a800ad09504deb20ed7c Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 15 Feb 2021 10:24:40 +0100 Subject: [PATCH] [13.0][IMP] contract_price_revision: Add fixed price revision --- .../tests/test_contract_price_revision.py | 29 +++++++++++-- .../wizards/contract_price_revision.py | 42 +++++++++++++++---- .../wizards/contract_price_revision_views.xml | 12 ++++++ 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/contract_price_revision/tests/test_contract_price_revision.py b/contract_price_revision/tests/test_contract_price_revision.py index 875d12c8a..d369727e1 100644 --- a/contract_price_revision/tests/test_contract_price_revision.py +++ b/contract_price_revision/tests/test_contract_price_revision.py @@ -7,18 +7,26 @@ from odoo.addons.contract.tests.test_contract import TestContractBase class TestContractPriceRevision(TestContractBase): - def execute_wizard(self): + def _create_wizard(self, v_type="percentage", value=0.0): # TODO: Limitation here, start date should be on the # beginning of next period (should not have a gap) - wizard = self.env["contract.price.revision.wizard"].create( - {"date_start": "2018-02-01", "variation_percent": 100.0} + self.wizard = self.env["contract.price.revision.wizard"].create( + { + "date_start": "2018-02-01", + "variation_type": v_type, + "variation_percent": value, + "fixed_price": value, + } ) - wizard.with_context({"active_ids": [self.contract.id]}).action_apply() + + def execute_wizard(self): + self.wizard.with_context({"active_ids": [self.contract.id]}).action_apply() def test_contract_price_revision_wizard(self): # This is for checking if this line is not versioned self.acct_line.copy({"automatic_price": True}) self.assertEqual(len(self.contract.contract_line_ids.ids), 2) + self._create_wizard(value=100.0) self.execute_wizard() self.assertEqual(len(self.contract.contract_line_ids.ids), 3) lines = self.contract.contract_line_ids.filtered( @@ -26,8 +34,21 @@ class TestContractPriceRevision(TestContractBase): ) self.assertEqual(len(lines), 1) + def test_contract_price_fixed_revision_wizard(self): + # This is for checking if this line is not versioned + self.acct_line.copy({"automatic_price": True}) + self.assertEqual(len(self.contract.contract_line_ids.ids), 2) + self._create_wizard(v_type="fixed", value=120.0) + self.execute_wizard() + self.assertEqual(len(self.contract.contract_line_ids.ids), 3) + lines = self.contract.contract_line_ids.filtered( + lambda x: x.price_unit == 120.0 + ) + self.assertEqual(len(lines), 1) + def test_contract_price_revision_invoicing(self): self.acct_line.copy({"automatic_price": True}) + self._create_wizard(value=100.0) self.execute_wizard() invoice = self.contract.recurring_create_invoice() invoices = self.env["account.move"].search( diff --git a/contract_price_revision/wizards/contract_price_revision.py b/contract_price_revision/wizards/contract_price_revision.py index 7fdfb0f4c..76c16d929 100644 --- a/contract_price_revision/wizards/contract_price_revision.py +++ b/contract_price_revision/wizards/contract_price_revision.py @@ -5,9 +5,7 @@ from dateutil.relativedelta import relativedelta -from odoo import fields, models - -import odoo.addons.decimal_precision as dp +from odoo import api, fields, models class ContractPriceRevisionWizard(models.TransientModel): @@ -18,9 +16,33 @@ class ContractPriceRevisionWizard(models.TransientModel): date_start = fields.Date(required=True,) date_end = fields.Date() - variation_percent = fields.Float( - digits=dp.get_precision("Product Price"), required=True, string="Variation %", + variation_type = fields.Selection( + selection=lambda self: self._get_variation_type(), + required=True, + default=lambda self: self._get_default_variation_type(), ) + variation_percent = fields.Float(digits="Product Price", string="Variation %",) + fixed_price = fields.Float(digits="Product Price") + + @api.model + def _get_variation_type(self): + return [ + ("percentage", "Percentage"), + ("fixed", "Fixed Price"), + ] + + @api.model + def _get_default_variation_type(self): + return "percentage" + + def _get_new_price(self, line): + """Get the price depending the change type chosen + """ + if self.variation_type == "percentage": + return line.price_unit * (1.0 + self.variation_percent / 100.0) + elif self.variation_type == "fixed": + return self.fixed_price + return line.price_unit def _get_new_line_value(self, line): self.ensure_one() @@ -29,17 +51,21 @@ class ContractPriceRevisionWizard(models.TransientModel): "last_date_invoiced": False, "date_end": self.date_end, "predecessor_contract_line_id": line.id, - "price_unit": line.price_unit * (1.0 + self.variation_percent / 100.0), + "price_unit": self._get_new_price(line), } + def _get_old_line_date_end(self, line): + return self.date_start - relativedelta(days=1) + def action_apply(self): ContractLine = self.env["contract.line"] active_ids = self.env.context.get("active_ids") contracts = self.env["contract.contract"].browse(active_ids) for line in self._get_contract_lines_to_revise(contracts): - line.update({"date_end": self.date_start - relativedelta(days=1)}) + date_end = self._get_old_line_date_end(line) + line.stop(date_end) # As copy or copy_data are trigerring constraints, don't use them - new_line = line.new(line._cache) + new_line = self.env["contract.line"].new(line._cache) new_line.update(self._get_new_line_value(line)) new_line._onchange_date_start() new_line = ContractLine.create(new_line._convert_to_write(new_line._cache)) diff --git a/contract_price_revision/wizards/contract_price_revision_views.xml b/contract_price_revision/wizards/contract_price_revision_views.xml index 1867911f2..2c109be10 100644 --- a/contract_price_revision/wizards/contract_price_revision_views.xml +++ b/contract_price_revision/wizards/contract_price_revision_views.xml @@ -16,8 +16,20 @@ + + + + + +