[REF+FIX+IMP] contract: Several refactorings + fixes + imps

- REF: Refactor _update_recurring_next_date
  Reuse the logic that is now fully located in _get_recurring_next_date.
- REF: re-add _compute_first_recurring_next_date
  for backward compatibility
- FIX: add missing dependency in computed field
- REF: remove one monthlylastday special case
  get_relative_delta now works the same for all recurring rules.
  Move the special case handling to _init_last_date_invoiced
  which is used only for migration.
- IMP: support pre-paid for monthlylastday
  monthlylastday is (almost) not a special case anymore \o/.
  montlylastday is simply a montly period where the
  periods are aligned on month boundaries.
  The last bit of special casing is that postpaid generates
  invoice the day after the last dasy of the period, except
  for monthlylastday where the invoice is generated on the
  last day of the period. This last exception will disappear
  when we put the offset under user control.
  This is a breaking change because the post-paid/pre-paid
  mode becomes relevant for monthlylastday invoicing.
  The field becomes visible in the UI. Code that generate
  monthlylastday contract lines must now correctly set
  the pre-paid/post-paid mode too. Some tests have had
  to be adapted to reflect that.
- REF: make recurring_invoicing_offset a computed field
  In preparation to making it user modifiable.
- REF: make get_next_period_date_end public
  Make it public because it is the core logic of the module.
  Also, clarify that recurring_invoicing_type
  and recurring_invoicing_offset are needed only when
  we want the next period to be computed from a
  user chosen next invoice date.
- REF: rename _get_recurring_next_date as get_next_invoice_date
  It is easier to understand. Also make it public.
This commit is contained in:
Stéphane Bidoul (ACSONE)
2019-12-06 14:12:18 +01:00
committed by Christopher Rogos
parent 8210b4e95d
commit 68d2b84a4b
6 changed files with 228 additions and 85 deletions

View File

