diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index fd669ea4..e406a45e 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()