diff --git a/contract/migrations/12.0.5.0.0/pre-migration.py b/contract/migrations/12.0.5.0.0/pre-migration.py
new file mode 100644
index 00000000..ca208e9d
--- /dev/null
+++ b/contract/migrations/12.0.5.0.0/pre-migration.py
@@ -0,0 +1,10 @@
+def migrate(cr, version):
+ # pre-paid/post-paid becomes significant for monthlylastday too,
+ # make sure it has the value that was implied for previous versions.
+ cr.execute(
+ """\
+ UPDATE contract_line
+ SET recurring_invoicing_type = 'post-paid'
+ WHERE recurring_rule_type = 'monthlylastday'
+ """
+ )
diff --git a/contract/models/contract_line.py b/contract/models/contract_line.py
index 93711c5d..1a5fa3d0 100644
--- a/contract/models/contract_line.py
+++ b/contract/models/contract_line.py
@@ -380,6 +380,22 @@ class ContractLine(models.Model):
max_date_end=False,
)
+ @api.model
+ def _get_offset(self, recurring_invoicing_type, recurring_rule_type):
+ """Return a relativedelta to offset the invoice date compared
+ to the period start or end date.
+
+ This method will disappear when the offset becomes user controlled.
+ """
+ if (
+ recurring_invoicing_type == 'pre-paid'
+ or recurring_rule_type == 'monthlylastday'
+ ):
+ offset = 0
+ else:
+ offset = 1
+ return relativedelta(days=offset)
+
@api.model
def _get_recurring_next_date(
self,
@@ -398,12 +414,11 @@ class ContractLine(models.Model):
)
if not next_period_date_end:
return False
- if recurring_rule_type == 'monthlylastday':
- recurring_next_date = next_period_date_end
- elif recurring_invoicing_type == 'pre-paid':
- recurring_next_date = next_period_date_start
+ offset = self._get_offset(recurring_invoicing_type, recurring_rule_type)
+ if recurring_invoicing_type == 'pre-paid':
+ recurring_next_date = next_period_date_start + offset
else: # post-paid
- recurring_next_date = next_period_date_end + relativedelta(days=1)
+ recurring_next_date = next_period_date_end + offset
return recurring_next_date
@api.model
@@ -433,20 +448,18 @@ class ContractLine(models.Model):
)
else:
# special algorithm when the next invoice date is forced
- if recurring_rule_type == 'monthlylastday':
- next_period_date_end = next_invoice_date
- elif recurring_invoicing_type == 'pre-paid':
+ offset = self._get_offset(recurring_invoicing_type, recurring_rule_type)
+ if recurring_invoicing_type == 'pre-paid':
next_period_date_end = (
next_invoice_date
+ - offset
+ self.get_relative_delta(
recurring_rule_type, recurring_interval
)
- relativedelta(days=1)
)
else: # post-paid
- next_period_date_end = next_invoice_date - relativedelta(
- days=1
- )
+ next_period_date_end = next_invoice_date - offset
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
diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py
index 925ab2ce..e6bf09ec 100644
--- a/contract/tests/test_contract.py
+++ b/contract/tests/test_contract.py
@@ -614,12 +614,17 @@ class TestContract(TestContractBase):
False),
),
(
- to_date('2018-01-31'),
+ to_date('2018-01-06'),
(to_date('2018-01-06'), 'pre-paid', 'monthlylastday', 1,
False),
),
(
to_date('2018-02-28'),
+ (to_date('2018-01-05'), 'post-paid', 'monthlylastday', 2,
+ False),
+ ),
+ (
+ to_date('2018-01-05'),
(to_date('2018-01-05'), 'pre-paid', 'monthlylastday', 2,
False),
),
@@ -1363,7 +1368,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 +1399,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'
diff --git a/contract/views/abstract_contract_line.xml b/contract/views/abstract_contract_line.xml
index b66077ee..351ded65 100644
--- a/contract/views/abstract_contract_line.xml
+++ b/contract/views/abstract_contract_line.xml
@@ -59,8 +59,7 @@
-
+
diff --git a/contract_sale_mandate/tests/test_contract_sale_mandate.py b/contract_sale_mandate/tests/test_contract_sale_mandate.py
index eb36adcd..04515133 100644
--- a/contract_sale_mandate/tests/test_contract_sale_mandate.py
+++ b/contract_sale_mandate/tests/test_contract_sale_mandate.py
@@ -26,6 +26,7 @@ class TestContractSaleMandate(TestContractBase):
'is_contract': True,
'default_qty': 12,
'recurring_rule_type': "monthlylastday",
+ 'recurring_invoicing_type': "post-paid",
'contract_template_id': cls.contract_template1.id,
}
)
diff --git a/product_contract/tests/test_sale_order.py b/product_contract/tests/test_sale_order.py
index 7a630cbb..307cf908 100644
--- a/product_contract/tests/test_sale_order.py
+++ b/product_contract/tests/test_sale_order.py
@@ -43,6 +43,7 @@ class TestSaleOrder(TransactionCase):
'is_contract': True,
'default_qty': 12,
'recurring_rule_type': "monthlylastday",
+ 'recurring_invoicing_type': "post-paid",
'contract_template_id': self.contract_template1.id,
}
)
diff --git a/product_contract/views/product_template.xml b/product_contract/views/product_template.xml
index 400afa99..057ec95b 100644
--- a/product_contract/views/product_template.xml
+++ b/product_contract/views/product_template.xml
@@ -33,8 +33,7 @@
-
+
diff --git a/product_contract/views/sale_order.xml b/product_contract/views/sale_order.xml
index e5da25fe..4fd1b90b 100644
--- a/product_contract/views/sale_order.xml
+++ b/product_contract/views/sale_order.xml
@@ -58,8 +58,7 @@
-
+