diff --git a/contract/models/contract.py b/contract/models/contract.py index 00344e49..8a7dfd00 100644 --- a/contract/models/contract.py +++ b/contract/models/contract.py @@ -56,11 +56,14 @@ class AccountAnalyticAccount(models.Model): if date_end and all(date_end): contract.date_end = max(date_end) - @api.depends('recurring_invoice_line_ids.recurring_next_date') + @api.depends( + 'recurring_invoice_line_ids.recurring_next_date', + 'recurring_invoice_line_ids.is_canceled', + ) def _compute_recurring_next_date(self): for contract in self: recurring_next_date = contract.recurring_invoice_line_ids.filtered( - 'recurring_next_date' + lambda l: l.recurring_next_date and not l.is_canceled ).mapped('recurring_next_date') if recurring_next_date: contract.recurring_next_date = min(recurring_next_date) diff --git a/contract/models/contract_line.py b/contract/models/contract_line.py index 9bd58638..63d01029 100644 --- a/contract/models/contract_line.py +++ b/contract/models/contract_line.py @@ -29,7 +29,7 @@ class AccountAnalyticInvoiceLine(models.Model): date_end = fields.Date(string='Date End', index=True) recurring_next_date = fields.Date(string='Date of Next Invoice') last_date_invoiced = fields.Date( - string='Last Date Invoiced', readonly=True + string='Last Date Invoiced', readonly=True, copy=False ) create_invoice_visibility = fields.Boolean( compute='_compute_create_invoice_visibility' @@ -403,17 +403,20 @@ class AccountAnalyticInvoiceLine(models.Model): else self.date_start ) if self.recurring_rule_type == 'monthlylastday': - last_date_invoiced = first_date_invoiced + self.get_relative_delta( - self.recurring_rule_type, self.recurring_interval - 1 - ) + last_date_invoiced = self.recurring_next_date else: - last_date_invoiced = ( - first_date_invoiced - + self.get_relative_delta( - self.recurring_rule_type, self.recurring_interval + if self.recurring_invoicing_type == 'pre-paid': + last_date_invoiced = ( + self.recurring_next_date + + self.get_relative_delta( + self.recurring_rule_type, self.recurring_interval + ) + - relativedelta(days=1) + ) + else: + last_date_invoiced = self.recurring_next_date - relativedelta( + days=1 ) - - relativedelta(days=1) - ) if self.date_end and self.date_end < last_date_invoiced: last_date_invoiced = self.date_end return first_date_invoiced, last_date_invoiced diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index 8843ddcc..d427692f 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -159,6 +159,24 @@ class TestContract(TestContractBase): self.contract.partner_id.user_id, self.invoice_monthly.user_id ) + def test_contract_recurring_next_date(self): + recurring_next_date = to_date('2018-01-15') + self.assertEqual( + self.contract.recurring_next_date, recurring_next_date + ) + contract_line = self.acct_line.copy( + {'recurring_next_date': '2018-01-14'} + ) + recurring_next_date = to_date('2018-01-14') + self.assertEqual( + self.contract.recurring_next_date, recurring_next_date + ) + contract_line.cancel() + recurring_next_date = to_date('2018-01-15') + self.assertEqual( + self.contract.recurring_next_date, recurring_next_date + ) + def test_contract_daily(self): recurring_next_date = to_date('2018-02-23') last_date_invoiced = to_date('2018-02-22') @@ -1299,6 +1317,36 @@ class TestContract(TestContractBase): self.assertEqual(first, to_date('2018-03-01')) self.assertEqual(last, to_date('2018-03-15')) + def test_get_invoiced_period_monthly_pre_paid_2(self): + self.acct_line.date_start = '2018-01-05' + self.acct_line.recurring_invoicing_type = 'pre-paid' + self.acct_line.recurring_rule_type = 'monthly' + self.acct_line.date_end = '2018-08-15' + self.acct_line._onchange_date_start() + self.contract.recurring_create_invoice() + first, last = self.acct_line._get_invoiced_period() + self.assertEqual(first, to_date('2018-02-05')) + self.assertEqual(last, to_date('2018-03-04')) + self.acct_line.recurring_next_date = '2018-06-05' + first, last = self.acct_line._get_invoiced_period() + self.assertEqual(first, to_date('2018-02-05')) + self.assertEqual(last, to_date('2018-07-04')) + + def test_get_invoiced_period_monthly_post_paid_2(self): + self.acct_line.date_start = '2018-01-05' + self.acct_line.recurring_invoicing_type = 'post-paid' + self.acct_line.recurring_rule_type = 'monthly' + self.acct_line.date_end = '2018-08-15' + self.acct_line._onchange_date_start() + self.contract.recurring_create_invoice() + first, last = self.acct_line._get_invoiced_period() + self.assertEqual(first, to_date('2018-02-05')) + self.assertEqual(last, to_date('2018-03-04')) + self.acct_line.recurring_next_date = '2018-06-05' + first, last = self.acct_line._get_invoiced_period() + self.assertEqual(first, to_date('2018-02-05')) + self.assertEqual(last, to_date('2018-06-04')) + def test_get_invoiced_period_monthly_post_paid(self): self.acct_line.date_start = '2018-01-05' self.acct_line.recurring_invoicing_type = 'post-paid'