mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[IMP] - store last_date_invoiced on contract_line
Improve CRITERIA_ALLOWED_DICT [IMP] - code improvement [IMP] - Use last_date_invoiced to set marker in invoice description [IMP] - add migration script to init last_day_invoiced and some other improvement [FIX] - a contract line suspended should start a day after the suspension end
This commit is contained in:
committed by
Francisco Ivan Anton Prieto
parent
0275254a4f
commit
c83f3162a0
@@ -7,7 +7,7 @@ from dateutil.relativedelta import relativedelta
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
from ..data.contract_line_constraints import get_allowed
|
||||
from .contract_line_constraints import get_allowed
|
||||
|
||||
|
||||
class AccountAnalyticInvoiceLine(models.Model):
|
||||
@@ -16,14 +16,21 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
|
||||
contract_id = fields.Many2one(
|
||||
comodel_name='account.analytic.account',
|
||||
string='Analytic Account',
|
||||
string='Contract',
|
||||
required=True,
|
||||
index=True,
|
||||
ondelete='cascade',
|
||||
oldname='analytic_account_id',
|
||||
)
|
||||
date_start = fields.Date(string='Date Start', default=fields.Date.today())
|
||||
date_start = fields.Date(
|
||||
string='Date Start',
|
||||
default=lambda self: fields.Date.context_today(self),
|
||||
)
|
||||
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
|
||||
)
|
||||
create_invoice_visibility = fields.Boolean(
|
||||
compute='_compute_create_invoice_visibility'
|
||||
)
|
||||
@@ -33,7 +40,8 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
required=False,
|
||||
readonly=True,
|
||||
copy=False,
|
||||
help="Contract Line created by this one.",
|
||||
help="In case of restart after suspension, this field contain the new "
|
||||
"contract line created.",
|
||||
)
|
||||
predecessor_contract_line_id = fields.Many2one(
|
||||
comodel_name='account.analytic.invoice.line',
|
||||
@@ -72,7 +80,7 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
|
||||
@api.multi
|
||||
def _compute_state(self):
|
||||
today = fields.Date.today()
|
||||
today = fields.Date.context_today(self)
|
||||
for rec in self:
|
||||
if rec.is_canceled:
|
||||
rec.state = 'canceled'
|
||||
@@ -90,6 +98,7 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
@api.depends(
|
||||
'date_start',
|
||||
'date_end',
|
||||
'last_date_invoiced',
|
||||
'is_auto_renew',
|
||||
'successor_contract_line_id',
|
||||
'predecessor_contract_line_id',
|
||||
@@ -101,19 +110,20 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
allowed = get_allowed(
|
||||
rec.date_start,
|
||||
rec.date_end,
|
||||
rec.last_date_invoiced,
|
||||
rec.is_auto_renew,
|
||||
rec.successor_contract_line_id,
|
||||
rec.predecessor_contract_line_id,
|
||||
rec.is_canceled,
|
||||
)
|
||||
if allowed:
|
||||
rec.is_plan_successor_allowed = allowed.PLAN_SUCCESSOR
|
||||
rec.is_plan_successor_allowed = allowed.plan_successor
|
||||
rec.is_stop_plan_successor_allowed = (
|
||||
allowed.STOP_PLAN_SUCCESSOR
|
||||
allowed.stop_plan_successor
|
||||
)
|
||||
rec.is_stop_allowed = allowed.STOP
|
||||
rec.is_cancel_allowed = allowed.CANCEL
|
||||
rec.is_un_cancel_allowed = allowed.UN_CANCEL
|
||||
rec.is_stop_allowed = allowed.stop
|
||||
rec.is_cancel_allowed = allowed.cancel
|
||||
rec.is_un_cancel_allowed = allowed.uncancel
|
||||
|
||||
@api.constrains('is_auto_renew', 'successor_contract_line_id', 'date_end')
|
||||
def _check_allowed(self):
|
||||
@@ -135,14 +145,14 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
)
|
||||
if not rec.date_end:
|
||||
raise ValidationError(
|
||||
_("An auto-renew line should have a " "date end ")
|
||||
_("An auto-renew line must have a end date")
|
||||
)
|
||||
else:
|
||||
if not rec.date_end and rec.successor_contract_line_id:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"A contract line with a successor "
|
||||
"should have date end"
|
||||
"must have a end date"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -150,7 +160,7 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
def _check_overlap_successor(self):
|
||||
for rec in self:
|
||||
if rec.date_end and rec.successor_contract_line_id:
|
||||
if rec.date_end > rec.successor_contract_line_id.date_start:
|
||||
if rec.date_end >= rec.successor_contract_line_id.date_start:
|
||||
raise ValidationError(
|
||||
_("Contract line and its successor overlapped")
|
||||
)
|
||||
@@ -159,7 +169,7 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
def _check_overlap_predecessor(self):
|
||||
for rec in self:
|
||||
if rec.predecessor_contract_line_id:
|
||||
if rec.date_start < rec.predecessor_contract_line_id.date_end:
|
||||
if rec.date_start <= rec.predecessor_contract_line_id.date_end:
|
||||
raise ValidationError(
|
||||
_("Contract line and its predecessor overlapped")
|
||||
)
|
||||
@@ -183,7 +193,10 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
)
|
||||
|
||||
@api.onchange(
|
||||
'is_auto_renew', 'auto_renew_rule_type', 'auto_renew_interval'
|
||||
'date_start',
|
||||
'is_auto_renew',
|
||||
'auto_renew_rule_type',
|
||||
'auto_renew_interval',
|
||||
)
|
||||
def _onchange_is_auto_renew(self):
|
||||
"""Date end should be auto-computed if a contract line is set to
|
||||
@@ -219,22 +232,45 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
if line.date_start > line.recurring_next_date:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"You can't have a next invoicing date before the "
|
||||
"start of the contract '%s'"
|
||||
"You can't have a date of next invoice anterior "
|
||||
"to the start of the contract line '%s'"
|
||||
)
|
||||
% line.contract_id.name
|
||||
% line.name
|
||||
)
|
||||
|
||||
@api.constrains('date_start', 'date_end', 'last_date_invoiced')
|
||||
def _check_last_date_invoiced(self):
|
||||
for rec in self.filtered('last_date_invoiced'):
|
||||
if rec.date_start and rec.date_start > rec.last_date_invoiced:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"You can't have the start date after the date of last "
|
||||
"invoice for the contract line '%s'"
|
||||
)
|
||||
% rec.name
|
||||
)
|
||||
if rec.date_end and rec.date_end < rec.last_date_invoiced:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"You can't have the end date before the date of last "
|
||||
"invoice for the contract line '%s'"
|
||||
)
|
||||
% rec.name
|
||||
)
|
||||
|
||||
@api.constrains('recurring_next_date')
|
||||
def _check_recurring_next_date_recurring_invoices(self):
|
||||
for line in self.filtered('contract_id.recurring_invoices'):
|
||||
if not line.recurring_next_date:
|
||||
for rec in self.filtered('contract_id.recurring_invoices'):
|
||||
if not rec.recurring_next_date and (
|
||||
not rec.last_date_invoiced
|
||||
or rec.last_date_invoiced < rec.date_end
|
||||
):
|
||||
raise ValidationError(
|
||||
_(
|
||||
"You must supply a next invoicing date for contract "
|
||||
"'%s'"
|
||||
"You must supply a date of next invoice for contract "
|
||||
"line '%s'"
|
||||
)
|
||||
% line.contract_id.name
|
||||
% rec.name
|
||||
)
|
||||
|
||||
@api.constrains('date_start')
|
||||
@@ -242,8 +278,8 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
for line in self.filtered('contract_id.recurring_invoices'):
|
||||
if not line.date_start:
|
||||
raise ValidationError(
|
||||
_("You must supply a start date for contract '%s'")
|
||||
% line.contract_id.name
|
||||
_("You must supply a start date for contract line '%s'")
|
||||
% line.name
|
||||
)
|
||||
|
||||
@api.constrains('date_start', 'date_end')
|
||||
@@ -253,39 +289,28 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
if line.date_start > line.date_end:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"Contract '%s' start date can't be later than "
|
||||
"end date"
|
||||
"Contract line '%s' start date can't be later than"
|
||||
" end date"
|
||||
)
|
||||
% line.contract_id.name
|
||||
% line.name
|
||||
)
|
||||
|
||||
@api.depends('recurring_next_date', 'date_start', 'date_end')
|
||||
def _compute_create_invoice_visibility(self):
|
||||
today = fields.Date.today()
|
||||
for line in self:
|
||||
if line.date_start:
|
||||
if today < line.date_start:
|
||||
line.create_invoice_visibility = False
|
||||
elif not line.date_end:
|
||||
line.create_invoice_visibility = True
|
||||
elif line.recurring_next_date:
|
||||
if line.recurring_invoicing_type == 'pre-paid':
|
||||
line.create_invoice_visibility = (
|
||||
line.recurring_next_date <= line.date_end
|
||||
)
|
||||
else:
|
||||
line.create_invoice_visibility = (
|
||||
line.recurring_next_date
|
||||
- line.get_relative_delta(
|
||||
line.recurring_rule_type,
|
||||
line.recurring_interval,
|
||||
)
|
||||
) <= line.date_end
|
||||
today = fields.Date.context_today(self)
|
||||
for rec in self:
|
||||
if rec.date_start:
|
||||
if today < rec.date_start:
|
||||
rec.create_invoice_visibility = False
|
||||
else:
|
||||
rec.create_invoice_visibility = bool(
|
||||
rec.recurring_next_date
|
||||
)
|
||||
|
||||
@api.model
|
||||
def recurring_create_invoice(self, contract=False):
|
||||
def _get_recurring_create_invoice_domain(self, contract=False):
|
||||
domain = []
|
||||
date_ref = fields.Date.today()
|
||||
date_ref = fields.Date.context_today(self)
|
||||
if contract:
|
||||
contract.ensure_one()
|
||||
date_ref = contract.recurring_next_date
|
||||
@@ -296,39 +321,36 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
('contract_id.recurring_invoices', '=', True),
|
||||
('recurring_next_date', '<=', date_ref),
|
||||
('is_canceled', '=', False),
|
||||
# '|',
|
||||
# ('date_end', '=', False),
|
||||
# ('date_end', '>=', date_ref),
|
||||
# with this leaf, it's impossible to invoice the last period
|
||||
# in post-paid case.
|
||||
# i.e: date_end = 15/03 recurring_next_date = 31/03
|
||||
# A solution for this, is to only check recurring_next_date
|
||||
# and filter with create_invoice_visibility
|
||||
]
|
||||
)
|
||||
lines = self.search(domain).filtered('create_invoice_visibility')
|
||||
if lines:
|
||||
return lines._recurring_create_invoice()
|
||||
return False
|
||||
return domain
|
||||
|
||||
@api.multi
|
||||
def _recurring_create_invoice(self):
|
||||
@api.model
|
||||
def recurring_create_invoice(self, contract=False):
|
||||
domain = self._get_recurring_create_invoice_domain(contract)
|
||||
contract_to_invoice = self.read_group(
|
||||
domain, ['id', 'contract_id'], ['contract_id']
|
||||
)
|
||||
return self._recurring_create_invoice(contract_to_invoice)
|
||||
|
||||
@api.model
|
||||
def _recurring_create_invoice(self, contract_to_invoice):
|
||||
"""Create invoices from contracts
|
||||
|
||||
:return: invoices created
|
||||
"""
|
||||
invoices = self.env['account.invoice']
|
||||
for contract in self.mapped('contract_id'):
|
||||
lines = self.filtered(lambda l: l.contract_id == contract)
|
||||
invoices |= lines._create_invoice()
|
||||
lines._update_recurring_next_date()
|
||||
for contract in contract_to_invoice:
|
||||
lines = self.search(contract['__domain'])
|
||||
if lines:
|
||||
invoices |= lines._create_invoice()
|
||||
lines._update_recurring_next_date()
|
||||
return invoices
|
||||
|
||||
@api.multi
|
||||
def _create_invoice(self):
|
||||
"""
|
||||
:param invoice: If not False add lines to this invoice
|
||||
:return: invoice created or updated
|
||||
:return: invoice created
|
||||
"""
|
||||
contract = self.mapped('contract_id')
|
||||
date_invoice = min(self.mapped('recurring_next_date'))
|
||||
@@ -359,10 +381,8 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
invoice_line_vals = invoice_line._convert_to_write(invoice_line._cache)
|
||||
# Insert markers
|
||||
contract = self.contract_id
|
||||
lang_obj = self.env['res.lang']
|
||||
lang = lang_obj.search([('code', '=', contract.partner_id.lang)])
|
||||
date_format = lang.date_format or '%m/%d/%Y'
|
||||
name = self._insert_markers(date_format)
|
||||
first_date_invoiced, last_date_invoiced = self._get_invoiced_period()
|
||||
name = self._insert_markers(first_date_invoiced, last_date_invoiced)
|
||||
invoice_line_vals.update(
|
||||
{
|
||||
'name': name,
|
||||
@@ -373,26 +393,98 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
return invoice_line_vals
|
||||
|
||||
@api.multi
|
||||
def _insert_markers(self, date_format):
|
||||
def _get_invoiced_period(self):
|
||||
self.ensure_one()
|
||||
date_from = fields.Date.from_string(self.recurring_next_date)
|
||||
date_to = date_from + self.get_relative_delta(
|
||||
self.recurring_rule_type, self.recurring_interval
|
||||
first_date_invoiced = (
|
||||
self.last_date_invoiced + relativedelta(days=1)
|
||||
if self.last_date_invoiced
|
||||
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
|
||||
)
|
||||
else:
|
||||
last_date_invoiced = (
|
||||
first_date_invoiced
|
||||
+ self.get_relative_delta(
|
||||
self.recurring_rule_type, self.recurring_interval
|
||||
)
|
||||
- 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
|
||||
|
||||
@api.multi
|
||||
def _insert_markers(self, first_date_invoiced, last_date_invoiced):
|
||||
self.ensure_one()
|
||||
lang_obj = self.env['res.lang']
|
||||
lang = lang_obj.search(
|
||||
[('code', '=', self.contract_id.partner_id.lang)]
|
||||
)
|
||||
date_format = lang.date_format or '%m/%d/%Y'
|
||||
name = self.name
|
||||
name = name.replace('#START#', date_from.strftime(date_format))
|
||||
name = name.replace('#END#', date_to.strftime(date_format))
|
||||
name = name.replace(
|
||||
'#START#', first_date_invoiced.strftime(date_format)
|
||||
)
|
||||
name = name.replace('#END#', last_date_invoiced.strftime(date_format))
|
||||
return name
|
||||
|
||||
@api.multi
|
||||
def _update_recurring_next_date(self):
|
||||
for line in self:
|
||||
ref_date = line.recurring_next_date or fields.Date.today()
|
||||
old_date = fields.Date.from_string(ref_date)
|
||||
for rec in self:
|
||||
old_date = rec.recurring_next_date
|
||||
new_date = old_date + self.get_relative_delta(
|
||||
line.recurring_rule_type, line.recurring_interval
|
||||
rec.recurring_rule_type, rec.recurring_interval
|
||||
)
|
||||
line.recurring_next_date = new_date
|
||||
|
||||
if rec.recurring_rule_type == 'monthlylastday':
|
||||
rec.last_date_invoiced = (
|
||||
old_date
|
||||
if rec.date_end and old_date < rec.date_end
|
||||
else rec.date_end
|
||||
)
|
||||
elif rec.recurring_invoicing_type == 'post-paid':
|
||||
rec.last_date_invoiced = (
|
||||
old_date - relativedelta(days=1)
|
||||
if rec.date_end and old_date < rec.date_end
|
||||
else rec.date_end
|
||||
)
|
||||
elif rec.recurring_invoicing_type == 'pre-paid':
|
||||
rec.last_date_invoiced = (
|
||||
new_date - relativedelta(days=1)
|
||||
if rec.date_end and new_date < rec.date_end
|
||||
else rec.date_end
|
||||
)
|
||||
if (
|
||||
rec.last_date_invoiced
|
||||
and rec.last_date_invoiced == rec.date_end
|
||||
):
|
||||
rec.recurring_next_date = False
|
||||
else:
|
||||
rec.recurring_next_date = new_date
|
||||
|
||||
@api.multi
|
||||
def _init_last_date_invoiced(self):
|
||||
"""Used to init last_date_invoiced for migration purpose"""
|
||||
for rec in self:
|
||||
if rec.recurring_rule_type == 'monthlylastday':
|
||||
last_date_invoiced = (
|
||||
rec.recurring_next_date
|
||||
- self.get_relative_delta(
|
||||
rec.recurring_rule_type, rec.recurring_interval
|
||||
)
|
||||
)
|
||||
elif rec.recurring_invoicing_type == 'post-paid':
|
||||
last_date_invoiced = (
|
||||
rec.recurring_next_date
|
||||
- self.get_relative_delta(
|
||||
rec.recurring_rule_type, rec.recurring_interval
|
||||
)
|
||||
) - relativedelta(days=1)
|
||||
if last_date_invoiced > rec.date_start:
|
||||
rec.last_date_invoiced = last_date_invoiced
|
||||
|
||||
@api.model
|
||||
def get_relative_delta(self, recurring_rule_type, interval):
|
||||
@@ -408,13 +500,20 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
return relativedelta(years=interval)
|
||||
|
||||
@api.multi
|
||||
def delay(self, delay_delta):
|
||||
def _delay(self, delay_delta):
|
||||
"""
|
||||
Delay a contract line
|
||||
:param delay_delta: delay relative delta
|
||||
:return: delayed contract line
|
||||
"""
|
||||
for rec in self:
|
||||
if rec.last_date_invoiced:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"You can't delay a contract line "
|
||||
"invoiced at least one time."
|
||||
)
|
||||
)
|
||||
old_date_start = rec.date_start
|
||||
old_date_end = rec.date_end
|
||||
new_date_start = rec.date_start + delay_delta
|
||||
@@ -424,30 +523,12 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
rec.recurring_rule_type,
|
||||
rec.recurring_interval,
|
||||
)
|
||||
rec.date_end = (
|
||||
rec.date_end
|
||||
if not rec.date_end
|
||||
else rec.date_end + delay_delta
|
||||
)
|
||||
if rec.date_end:
|
||||
rec.date_end += delay_delta
|
||||
rec.date_start = new_date_start
|
||||
msg = _(
|
||||
"""Contract line for <strong>{product}</strong>
|
||||
delayed: <br/>
|
||||
- <strong>Start</strong>: {old_date_start} -- {new_date_start}
|
||||
<br/>
|
||||
- <strong>End</strong>: {old_date_end} -- {new_date_end}
|
||||
""".format(
|
||||
product=rec.name,
|
||||
old_date_start=old_date_start,
|
||||
new_date_start=rec.date_start,
|
||||
old_date_end=old_date_end,
|
||||
new_date_end=rec.date_end,
|
||||
)
|
||||
)
|
||||
rec.contract_id.message_post(body=msg)
|
||||
|
||||
@api.multi
|
||||
def stop(self, date_end):
|
||||
def stop(self, date_end, post_message=True):
|
||||
"""
|
||||
Put date_end on contract line
|
||||
We don't consider contract lines that end's before the new end date
|
||||
@@ -460,25 +541,23 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
if date_end < rec.date_start:
|
||||
rec.cancel()
|
||||
else:
|
||||
old_date_end = rec.date_end
|
||||
date_end = (
|
||||
rec.date_end
|
||||
if rec.date_end and rec.date_end < date_end
|
||||
else date_end
|
||||
)
|
||||
rec.write({'date_end': date_end, 'is_auto_renew': False})
|
||||
|
||||
msg = _(
|
||||
"""Contract line for <strong>{product}</strong>
|
||||
stopped: <br/>
|
||||
- <strong>End</strong>: {old_date_end} -- {new_date_end}
|
||||
""".format(
|
||||
product=rec.name,
|
||||
old_date_end=old_date_end,
|
||||
new_date_end=rec.date_end,
|
||||
)
|
||||
)
|
||||
rec.contract_id.message_post(body=msg)
|
||||
if not rec.date_end or rec.date_end > date_end:
|
||||
if post_message:
|
||||
old_date_end = rec.date_end
|
||||
msg = _(
|
||||
"""Contract line for <strong>{product}</strong>
|
||||
stopped: <br/>
|
||||
- <strong>End</strong>: {old_end} -- {new_end}
|
||||
""".format(
|
||||
product=rec.name,
|
||||
old_end=old_date_end,
|
||||
new_end=rec.date_end,
|
||||
)
|
||||
)
|
||||
rec.contract_id.message_post(body=msg)
|
||||
rec.write({'date_end': date_end, 'is_auto_renew': False})
|
||||
else:
|
||||
rec.write({'is_auto_renew': False})
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
@@ -505,7 +584,12 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
|
||||
@api.multi
|
||||
def plan_successor(
|
||||
self, date_start, date_end, is_auto_renew, recurring_next_date=False
|
||||
self,
|
||||
date_start,
|
||||
date_end,
|
||||
is_auto_renew,
|
||||
recurring_next_date=False,
|
||||
post_message=True,
|
||||
):
|
||||
"""
|
||||
Create a copy of a contract line in a new interval
|
||||
@@ -530,20 +614,20 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
)
|
||||
rec.successor_contract_line_id = new_line
|
||||
contract_line |= new_line
|
||||
|
||||
msg = _(
|
||||
"""Contract line for <strong>{product}</strong>
|
||||
planned a successor: <br/>
|
||||
- <strong>Start</strong>: {new_date_start}
|
||||
<br/>
|
||||
- <strong>End</strong>: {new_date_end}
|
||||
""".format(
|
||||
product=rec.name,
|
||||
new_date_start=new_line.date_start,
|
||||
new_date_end=new_line.date_end,
|
||||
if post_message:
|
||||
msg = _(
|
||||
"""Contract line for <strong>{product}</strong>
|
||||
planned a successor: <br/>
|
||||
- <strong>Start</strong>: {new_date_start}
|
||||
<br/>
|
||||
- <strong>End</strong>: {new_date_end}
|
||||
""".format(
|
||||
product=rec.name,
|
||||
new_date_start=new_line.date_start,
|
||||
new_date_end=new_line.date_end,
|
||||
)
|
||||
)
|
||||
)
|
||||
rec.contract_id.message_post(body=msg)
|
||||
rec.contract_id.message_post(body=msg)
|
||||
return contract_line
|
||||
|
||||
@api.multi
|
||||
@@ -590,34 +674,64 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
delay = (date_end - rec.date_start) + timedelta(days=1)
|
||||
else:
|
||||
delay = (date_end - date_start) + timedelta(days=1)
|
||||
rec.delay(delay)
|
||||
rec._delay(delay)
|
||||
contract_line |= rec
|
||||
else:
|
||||
if rec.date_end and rec.date_end < date_start:
|
||||
rec.stop(date_start)
|
||||
rec.stop(date_start, post_message=False)
|
||||
elif (
|
||||
rec.date_end
|
||||
and rec.date_end > date_start
|
||||
and rec.date_end < date_end
|
||||
):
|
||||
new_date_start = date_end
|
||||
new_date_end = date_end + (rec.date_end - date_start)
|
||||
rec.stop(date_start)
|
||||
new_date_start = date_end + relativedelta(days=1)
|
||||
new_date_end = (
|
||||
date_end
|
||||
+ (rec.date_end - date_start)
|
||||
+ relativedelta(days=1)
|
||||
)
|
||||
rec.stop(
|
||||
date_start - relativedelta(days=1), post_message=False
|
||||
)
|
||||
contract_line |= rec.plan_successor(
|
||||
new_date_start, new_date_end, is_auto_renew
|
||||
new_date_start,
|
||||
new_date_end,
|
||||
is_auto_renew,
|
||||
post_message=False,
|
||||
)
|
||||
else:
|
||||
new_date_start = date_end
|
||||
new_date_end = (
|
||||
rec.date_end
|
||||
if not rec.date_end
|
||||
else rec.date_end + (date_end - date_start)
|
||||
)
|
||||
rec.stop(date_start)
|
||||
contract_line |= rec.plan_successor(
|
||||
new_date_start, new_date_end, is_auto_renew
|
||||
)
|
||||
new_date_start = date_end + relativedelta(days=1)
|
||||
if rec.date_end:
|
||||
new_date_end = (
|
||||
rec.date_end
|
||||
+ (date_end - date_start)
|
||||
+ relativedelta(days=1)
|
||||
)
|
||||
else:
|
||||
new_date_end = rec.date_end
|
||||
|
||||
rec.stop(
|
||||
date_start - relativedelta(days=1), post_message=False
|
||||
)
|
||||
contract_line |= rec.plan_successor(
|
||||
new_date_start,
|
||||
new_date_end,
|
||||
is_auto_renew,
|
||||
post_message=False,
|
||||
)
|
||||
msg = _(
|
||||
"""Contract line for <strong>{product}</strong>
|
||||
suspended: <br/>
|
||||
- <strong>Suspension Start</strong>: {new_date_start}
|
||||
<br/>
|
||||
- <strong>Suspension End</strong>: {new_date_end}
|
||||
""".format(
|
||||
product=rec.name,
|
||||
new_date_start=date_start,
|
||||
new_date_end=date_end,
|
||||
)
|
||||
)
|
||||
rec.contract_id.message_post(body=msg)
|
||||
return contract_line
|
||||
|
||||
@api.multi
|
||||
@@ -671,7 +785,7 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
self.ensure_one()
|
||||
context = {
|
||||
'default_contract_line_id': self.id,
|
||||
'default_recurring_next_date': fields.Date.today(),
|
||||
'default_recurring_next_date': fields.Date.context_today(self),
|
||||
}
|
||||
context.update(self.env.context)
|
||||
view_id = self.env.ref(
|
||||
@@ -772,16 +886,31 @@ class AccountAnalyticInvoiceLine(models.Model):
|
||||
res = self.env['account.analytic.invoice.line']
|
||||
for rec in self:
|
||||
is_auto_renew = rec.is_auto_renew
|
||||
rec.stop(rec.date_end)
|
||||
rec.stop(rec.date_end, post_message=False)
|
||||
date_start, date_end = rec._get_renewal_dates()
|
||||
new_line = rec.plan_successor(date_start, date_end, is_auto_renew)
|
||||
new_line = rec.plan_successor(
|
||||
date_start, date_end, is_auto_renew, post_message=False
|
||||
)
|
||||
new_line._onchange_date_start()
|
||||
res |= new_line
|
||||
msg = _(
|
||||
"""Contract line for <strong>{product}</strong>
|
||||
renewed: <br/>
|
||||
- <strong>Start</strong>: {new_date_start}
|
||||
<br/>
|
||||
- <strong>End</strong>: {new_date_end}
|
||||
""".format(
|
||||
product=rec.name,
|
||||
new_date_start=date_start,
|
||||
new_date_end=date_end,
|
||||
)
|
||||
)
|
||||
rec.contract_id.message_post(body=msg)
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _contract_line_to_renew_domain(self):
|
||||
date_ref = fields.datetime.today() + self.get_relative_delta(
|
||||
date_ref = fields.Date.context_today(self) + self.get_relative_delta(
|
||||
self.termination_notice_rule_type, self.termination_notice_interval
|
||||
)
|
||||
return [
|
||||
|
||||
Reference in New Issue
Block a user