@@ -247,7 +247,7 @@ class TestContract(TestContractBase):
self.assertEqual(self.acct_line.last_date_invoiced, last_date_invoiced)
def test_contract_monthly_lastday(self):
recurring_next_date = to_date('2018-03-31')
recurring_next_date = to_date('2018-02-28')
last_date_invoiced = to_date('2018-02-22')
self.acct_line.recurring_next_date = '2018-02-22'
self.acct_line.recurring_invoicing_type = 'post-paid'
@@ -279,7 +279,7 @@ class TestContract(TestContractBase):
)
self.contract.recurring_create_invoice()
self.assertEqual(
self.acct_line.recurring_next_date, to_date('2018-04-01')
self.acct_line.recurring_next_date, to_date('2018-3-16')
)
self.assertEqual(
self.acct_line.last_date_invoiced, to_date('2018-02-28')
@@ -537,7 +537,34 @@ class TestContract(TestContractBase):
'There was an error and the view couldn\'t be opened.',
)
def test_get_recurring_next_date(self):
def test_get_default_recurring_invoicing_offset(self):
clm = self.env['contract.line']
self.assertEqual(
clm._get_default_recurring_invoicing_offset(
"pre-paid", "monthly"
),
0
)
self.assertEqual(
clm._get_default_recurring_invoicing_offset(
"post-paid", "monthly"
),
1
)
self.assertEqual(
clm._get_default_recurring_invoicing_offset(
"pre-paid", "monthlylastday"
),
0
)
self.assertEqual(
clm._get_default_recurring_invoicing_offset(
"post-paid", "monthlylastday"
),
0
)
def test_get_next_invoice_date(self):
"""Test different combination to compute recurring_next_date
Combination format
{
@@ -555,82 +582,92 @@ class TestContract(TestContractBase):
def error_message(
date_start,
recurring_invoicing_type,
recurring_invoicing_offset,
recurring_rule_type,
recurring_interval,
max_date_end,
):
return "Error in %s every %d %s case, start with %s (max_date_end=%s)" % (
recurring_invoicing_type,
recurring_interval,
recurring_rule_type,
date_start,
max_date_end,
return (
"Error in %s-%d every %d %s case, "
"start with %s (max_date_end=%s)" % (
recurring_invoicing_type,
recurring_invoicing_offset,
recurring_interval,
recurring_rule_type,
date_start,
max_date_end,
)
)
combinations = [
(
to_date('2018-01-01'),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 1,
(to_date('2018-01-01'), 'pre-paid', 0, 'monthly', 1,
False),
),
(
to_date('2018-01-01'),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 1,
(to_date('2018-01-01'), 'pre-paid', 0, 'monthly', 1,
to_date('2018-01-15')),
),
(
False,
(to_date('2018-01-16'), 'pre-paid', 'monthly', 1,
(to_date('2018-01-16'), 'pre-paid', 0, 'monthly', 1,
to_date('2018-01-15')),
),
(
to_date('2018-01-01'),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 2,
(to_date('2018-01-01'), 'pre-paid', 0, 'monthly', 2,
False),
),
(
to_date('2018-02-01'),
(to_date('2018-01-01'), 'post-paid', 'monthly', 1,
(to_date('2018-01-01'), 'post-paid', 1, 'monthly', 1,
False),
),
(
to_date('2018-01-16'),
(to_date('2018-01-01'), 'post-paid', 'monthly', 1,
(to_date('2018-01-01'), 'post-paid', 1, 'monthly', 1,
to_date('2018-01-15')),
),
(
False,
(to_date('2018-01-16'), 'post-paid', 'monthly', 1,
(to_date('2018-01-16'), 'post-paid', 1, 'monthly', 1,
to_date('2018-01-15')),
),
(
to_date('2018-03-01'),
(to_date('2018-01-01'), 'post-paid', 'monthly', 2,
(to_date('2018-01-01'), 'post-paid', 1, 'monthly', 2,
False),
),
(
to_date('2018-01-31'),
(to_date('2018-01-05'), 'post-paid', 'monthlylastday', 1,
(to_date('2018-01-05'), 'post-paid', 0, 'monthlylastday', 1,
False),
),
(
to_date('2018-01-31'),
(to_date('2018-01-06'), 'pre-paid', 'monthlylastday', 1,
to_date('2018-01-06'),
(to_date('2018-01-06'), 'pre-paid', 0, 'monthlylastday', 1,
False),
),
(
to_date('2018-02-28'),
(to_date('2018-01-05'), 'pre-paid', 'monthlylastday', 2,
(to_date('2018-01-05'), 'post-paid', 0, 'monthlylastday', 2,
False),
),
(
to_date('2018-01-05'),
(to_date('2018-01-05'), 'pre-paid', 'yearly', 1,
(to_date('2018-01-05'), 'pre-paid', 0, 'monthlylastday', 2,
False),
),
(
to_date('2018-01-05'),
(to_date('2018-01-05'), 'pre-paid', 0, 'yearly', 1,
False),
),
(
to_date('2019-01-05'),
(to_date('2018-01-05'), 'post-paid', 'yearly', 1,
(to_date('2018-01-05'), 'post-paid', 1, 'yearly', 1,
False),
),
]
@@ -638,7 +675,7 @@ class TestContract(TestContractBase):
for recurring_next_date, combination in combinations:
self.assertEqual(
recurring_next_date,
contract_line_env._get_recurring_next_date(
contract_line_env.get_next_invoice_date(
*combination
),
error_message(*combination),
@@ -1363,7 +1400,7 @@ class TestContract(TestContractBase):
len(invoice_lines),
)
def test_get_period_to_invoice_monthlylastday(self):
def test_get_period_to_invoice_monthlylastday_postpaid(self):
self.acct_line.date_start = '2018-01-05'
self.acct_line.recurring_invoicing_type = 'post-paid'
self.acct_line.recurring_rule_type = 'monthlylastday'
@@ -1394,6 +1431,37 @@ class TestContract(TestContractBase):
self.assertEqual(last, to_date('2018-03-15'))
self.acct_line.manual_renew_needed = True
def test_get_period_to_invoice_monthlylastday_prepaid(self):
self.acct_line.date_start = '2018-01-05'
self.acct_line.recurring_invoicing_type = 'pre-paid'
self.acct_line.recurring_rule_type = 'monthlylastday'
self.acct_line.date_end = '2018-03-15'
self.acct_line._onchange_date_start()
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.assertEqual(first, to_date('2018-01-05'))
self.assertEqual(last, to_date('2018-01-31'))
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.assertEqual(first, to_date('2018-02-01'))
self.assertEqual(last, 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.assertEqual(first, to_date('2018-03-01'))
self.assertEqual(last, to_date('2018-03-15'))
self.acct_line.manual_renew_needed = True
def test_get_period_to_invoice_monthly_pre_paid_2(self):
self.acct_line.date_start = '2018-01-05'
self.acct_line.recurring_invoicing_type = 'pre-paid'