Browse Source

[REF] contract: handle max_date_end in _get_recurring_next_date

This concentrates all next date calculation
logic in one place, and will allow further simplifications.
pull/434/head
Stéphane Bidoul (ACSONE) 5 years ago
parent
commit
e6b9ea9ce7
No known key found for this signature in database GPG Key ID: BCAB2555446B5B92
  1. 34
      contract/models/contract_line.py
  2. 52
      contract/tests/test_contract.py

34
contract/models/contract_line.py

@ -362,19 +362,23 @@ class ContractLine(models.Model):
recurring_invoicing_type, recurring_invoicing_type,
recurring_rule_type, recurring_rule_type,
recurring_interval, recurring_interval,
max_date_end,
): ):
next_period_date_end = self._get_next_period_date_end( next_period_date_end = self._get_next_period_date_end(
next_period_date_start, next_period_date_start,
recurring_rule_type, recurring_rule_type,
recurring_interval, recurring_interval,
max_date_end=False, # TODO
max_date_end=max_date_end,
) )
if not next_period_date_end:
return False
if recurring_rule_type == 'monthlylastday': if recurring_rule_type == 'monthlylastday':
return next_period_date_end
recurring_next_date = next_period_date_end
elif recurring_invoicing_type == 'pre-paid': elif recurring_invoicing_type == 'pre-paid':
return next_period_date_start
recurring_next_date = next_period_date_start
else: # post-paid else: # post-paid
return next_period_date_end + relativedelta(days=1)
recurring_next_date = next_period_date_end + relativedelta(days=1)
return recurring_next_date
@api.model @api.model
def _get_next_period_date_end( def _get_next_period_date_end(
@ -385,6 +389,9 @@ class ContractLine(models.Model):
max_date_end, max_date_end,
): ):
"""Compute the end date for the next period""" """Compute the end date for the next period"""
if max_date_end and next_period_date_start > max_date_end:
# start is past max date end: there is no next period
return False
if recurring_rule_type == 'monthlylastday': if recurring_rule_type == 'monthlylastday':
next_period_date_end = ( next_period_date_end = (
next_period_date_start next_period_date_start
@ -401,6 +408,7 @@ class ContractLine(models.Model):
- relativedelta(days=1) - relativedelta(days=1)
) )
if max_date_end and next_period_date_end > max_date_end: if max_date_end and next_period_date_end > max_date_end:
# end date is past max_date_end: trim it
next_period_date_end = max_date_end next_period_date_end = max_date_end
return next_period_date_end return next_period_date_end
@ -435,6 +443,7 @@ class ContractLine(models.Model):
@api.onchange( @api.onchange(
'date_start', 'date_start',
'date_end',
'recurring_invoicing_type', 'recurring_invoicing_type',
'recurring_rule_type', 'recurring_rule_type',
'recurring_interval', 'recurring_interval',
@ -446,6 +455,7 @@ class ContractLine(models.Model):
rec.recurring_invoicing_type, rec.recurring_invoicing_type,
rec.recurring_rule_type, rec.recurring_rule_type,
rec.recurring_interval, rec.recurring_interval,
max_date_end=rec.date_end,
) )
@api.constrains('is_canceled', 'is_auto_renew') @api.constrains('is_canceled', 'is_auto_renew')
@ -682,15 +692,22 @@ class ContractLine(models.Model):
) )
) )
new_date_start = rec.date_start + delay_delta new_date_start = rec.date_start + delay_delta
rec.recurring_next_date = self._get_recurring_next_date(
if rec.date_end:
new_date_end = rec.date_end + delay_delta
else:
new_date_end = False
new_recurring_next_date = self._get_recurring_next_date(
new_date_start, new_date_start,
rec.recurring_invoicing_type, rec.recurring_invoicing_type,
rec.recurring_rule_type, rec.recurring_rule_type,
rec.recurring_interval, rec.recurring_interval,
max_date_end=new_date_end
) )
if rec.date_end:
rec.date_end += delay_delta
rec.date_start = new_date_start
rec.write({
"date_start": new_date_start,
"date_end": new_date_end,
"recurring_next_date": new_recurring_next_date,
})
@api.multi @api.multi
def stop(self, date_end, manual_renew_needed=False, post_message=True): def stop(self, date_end, manual_renew_needed=False, post_message=True):
@ -748,6 +765,7 @@ class ContractLine(models.Model):
self.recurring_invoicing_type, self.recurring_invoicing_type,
self.recurring_rule_type, self.recurring_rule_type,
self.recurring_interval, self.recurring_interval,
max_date_end=date_end,
) )
new_vals = self.read()[0] new_vals = self.read()[0]
new_vals.pop("id", None) new_vals.pop("id", None)

