From 2fab07b9e3467b2974a4a648c4758f7f3b33a464 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 9 Dec 2019 10:27:02 +0100 Subject: [PATCH] [FIX+REF] contract: Improve unit tests + add unit test for different combinations for next invoicing period + simplify _get_period_to_invoice --- contract/models/contract_line.py | 3 +- contract/tests/test_contract.py | 343 ++++++++++++++++++++++++++++++- 2 files changed, 343 insertions(+), 3 deletions(-) diff --git a/contract/models/contract_line.py b/contract/models/contract_line.py index c8aa46854..c9d475bde 100644 --- a/contract/models/contract_line.py +++ b/contract/models/contract_line.py @@ -667,9 +667,8 @@ class ContractLine(models.Model): # TODO this method can now be removed, since # TODO self.next_period_date_start/end have the same values self.ensure_one() - first_date_invoiced = False if not recurring_next_date: - return first_date_invoiced, last_date_invoiced, recurring_next_date + return False, False, False first_date_invoiced = ( last_date_invoiced + relativedelta(days=1) if last_date_invoiced diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index 2e39d8375..e406a45e3 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -2,6 +2,7 @@ # Copyright 2018 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from collections import namedtuple from datetime import timedelta from dateutil.relativedelta import relativedelta from odoo import fields @@ -681,6 +682,316 @@ class TestContract(TestContractBase): error_message(*combination), ) + def test_next_invoicing_period(self): + """Test different combination for next invoicing period + { + ( + 'recurring_next_date', # date + 'next_period_date_start', # date + 'next_period_date_end' # date + ): ( + date_start, # date + date_end, # date + last_date_invoiced, # date + recurring_next_date, # date + recurring_invoicing_type, # ('pre-paid','post-paid',) + recurring_rule_type, # ('daily', 'weekly', 'monthly', + # 'monthlylastday', 'yearly'), + recurring_interval, # integer + max_date_end, # date + ), + } + """ + + def _update_contract_line( + case, + date_start, + date_end, + last_date_invoiced, + recurring_next_date, + recurring_invoicing_type, + recurring_rule_type, + recurring_interval, + max_date_end, + ): + self.acct_line.write( + { + 'date_start': date_start, + 'date_end': date_end, + 'last_date_invoiced': last_date_invoiced, + 'recurring_next_date': recurring_next_date, + 'recurring_invoicing_type': recurring_invoicing_type, + 'recurring_rule_type': recurring_rule_type, + 'recurring_interval': recurring_interval, + 'max_date_end': max_date_end, + } + ) + + def _get_result(): + return Result( + recurring_next_date=self.acct_line.recurring_next_date, + next_period_date_start=self.acct_line.next_period_date_start, + next_period_date_end=self.acct_line.next_period_date_end, + ) + + def _error_message( + case, + date_start, + date_end, + last_date_invoiced, + recurring_next_date, + recurring_invoicing_type, + recurring_rule_type, + recurring_interval, + max_date_end, + ): + return ( + "Error in case %s:" + "date_start: %s, " + "date_end: %s, " + "last_date_invoiced: %s, " + "recurring_next_date: %s, " + "recurring_invoicing_type: %s, " + "recurring_rule_type: %s, " + "recurring_interval: %s, " + "max_date_end: %s, " + ) % ( + case, + date_start, + date_end, + last_date_invoiced, + recurring_next_date, + recurring_invoicing_type, + recurring_rule_type, + recurring_interval, + max_date_end, + ) + + Result = namedtuple( + 'Result', + [ + 'recurring_next_date', + 'next_period_date_start', + 'next_period_date_end', + ], + ) + Combination = namedtuple( + 'Combination', + [ + 'case', + 'date_start', + 'date_end', + 'last_date_invoiced', + 'recurring_next_date', + 'recurring_invoicing_type', + 'recurring_rule_type', + 'recurring_interval', + 'max_date_end', + ], + ) + combinations = { + Result( + recurring_next_date=to_date('2019-01-01'), + next_period_date_start=to_date('2019-01-01'), + next_period_date_end=to_date('2019-01-31'), + ): Combination( + case="1", + date_start='2019-01-01', + date_end=False, + last_date_invoiced=False, + recurring_next_date='2019-01-01', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-01-01'), + next_period_date_start=to_date('2019-01-01'), + next_period_date_end=to_date('2019-01-15'), + ): Combination( + case="2", + date_start='2019-01-01', + date_end='2019-01-15', + last_date_invoiced=False, + recurring_next_date='2019-01-01', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-01-05'), + next_period_date_start=to_date('2019-01-05'), + next_period_date_end=to_date('2019-01-15'), + ): Combination( + case="3", + date_start='2019-01-05', + date_end='2019-01-15', + last_date_invoiced=False, + recurring_next_date='2019-01-05', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-01-05'), + next_period_date_start=to_date('2019-01-01'), + next_period_date_end=to_date('2019-01-15'), + ): Combination( + case="4", + date_start='2019-01-01', + date_end='2019-01-15', + last_date_invoiced=False, + recurring_next_date='2019-01-05', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-02-01'), + next_period_date_start=to_date('2019-01-01'), + next_period_date_end=to_date('2019-01-31'), + ): Combination( + case="5", + date_start='2019-01-01', + date_end=False, + last_date_invoiced=False, + recurring_next_date='2019-02-01', + recurring_invoicing_type='post-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-02-01'), + next_period_date_start=to_date('2019-01-01'), + next_period_date_end=to_date('2019-01-15'), + ): Combination( + case="6", + date_start='2019-01-01', + date_end='2019-01-15', + last_date_invoiced=False, + recurring_next_date='2019-02-01', + recurring_invoicing_type='post-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-02-01'), + next_period_date_start=to_date('2019-01-05'), + next_period_date_end=to_date('2019-01-31'), + ): Combination( + case="7", + date_start='2019-01-05', + date_end=False, + last_date_invoiced=False, + recurring_next_date='2019-02-01', + recurring_invoicing_type='post-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-01-05'), + next_period_date_start=to_date('2019-01-01'), + next_period_date_end=to_date('2019-01-15'), + ): Combination( + case="8", + date_start='2019-01-01', + date_end='2019-01-15', + last_date_invoiced=False, + recurring_next_date='2019-01-05', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-01-01'), + next_period_date_start=to_date('2018-12-16'), + next_period_date_end=to_date('2019-01-31'), + ): Combination( + case="9", + date_start='2018-01-01', + date_end='2020-01-15', + last_date_invoiced='2018-12-15', + recurring_next_date='2019-01-01', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2019-01-01'), + next_period_date_start=to_date('2018-12-16'), + next_period_date_end=to_date('2018-12-31'), + ): Combination( + case="10", + date_start='2018-01-01', + date_end='2020-01-15', + last_date_invoiced='2018-12-15', + recurring_next_date='2019-01-01', + recurring_invoicing_type='post-paid', + recurring_rule_type='monthly', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2018-12-31'), + next_period_date_start=to_date('2018-12-16'), + next_period_date_end=to_date('2018-12-31'), + ): Combination( + case="11", + date_start='2018-01-01', + date_end='2020-01-15', + last_date_invoiced='2018-12-15', + recurring_next_date='2018-12-31', + recurring_invoicing_type='post-paid', + recurring_rule_type='monthlylastday', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2018-12-16'), + next_period_date_start=to_date('2018-12-16'), + next_period_date_end=to_date('2018-12-31'), + ): Combination( + case="12", + date_start='2018-01-01', + date_end='2020-01-15', + last_date_invoiced='2018-12-15', + recurring_next_date='2018-12-16', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthlylastday', + recurring_interval=1, + max_date_end=False, + ), + Result( + recurring_next_date=to_date('2018-01-05'), + next_period_date_start=to_date('2018-01-05'), + next_period_date_end=to_date('2018-03-31'), + ): Combination( + case="12", + date_start='2018-01-05', + date_end='2020-01-15', + last_date_invoiced=False, + recurring_next_date='2018-01-05', + recurring_invoicing_type='pre-paid', + recurring_rule_type='monthlylastday', + recurring_interval=3, + max_date_end=False, + ), + } + for result, combination in combinations.items(): + _update_contract_line(*combination) + self.assertEqual( + result, _get_result(), _error_message(*combination) + ) + def test_recurring_next_date(self): """recurring next date for a contract is the min for all lines""" self.contract.recurring_create_invoice() @@ -1444,6 +1755,10 @@ class TestContract(TestContractBase): ) self.assertEqual(first, to_date('2018-01-05')) self.assertEqual(last, to_date('2018-01-31')) + self.assertEqual(recurring_next_date, to_date('2018-01-05')) + self.assertEqual( + self.acct_line.recurring_next_date, to_date('2018-01-05') + ) self.contract.recurring_create_invoice() first, last, recurring_next_date = \ self.acct_line._get_period_to_invoice( @@ -1452,6 +1767,13 @@ class TestContract(TestContractBase): ) self.assertEqual(first, to_date('2018-02-01')) self.assertEqual(last, to_date('2018-02-28')) + self.assertEqual(recurring_next_date, to_date('2018-02-01')) + self.assertEqual( + self.acct_line.recurring_next_date, to_date('2018-02-01') + ) + self.assertEqual( + self.acct_line.last_date_invoiced, to_date('2018-01-31') + ) self.contract.recurring_create_invoice() first, last, recurring_next_date = \ self.acct_line._get_period_to_invoice( @@ -1460,7 +1782,26 @@ class TestContract(TestContractBase): ) self.assertEqual(first, to_date('2018-03-01')) self.assertEqual(last, to_date('2018-03-15')) - self.acct_line.manual_renew_needed = True + self.assertEqual(recurring_next_date, to_date('2018-03-01')) + self.assertEqual( + self.acct_line.recurring_next_date, to_date('2018-03-01') + ) + self.assertEqual( + self.acct_line.last_date_invoiced, to_date('2018-02-28') + ) + self.contract.recurring_create_invoice() + first, last, recurring_next_date = \ + self.acct_line._get_period_to_invoice( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) + self.assertFalse(first) + self.assertFalse(last) + self.assertFalse(recurring_next_date) + self.assertFalse(self.acct_line.recurring_next_date) + self.assertEqual( + self.acct_line.last_date_invoiced, to_date('2018-03-15') + ) def test_get_period_to_invoice_monthly_pre_paid_2(self): self.acct_line.date_start = '2018-01-05'