|
|
@ -31,8 +31,7 @@ class SaleOrderLine(models.Model): |
|
|
|
('yearly', 'Year(s)'), |
|
|
|
], |
|
|
|
default='monthly', |
|
|
|
string='Recurrence', |
|
|
|
help="Specify Interval for automatic invoice generation.", |
|
|
|
string='Invoice Every', |
|
|
|
copy=False, |
|
|
|
) |
|
|
|
recurring_invoicing_type = fields.Selection( |
|
|
@ -42,12 +41,6 @@ class SaleOrderLine(models.Model): |
|
|
|
help="Specify if process date is 'from' or 'to' invoicing date", |
|
|
|
copy=False, |
|
|
|
) |
|
|
|
recurring_interval = fields.Integer( |
|
|
|
default=1, |
|
|
|
string='Repeat Every', |
|
|
|
help="Repeat every (Days/Week/Month/Year)", |
|
|
|
copy=False, |
|
|
|
) |
|
|
|
date_start = fields.Date(string='Date Start') |
|
|
|
date_end = fields.Date(string='Date End') |
|
|
|
|
|
|
@ -57,48 +50,42 @@ class SaleOrderLine(models.Model): |
|
|
|
required=False, |
|
|
|
copy=False, |
|
|
|
) |
|
|
|
is_auto_renew = fields.Boolean( |
|
|
|
string="Auto Renew", related="product_id.is_auto_renew", readonly=True |
|
|
|
) |
|
|
|
|
|
|
|
@api.onchange('product_id') |
|
|
|
def onchange_product(self): |
|
|
|
contract_line_env = self.env['account.analytic.invoice.line'] |
|
|
|
for rec in self: |
|
|
|
if rec.product_id.is_contract: |
|
|
|
rec.product_uom_qty = rec.product_id.default_qty |
|
|
|
rec.recurring_rule_type = rec.product_id.recurring_rule_type |
|
|
|
rec.recurring_invoicing_type = ( |
|
|
|
rec.product_id.recurring_invoicing_type |
|
|
|
) |
|
|
|
rec.recurring_interval = rec.product_id.recurring_interval |
|
|
|
rec.date_start = rec.date_start or fields.Date.today() |
|
|
|
if rec.product_id.is_auto_renew: |
|
|
|
rec.date_end = ( |
|
|
|
rec.date_start |
|
|
|
+ contract_line_env.get_relative_delta( |
|
|
|
rec.product_id.auto_renew_rule_type, |
|
|
|
rec.product_id.auto_renew_interval, |
|
|
|
) |
|
|
|
- relativedelta(days=1) |
|
|
|
rec.date_end = ( |
|
|
|
rec.date_start |
|
|
|
+ contract_line_env.get_relative_delta( |
|
|
|
rec.product_id.recurring_rule_type, |
|
|
|
int(rec.product_uom_qty), |
|
|
|
) |
|
|
|
- relativedelta(days=1) |
|
|
|
) |
|
|
|
|
|
|
|
@api.onchange('date_start') |
|
|
|
@api.onchange('date_start', 'product_uom_qty', 'recurring_rule_type') |
|
|
|
def onchange_date_start(self): |
|
|
|
for rec in self: |
|
|
|
if rec.product_id.is_auto_renew: |
|
|
|
if not rec.date_start: |
|
|
|
rec.date_end = False |
|
|
|
else: |
|
|
|
rec.date_end = ( |
|
|
|
rec.date_start |
|
|
|
+ self.env[ |
|
|
|
'account.analytic.invoice.line' |
|
|
|
].get_relative_delta( |
|
|
|
rec.product_id.auto_renew_rule_type, |
|
|
|
rec.product_id.auto_renew_interval, |
|
|
|
) |
|
|
|
- relativedelta(days=1) |
|
|
|
if not rec.date_start: |
|
|
|
rec.date_end = False |
|
|
|
else: |
|
|
|
rec.date_end = ( |
|
|
|
rec.date_start |
|
|
|
+ self.env[ |
|
|
|
'account.analytic.invoice.line' |
|
|
|
].get_relative_delta( |
|
|
|
rec.recurring_rule_type, int(rec.product_uom_qty) |
|
|
|
) |
|
|
|
- relativedelta(days=1) |
|
|
|
) |
|
|
|
|
|
|
|
@api.multi |
|
|
|
def _prepare_contract_line_values( |
|
|
@ -111,7 +98,7 @@ class SaleOrderLine(models.Model): |
|
|
|
self.date_start or fields.Date.today(), |
|
|
|
self.recurring_invoicing_type, |
|
|
|
self.recurring_rule_type, |
|
|
|
self.recurring_interval, |
|
|
|
int(self.product_uom_qty), |
|
|
|
) |
|
|
|
termination_notice_interval = ( |
|
|
|
self.product_id.termination_notice_interval |
|
|
@ -123,19 +110,31 @@ class SaleOrderLine(models.Model): |
|
|
|
'sequence': self.sequence, |
|
|
|
'product_id': self.product_id.id, |
|
|
|
'name': self.name, |
|
|
|
'quantity': self.product_uom_qty, |
|
|
|
# The quantity on the generated contract line is 1, as it |
|
|
|
# correspond to the most common use cases: |
|
|
|
# - quantity on the SO line = number of periods sold and unit |
|
|
|
# price the price of one period, so the |
|
|
|
# total amount of the SO corresponds to the planned value |
|
|
|
# of the contract; in this case the quantity on the contract |
|
|
|
# line must be 1 |
|
|
|
# - quantity on the SO line = number of hours sold, |
|
|
|
# automatic invoicing of the actual hours through a variable |
|
|
|
# quantity formula, in which case the quantity on the contract |
|
|
|
# line is not used |
|
|
|
# Other use cases are easy to implement by overriding this method. |
|
|
|
'quantity': 1.0, |
|
|
|
'uom_id': self.product_uom.id, |
|
|
|
'price_unit': self.price_unit, |
|
|
|
'discount': self.discount, |
|
|
|
'date_end': self.date_end, |
|
|
|
'date_start': self.date_start or fields.Date.today(), |
|
|
|
'recurring_next_date': recurring_next_date, |
|
|
|
'recurring_interval': self.recurring_interval, |
|
|
|
'recurring_interval': 1, |
|
|
|
'recurring_invoicing_type': self.recurring_invoicing_type, |
|
|
|
'recurring_rule_type': self.recurring_rule_type, |
|
|
|
'is_auto_renew': self.product_id.is_auto_renew, |
|
|
|
'auto_renew_interval': self.product_id.auto_renew_interval, |
|
|
|
'auto_renew_rule_type': self.product_id.auto_renew_rule_type, |
|
|
|
'auto_renew_interval': self.product_uom_qty, |
|
|
|
'auto_renew_rule_type': self.product_id.recurring_rule_type, |
|
|
|
'termination_notice_interval': termination_notice_interval, |
|
|
|
'termination_notice_rule_type': termination_notice_rule_type, |
|
|
|
'contract_id': contract.id, |
|
|
@ -153,8 +152,9 @@ class SaleOrderLine(models.Model): |
|
|
|
rec.date_start - relativedelta(days=1) |
|
|
|
) |
|
|
|
new_contract_line = contract_line_env.create( |
|
|
|
rec._prepare_contract_line_values(contract, |
|
|
|
rec.contract_line_id) |
|
|
|
rec._prepare_contract_line_values( |
|
|
|
contract, rec.contract_line_id |
|
|
|
) |
|
|
|
) |
|
|
|
if rec.contract_line_id: |
|
|
|
rec.contract_line_id.successor_contract_line_id = ( |
|
|
|