52
contract/tests/test_contract.py

@ -547,6 +547,7 @@ class TestContract(TestContractBase):
recurring_rule_type, # ('daily', 'weekly', 'monthly', recurring_rule_type, # ('daily', 'weekly', 'monthly',
# 'monthlylastday', 'yearly'), # 'monthlylastday', 'yearly'),
recurring_interval, # integer recurring_interval, # integer
max_date_end, # date
), ),
} }
""" """
@ -556,50 +557,81 @@ class TestContract(TestContractBase):
recurring_invoicing_type, recurring_invoicing_type,
recurring_rule_type, recurring_rule_type,
recurring_interval, recurring_interval,
max_date_end,
): ):
return "Error in %s every %d %s case, start with %s " % (
return "Error in %s every %d %s case, start with %s (max_date_end=%s)" % (
recurring_invoicing_type, recurring_invoicing_type,
recurring_interval, recurring_interval,
recurring_rule_type, recurring_rule_type,
date_start, date_start,
max_date_end,
) )
combinations = [ combinations = [
( (
to_date('2018-01-01'), to_date('2018-01-01'),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 1),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 1,
False),
), ),
( (
to_date('2018-01-01'), to_date('2018-01-01'),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 2),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 1,
to_date('2018-01-15')),
),
(
False,
(to_date('2018-01-16'), 'pre-paid', 'monthly', 1,
to_date('2018-01-15')),
),
(
to_date('2018-01-01'),
(to_date('2018-01-01'), 'pre-paid', 'monthly', 2,
False),
), ),
( (
to_date('2018-02-01'), to_date('2018-02-01'),
(to_date('2018-01-01'), 'post-paid', 'monthly', 1),
(to_date('2018-01-01'), 'post-paid', 'monthly', 1,
False),
),
(
to_date('2018-01-16'),
(to_date('2018-01-01'), 'post-paid', 'monthly', 1,
to_date('2018-01-15')),
),
(
False,
(to_date('2018-01-16'), 'post-paid', 'monthly', 1,
to_date('2018-01-15')),
), ),
( (
to_date('2018-03-01'), to_date('2018-03-01'),
(to_date('2018-01-01'), 'post-paid', 'monthly', 2),
(to_date('2018-01-01'), 'post-paid', 'monthly', 2,
False),
), ),
( (
to_date('2018-01-31'), to_date('2018-01-31'),
(to_date('2018-01-05'), 'post-paid', 'monthlylastday', 1),
(to_date('2018-01-05'), 'post-paid', 'monthlylastday', 1,
False),
), ),
( (
to_date('2018-01-31'), to_date('2018-01-31'),
(to_date('2018-01-06'), 'pre-paid', 'monthlylastday', 1),
(to_date('2018-01-06'), 'pre-paid', 'monthlylastday', 1,
False),
), ),
( (
to_date('2018-02-28'), to_date('2018-02-28'),
(to_date('2018-01-05'), 'pre-paid', 'monthlylastday', 2),
(to_date('2018-01-05'), 'pre-paid', 'monthlylastday', 2,
False),
), ),
( (
to_date('2018-01-05'), to_date('2018-01-05'),
(to_date('2018-01-05'), 'pre-paid', 'yearly', 1),
(to_date('2018-01-05'), 'pre-paid', 'yearly', 1,
False),
), ),
( (
to_date('2019-01-05'), to_date('2019-01-05'),
(to_date('2018-01-05'), 'post-paid', 'yearly', 1),
(to_date('2018-01-05'), 'post-paid', 'yearly', 1,
False),
), ),
] ]
contract_line_env = self.env['contract.line'] contract_line_env = self.env['contract.line']

Loading…
Cancel
Save