mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[IMP] - improve cancel/uncancel process
[FIX] - Test if start_date is set before compute [FIX] - date_end include in the period in auto_renew case [FIX] - in suspension case, contract line should start a day after the end [IMP] - confirm message on contract line cancel
This commit is contained in:
@@ -6,7 +6,14 @@ from odoo.fields import Date
|
|||||||
|
|
||||||
CRITERIA = namedtuple(
|
CRITERIA = namedtuple(
|
||||||
'CRITERIA',
|
'CRITERIA',
|
||||||
['WHEN', 'HAS_DATE_END', 'IS_AUTO_RENEW', 'HAS_SUCCESSOR', 'CANCELED'],
|
[
|
||||||
|
'WHEN',
|
||||||
|
'HAS_DATE_END',
|
||||||
|
'IS_AUTO_RENEW',
|
||||||
|
'HAS_SUCCESSOR',
|
||||||
|
'PREDECESSOR_HAS_SUCCESSOR',
|
||||||
|
'CANCELED',
|
||||||
|
],
|
||||||
)
|
)
|
||||||
ALLOWED = namedtuple(
|
ALLOWED = namedtuple(
|
||||||
'ALLOWED',
|
'ALLOWED',
|
||||||
@@ -19,6 +26,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=True,
|
IS_AUTO_RENEW=True,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -32,6 +40,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=True,
|
HAS_SUCCESSOR=True,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -45,6 +54,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=True,
|
PLAN_SUCCESSOR=True,
|
||||||
@@ -58,6 +68,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=False,
|
HAS_DATE_END=False,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -71,6 +82,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=True,
|
IS_AUTO_RENEW=True,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -84,6 +96,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=True,
|
HAS_SUCCESSOR=True,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -97,6 +110,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=True,
|
PLAN_SUCCESSOR=True,
|
||||||
@@ -110,6 +124,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=False,
|
HAS_DATE_END=False,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -123,6 +138,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=True,
|
IS_AUTO_RENEW=True,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -136,6 +152,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=True,
|
HAS_SUCCESSOR=True,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -149,6 +166,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=True,
|
HAS_DATE_END=True,
|
||||||
IS_AUTO_RENEW=False,
|
IS_AUTO_RENEW=False,
|
||||||
HAS_SUCCESSOR=False,
|
HAS_SUCCESSOR=False,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=False,
|
CANCELED=False,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=True,
|
PLAN_SUCCESSOR=True,
|
||||||
@@ -162,6 +180,7 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
HAS_DATE_END=None,
|
HAS_DATE_END=None,
|
||||||
IS_AUTO_RENEW=None,
|
IS_AUTO_RENEW=None,
|
||||||
HAS_SUCCESSOR=None,
|
HAS_SUCCESSOR=None,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=False,
|
||||||
CANCELED=True,
|
CANCELED=True,
|
||||||
): ALLOWED(
|
): ALLOWED(
|
||||||
PLAN_SUCCESSOR=False,
|
PLAN_SUCCESSOR=False,
|
||||||
@@ -170,6 +189,20 @@ CRITERIA_ALLOWED_DICT = {
|
|||||||
CANCEL=False,
|
CANCEL=False,
|
||||||
UN_CANCEL=True,
|
UN_CANCEL=True,
|
||||||
),
|
),
|
||||||
|
CRITERIA(
|
||||||
|
WHEN=None,
|
||||||
|
HAS_DATE_END=None,
|
||||||
|
IS_AUTO_RENEW=None,
|
||||||
|
HAS_SUCCESSOR=None,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=True,
|
||||||
|
CANCELED=True,
|
||||||
|
): ALLOWED(
|
||||||
|
PLAN_SUCCESSOR=False,
|
||||||
|
STOP_PLAN_SUCCESSOR=False,
|
||||||
|
STOP=False,
|
||||||
|
CANCEL=False,
|
||||||
|
UN_CANCEL=False,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -187,14 +220,29 @@ def compute_criteria(
|
|||||||
date_end,
|
date_end,
|
||||||
is_auto_renew,
|
is_auto_renew,
|
||||||
successor_contract_line_id,
|
successor_contract_line_id,
|
||||||
|
predecessor_contract_line_id,
|
||||||
is_canceled,
|
is_canceled,
|
||||||
):
|
):
|
||||||
if is_canceled:
|
if is_canceled:
|
||||||
|
if (
|
||||||
|
not predecessor_contract_line_id
|
||||||
|
or not predecessor_contract_line_id.successor_contract_line_id
|
||||||
|
):
|
||||||
return CRITERIA(
|
return CRITERIA(
|
||||||
WHEN=None,
|
WHEN=None,
|
||||||
HAS_DATE_END=None,
|
HAS_DATE_END=None,
|
||||||
IS_AUTO_RENEW=None,
|
IS_AUTO_RENEW=None,
|
||||||
HAS_SUCCESSOR=None,
|
HAS_SUCCESSOR=None,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=False,
|
||||||
|
CANCELED=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return CRITERIA(
|
||||||
|
WHEN=None,
|
||||||
|
HAS_DATE_END=None,
|
||||||
|
IS_AUTO_RENEW=None,
|
||||||
|
HAS_SUCCESSOR=None,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=True,
|
||||||
CANCELED=True,
|
CANCELED=True,
|
||||||
)
|
)
|
||||||
when = compute_when(date_start, date_end)
|
when = compute_when(date_start, date_end)
|
||||||
@@ -207,6 +255,7 @@ def compute_criteria(
|
|||||||
HAS_DATE_END=has_date_end,
|
HAS_DATE_END=has_date_end,
|
||||||
IS_AUTO_RENEW=is_auto_renew,
|
IS_AUTO_RENEW=is_auto_renew,
|
||||||
HAS_SUCCESSOR=has_successor,
|
HAS_SUCCESSOR=has_successor,
|
||||||
|
PREDECESSOR_HAS_SUCCESSOR=None,
|
||||||
CANCELED=canceled,
|
CANCELED=canceled,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -216,6 +265,7 @@ def get_allowed(
|
|||||||
date_end,
|
date_end,
|
||||||
is_auto_renew,
|
is_auto_renew,
|
||||||
successor_contract_line_id,
|
successor_contract_line_id,
|
||||||
|
predecessor_contract_line_id,
|
||||||
is_canceled,
|
is_canceled,
|
||||||
):
|
):
|
||||||
criteria = compute_criteria(
|
criteria = compute_criteria(
|
||||||
@@ -223,6 +273,7 @@ def get_allowed(
|
|||||||
date_end,
|
date_end,
|
||||||
is_auto_renew,
|
is_auto_renew,
|
||||||
successor_contract_line_id,
|
successor_contract_line_id,
|
||||||
|
predecessor_contract_line_id,
|
||||||
is_canceled,
|
is_canceled,
|
||||||
)
|
)
|
||||||
if criteria in CRITERIA_ALLOWED_DICT:
|
if criteria in CRITERIA_ALLOWED_DICT:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Copyright 2017 LasLabs Inc.
|
# Copyright 2017 LasLabs Inc.
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
from odoo import api, fields, models, _
|
from odoo import api, fields, models, _
|
||||||
@@ -91,15 +92,18 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
'date_end',
|
'date_end',
|
||||||
'is_auto_renew',
|
'is_auto_renew',
|
||||||
'successor_contract_line_id',
|
'successor_contract_line_id',
|
||||||
|
'predecessor_contract_line_id',
|
||||||
'is_canceled',
|
'is_canceled',
|
||||||
)
|
)
|
||||||
def _compute_allowed(self):
|
def _compute_allowed(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
|
if rec.date_start:
|
||||||
allowed = get_allowed(
|
allowed = get_allowed(
|
||||||
rec.date_start,
|
rec.date_start,
|
||||||
rec.date_end,
|
rec.date_end,
|
||||||
rec.is_auto_renew,
|
rec.is_auto_renew,
|
||||||
rec.successor_contract_line_id,
|
rec.successor_contract_line_id,
|
||||||
|
rec.predecessor_contract_line_id,
|
||||||
rec.is_canceled,
|
rec.is_canceled,
|
||||||
)
|
)
|
||||||
if allowed:
|
if allowed:
|
||||||
@@ -185,9 +189,13 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
"""Date end should be auto-computed if a contract line is set to
|
"""Date end should be auto-computed if a contract line is set to
|
||||||
auto_renew"""
|
auto_renew"""
|
||||||
for rec in self.filtered('is_auto_renew'):
|
for rec in self.filtered('is_auto_renew'):
|
||||||
rec.date_end = self.date_start + self.get_relative_delta(
|
rec.date_end = (
|
||||||
|
self.date_start
|
||||||
|
+ self.get_relative_delta(
|
||||||
rec.auto_renew_rule_type, rec.auto_renew_interval
|
rec.auto_renew_rule_type, rec.auto_renew_interval
|
||||||
)
|
)
|
||||||
|
- relativedelta(days=1)
|
||||||
|
)
|
||||||
|
|
||||||
@api.onchange(
|
@api.onchange(
|
||||||
'date_start',
|
'date_start',
|
||||||
@@ -255,6 +263,7 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
def _compute_create_invoice_visibility(self):
|
def _compute_create_invoice_visibility(self):
|
||||||
today = fields.Date.today()
|
today = fields.Date.today()
|
||||||
for line in self:
|
for line in self:
|
||||||
|
if line.date_start:
|
||||||
if today < line.date_start:
|
if today < line.date_start:
|
||||||
line.create_invoice_visibility = False
|
line.create_invoice_visibility = False
|
||||||
elif not line.date_end:
|
elif not line.date_end:
|
||||||
@@ -268,7 +277,8 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
line.create_invoice_visibility = (
|
line.create_invoice_visibility = (
|
||||||
line.recurring_next_date
|
line.recurring_next_date
|
||||||
- line.get_relative_delta(
|
- line.get_relative_delta(
|
||||||
line.recurring_rule_type, line.recurring_interval
|
line.recurring_rule_type,
|
||||||
|
line.recurring_interval,
|
||||||
)
|
)
|
||||||
) <= line.date_end
|
) <= line.date_end
|
||||||
|
|
||||||
@@ -577,9 +587,9 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
for rec in self:
|
for rec in self:
|
||||||
if rec.date_start >= date_start:
|
if rec.date_start >= date_start:
|
||||||
if rec.date_start < date_end:
|
if rec.date_start < date_end:
|
||||||
delay = date_end - rec.date_start
|
delay = (date_end - rec.date_start) + timedelta(days=1)
|
||||||
else:
|
else:
|
||||||
delay = date_end - date_start
|
delay = (date_end - date_start) + timedelta(days=1)
|
||||||
rec.delay(delay)
|
rec.delay(delay)
|
||||||
contract_line |= rec
|
contract_line |= rec
|
||||||
else:
|
else:
|
||||||
@@ -626,6 +636,9 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
contract.message_post(body=msg)
|
contract.message_post(body=msg)
|
||||||
|
self.mapped('predecessor_contract_line_id').write(
|
||||||
|
{'successor_contract_line_id': False}
|
||||||
|
)
|
||||||
return self.write({'is_canceled': True})
|
return self.write({'is_canceled': True})
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@@ -644,9 +657,14 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
contract.message_post(body=msg)
|
contract.message_post(body=msg)
|
||||||
return self.write(
|
for rec in self:
|
||||||
{'is_canceled': False, 'recurring_next_date': recurring_next_date}
|
if rec.predecessor_contract_line_id:
|
||||||
|
rec.predecessor_contract_line_id.successor_contract_line_id = (
|
||||||
|
rec
|
||||||
)
|
)
|
||||||
|
rec.is_canceled = False
|
||||||
|
rec.recurring_next_date = recurring_next_date
|
||||||
|
return True
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def action_uncancel(self):
|
def action_uncancel(self):
|
||||||
@@ -739,10 +757,14 @@ class AccountAnalyticInvoiceLine(models.Model):
|
|||||||
@api.multi
|
@api.multi
|
||||||
def _get_renewal_dates(self):
|
def _get_renewal_dates(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
date_start = self.date_end
|
date_start = self.date_end + relativedelta(days=1)
|
||||||
date_end = date_start + self.get_relative_delta(
|
date_end = (
|
||||||
|
date_start
|
||||||
|
+ self.get_relative_delta(
|
||||||
self.auto_renew_rule_type, self.auto_renew_interval
|
self.auto_renew_rule_type, self.auto_renew_interval
|
||||||
)
|
)
|
||||||
|
- relativedelta(days=1)
|
||||||
|
)
|
||||||
return date_start, date_end
|
return date_start, date_end
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# Copyright 2018 Tecnativa - Pedro M. Baeza
|
# Copyright 2018 Tecnativa - Pedro M. Baeza
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from odoo import fields
|
from odoo import fields
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import ValidationError
|
||||||
@@ -828,10 +829,11 @@ class TestContract(TestContractBase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_start,
|
self.acct_line.date_start,
|
||||||
start_date + (suspension_end - start_date),
|
start_date + (suspension_end - start_date) + timedelta(days=1),
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_end, end_date + (suspension_end - start_date)
|
self.acct_line.date_end,
|
||||||
|
end_date + (suspension_end - start_date) + timedelta(days=1),
|
||||||
)
|
)
|
||||||
new_line = self.env['account.analytic.invoice.line'].search(
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
||||||
@@ -860,10 +862,11 @@ class TestContract(TestContractBase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_start,
|
self.acct_line.date_start,
|
||||||
start_date + (suspension_end - start_date),
|
start_date + (suspension_end - start_date) + timedelta(days=1),
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_end, end_date + (suspension_end - start_date)
|
self.acct_line.date_end,
|
||||||
|
end_date + (suspension_end - start_date) + timedelta(days=1),
|
||||||
)
|
)
|
||||||
new_line = self.env['account.analytic.invoice.line'].search(
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
||||||
@@ -893,7 +896,7 @@ class TestContract(TestContractBase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_start,
|
self.acct_line.date_start,
|
||||||
start_date + (suspension_end - start_date),
|
start_date + (suspension_end - start_date) + timedelta(days=1),
|
||||||
)
|
)
|
||||||
self.assertFalse(self.acct_line.date_end)
|
self.assertFalse(self.acct_line.date_end)
|
||||||
new_line = self.env['account.analytic.invoice.line'].search(
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
@@ -923,11 +926,13 @@ class TestContract(TestContractBase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_start,
|
self.acct_line.date_start,
|
||||||
start_date + (suspension_end - suspension_start),
|
start_date
|
||||||
|
+ (suspension_end - suspension_start)
|
||||||
|
+ timedelta(days=1),
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_end,
|
self.acct_line.date_end,
|
||||||
end_date + (suspension_end - suspension_start),
|
end_date + (suspension_end - suspension_start) + timedelta(days=1),
|
||||||
)
|
)
|
||||||
new_line = self.env['account.analytic.invoice.line'].search(
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
||||||
@@ -957,7 +962,9 @@ class TestContract(TestContractBase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_start,
|
self.acct_line.date_start,
|
||||||
start_date + (suspension_end - suspension_start),
|
start_date
|
||||||
|
+ (suspension_end - suspension_start)
|
||||||
|
+ timedelta(days=1),
|
||||||
)
|
)
|
||||||
self.assertFalse(self.acct_line.date_end)
|
self.assertFalse(self.acct_line.date_end)
|
||||||
new_line = self.env['account.analytic.invoice.line'].search(
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
@@ -988,11 +995,13 @@ class TestContract(TestContractBase):
|
|||||||
wizard.stop_plan_successor()
|
wizard.stop_plan_successor()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_start,
|
self.acct_line.date_start,
|
||||||
start_date + (suspension_end - suspension_start),
|
start_date
|
||||||
|
+ (suspension_end - suspension_start)
|
||||||
|
+ timedelta(days=1),
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.date_end,
|
self.acct_line.date_end,
|
||||||
end_date + (suspension_end - suspension_start),
|
end_date + (suspension_end - suspension_start) + timedelta(days=1),
|
||||||
)
|
)
|
||||||
new_line = self.env['account.analytic.invoice.line'].search(
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
||||||
@@ -1087,6 +1096,62 @@ class TestContract(TestContractBase):
|
|||||||
self.acct_line.uncancel(fields.Date.today())
|
self.acct_line.uncancel(fields.Date.today())
|
||||||
self.assertFalse(self.acct_line.is_canceled)
|
self.assertFalse(self.acct_line.is_canceled)
|
||||||
|
|
||||||
|
def test_cancel_uncancel_with_predecessor(self):
|
||||||
|
suspension_start = fields.Date.today() + relativedelta(months=3)
|
||||||
|
suspension_end = fields.Date.today() + relativedelta(months=5)
|
||||||
|
start_date = fields.Date.today()
|
||||||
|
end_date = fields.Date.today() + relativedelta(months=4)
|
||||||
|
self.acct_line.write(
|
||||||
|
{
|
||||||
|
'date_start': start_date,
|
||||||
|
'recurring_next_date': start_date,
|
||||||
|
'date_end': end_date,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.acct_line.stop_plan_successor(
|
||||||
|
suspension_start, suspension_end, True
|
||||||
|
)
|
||||||
|
self.assertEqual(self.acct_line.date_end, suspension_start)
|
||||||
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
|
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
||||||
|
)
|
||||||
|
self.assertEqual(self.acct_line.successor_contract_line_id, new_line)
|
||||||
|
new_line.cancel()
|
||||||
|
self.assertTrue(new_line.is_canceled)
|
||||||
|
self.assertFalse(self.acct_line.successor_contract_line_id)
|
||||||
|
self.assertEqual(new_line.predecessor_contract_line_id, self.acct_line)
|
||||||
|
new_line.uncancel(suspension_end)
|
||||||
|
self.assertFalse(new_line.is_canceled)
|
||||||
|
self.assertEqual(self.acct_line.successor_contract_line_id, new_line)
|
||||||
|
self.assertEqual(new_line.recurring_next_date, suspension_end)
|
||||||
|
|
||||||
|
def test_cancel_uncancel_with_predecessor_has_successor(self):
|
||||||
|
suspension_start = fields.Date.today() + relativedelta(months=6)
|
||||||
|
suspension_end = fields.Date.today() + relativedelta(months=7)
|
||||||
|
start_date = fields.Date.today()
|
||||||
|
end_date = fields.Date.today() + relativedelta(months=8)
|
||||||
|
self.acct_line.write(
|
||||||
|
{
|
||||||
|
'date_start': start_date,
|
||||||
|
'recurring_next_date': start_date,
|
||||||
|
'date_end': end_date,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.acct_line.stop_plan_successor(
|
||||||
|
suspension_start, suspension_end, True
|
||||||
|
)
|
||||||
|
new_line = self.env['account.analytic.invoice.line'].search(
|
||||||
|
[('predecessor_contract_line_id', '=', self.acct_line.id)]
|
||||||
|
)
|
||||||
|
new_line.cancel()
|
||||||
|
suspension_start = fields.Date.today() + relativedelta(months=4)
|
||||||
|
suspension_end = fields.Date.today() + relativedelta(months=5)
|
||||||
|
self.acct_line.stop_plan_successor(
|
||||||
|
suspension_start, suspension_end, True
|
||||||
|
)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
new_line.uncancel(suspension_end)
|
||||||
|
|
||||||
def test_check_has_not_date_end_has_successor(self):
|
def test_check_has_not_date_end_has_successor(self):
|
||||||
self.acct_line.write({'date_end': False, 'is_auto_renew': False})
|
self.acct_line.write({'date_end': False, 'is_auto_renew': False})
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
@@ -1126,8 +1191,10 @@ class TestContract(TestContractBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_renew(self):
|
def test_renew(self):
|
||||||
|
self.acct_line._onchange_is_auto_renew()
|
||||||
|
self.assertEqual(self.acct_line.date_end, to_date('2018-12-31'))
|
||||||
new_line = self.acct_line.renew()
|
new_line = self.acct_line.renew()
|
||||||
self.assertFalse(self.acct_line.is_auto_renew)
|
self.assertFalse(self.acct_line.is_auto_renew)
|
||||||
self.assertTrue(new_line.is_auto_renew)
|
self.assertTrue(new_line.is_auto_renew)
|
||||||
self.assertEqual(new_line.date_start, to_date('2019-01-01'))
|
self.assertEqual(new_line.date_start, to_date('2019-01-01'))
|
||||||
self.assertEqual(new_line.date_end, to_date('2020-01-01'))
|
self.assertEqual(new_line.date_end, to_date('2019-12-31'))
|
||||||
|
|||||||
@@ -131,6 +131,7 @@
|
|||||||
<button name="cancel" string="Cancel"
|
<button name="cancel" string="Cancel"
|
||||||
type="object"
|
type="object"
|
||||||
icon="fa-ban text-danger"
|
icon="fa-ban text-danger"
|
||||||
|
confirm="Are you sure you want to cancel this line"
|
||||||
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"/>
|
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"/>
|
||||||
<button name="action_uncancel"
|
<button name="action_uncancel"
|
||||||
string="Un-cancel" type="object"
|
string="Un-cancel" type="object"
|
||||||
|
|||||||
Reference in New Issue
Block a user