[MIG] product_contract: Migration to 14.0

This commit is contained in:
Mourad
2021-03-09 16:50:25 +01:00
committed by Ilyas
parent 1d0c280fe5
commit b793cf6356
9 changed files with 65 additions and 70 deletions

View File

@@ -7,6 +7,7 @@ from collections import namedtuple
from datetime import timedelta
from dateutil.relativedelta import relativedelta
from freezegun import freeze_time
from odoo import fields
from odoo.exceptions import UserError, ValidationError
@@ -2370,6 +2371,7 @@ class TestContract(TestContractBase):
to_date("2018-02-13"),
)
@freeze_time("2020-01-01 00:00:00")
def test_recurrency_propagation(self):
# Existing contract
vals = {

View File

@@ -4,7 +4,7 @@
{
"name": "Recurring - Product Contract",
"version": "13.0.1.0.0",
"version": "14.0.1.0.0",
"category": "Contract Management",
"license": "AGPL-3",
"author": "LasLabs, " "ACSONE SA/NV, " "Odoo Community Association (OCA)",

View File

@@ -65,7 +65,7 @@ class ProductTemplate(models.Model):
def write(self, vals):
if "is_contract" in vals and vals["is_contract"] is False:
for company in self.env["res.company"].search([]):
self.with_context(force_company=company.id).write(
self.with_company(company).write(
{"property_contract_template_id": False}
)
super().write(vals)

View File

@@ -16,15 +16,11 @@ class SaleOrder(models.Model):
@api.constrains("state")
def check_contact_is_not_terminated(self):
for rec in self:
if (
rec.state
not in (
if rec.state not in (
"sale",
"done",
"cancel",
)
and rec.order_line.filtered("contract_id.is_terminated")
):
) and rec.order_line.filtered("contract_id.is_terminated"):
raise ValidationError(
_("You can't upsell or downsell a terminated contract")
)
@@ -81,8 +77,8 @@ class SaleOrder(models.Model):
)
contract_templates = self.env["contract.template"]
for order_line in line_to_create_contract:
contract_template = order_line.product_id.with_context(
force_company=rec.company_id.id
contract_template = order_line.product_id.with_company(
rec.company_id
).property_contract_template_id
if not contract_template:
raise ValidationError(
@@ -94,8 +90,8 @@ class SaleOrder(models.Model):
contract_templates |= contract_template
for contract_template in contract_templates:
order_lines = line_to_create_contract.filtered(
lambda r, template=contract_template: r.product_id.with_context(
force_company=r.order_id.company_id.id
lambda r, template=contract_template: r.product_id.with_company(
r.order_id.company_id
).property_contract_template_id
== template
)
@@ -127,7 +123,7 @@ class SaleOrder(models.Model):
def action_show_contracts(self):
self.ensure_one()
action = self.env.ref("contract.action_customer_contract").read()[0]
action = self.env.ref("contract.action_customer_contract").sudo().read()[0]
contracts = (
self.env["contract.line"]
.search([("sale_order_line_id", "in", self.order_line.ids)])

View File

@@ -84,8 +84,8 @@ class SaleOrderLine(models.Model):
@api.depends("product_id")
def _compute_contract_template_id(self):
for rec in self:
rec.contract_template_id = rec.product_id.with_context(
force_company=rec.order_id.company_id.id
rec.contract_template_id = rec.product_id.with_company(
rec.order_id.company_id
).property_contract_template_id
def _get_auto_renew_rule_type(self):
@@ -95,9 +95,21 @@ class SaleOrderLine(models.Model):
return "monthly"
return self.recurring_rule_type
def _get_date_end(self):
self.ensure_one()
contract_line_model = self.env["contract.line"]
date_end = (
self.date_start
+ contract_line_model.get_relative_delta(
self._get_auto_renew_rule_type(),
int(self.product_uom_qty),
)
- relativedelta(days=1)
)
return date_end
@api.onchange("product_id")
def onchange_product(self):
contract_line_model = self.env["contract.line"]
for rec in self:
if rec.product_id.is_contract:
rec.product_uom_qty = rec.product_id.default_qty
@@ -105,14 +117,7 @@ class SaleOrderLine(models.Model):
rec.recurring_invoicing_type = rec.product_id.recurring_invoicing_type
rec.date_start = rec.date_start or fields.Date.today()
rec.date_end = (
rec.date_start
+ contract_line_model.get_relative_delta(
rec._get_auto_renew_rule_type(),
int(rec.product_uom_qty),
)
- relativedelta(days=1)
)
rec.date_end = rec._get_date_end()
rec.is_auto_renew = rec.product_id.is_auto_renew
if rec.is_auto_renew:
rec.auto_renew_interval = rec.product_id.auto_renew_interval
@@ -120,19 +125,25 @@ class SaleOrderLine(models.Model):
@api.onchange("date_start", "product_uom_qty", "recurring_rule_type")
def onchange_date_start(self):
contract_line_model = self.env["contract.line"]
for rec in self.filtered("product_id.is_contract"):
if not rec.date_start:
rec.date_end = False
else:
rec.date_end = (
rec.date_start
+ contract_line_model.get_relative_delta(
rec._get_auto_renew_rule_type(),
int(rec.product_uom_qty),
)
- relativedelta(days=1)
)
rec.date_end = rec._get_date_end() if rec.date_start else False
def _get_contract_line_qty(self):
"""Returns the quantity to be put on new contract lines."""
self.ensure_one()
# 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.
return 1.0
def _prepare_contract_line_values(
self, contract, predecessor_contract_line_id=False
@@ -157,19 +168,7 @@ class SaleOrderLine(models.Model):
"sequence": self.sequence,
"product_id": self.product_id.id,
"name": self.name,
# 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,
"quantity": self._get_contract_line_qty(),
"uom_id": self.product_uom.id,
"price_unit": self.price_unit,
"discount": self.discount,

View File

@@ -4,7 +4,7 @@
from dateutil.relativedelta import relativedelta
from odoo.exceptions import ValidationError
from odoo.exceptions import UserError, ValidationError
from odoo.fields import Date
from odoo.tests.common import TransactionCase
@@ -39,7 +39,7 @@ class TestSaleOrder(TransactionCase):
],
}
)
self.product1.with_context(force_company=self.sale.company_id.id).write(
self.product1.with_company(self.sale.company_id).write(
{
"is_contract": True,
"default_qty": 12,
@@ -48,7 +48,7 @@ class TestSaleOrder(TransactionCase):
"property_contract_template_id": self.contract_template1.id,
}
)
self.product2.with_context(force_company=self.sale.company_id.id).write(
self.product2.with_company(self.sale.company_id).write(
{
"is_contract": True,
"property_contract_template_id": self.contract_template2.id,
@@ -116,26 +116,16 @@ class TestSaleOrder(TransactionCase):
other_company = self.env["res.company"].create(
{"name": "other company", "parent_id": self.sale.company_id.id}
)
with self.assertRaises(UserError):
self.sale.company_id = other_company
with self.assertRaises(ValidationError):
self.sale.action_confirm()
def test_change_sale_company_2(self):
"""Contract company must be the sale order company."""
self.assertTrue(self.sale.company_id)
other_company = self.env["res.company"].create(
{"name": "other company", "parent_id": self.sale.company_id.id}
)
self.product1.with_context(
force_company=other_company.id
).property_contract_template_id = self.contract_template1
self.product2.with_context(
force_company=other_company.id
).property_contract_template_id = self.contract_template2
self.sale.company_id = other_company
self.sale.action_confirm()
contracts = self.sale.order_line.mapped("contract_id")
self.assertEqual(contracts.mapped("company_id"), other_company)
self.assertEqual(contracts.mapped("company_id"), self.sale.company_id)
def test_sale_order_invoice_status(self):
"""
@@ -353,7 +343,7 @@ class TestSaleOrder(TransactionCase):
def test_order_lines_with_the_same_contract_template(self):
"""It should create one contract with two lines grouped by contract
template"""
self.product2.with_context(force_company=self.sale.company_id.id).write(
self.product2.with_company(self.sale.company_id).write(
{
"is_contract": True,
"property_contract_template_id": self.contract_template1.id,

View File

@@ -1 +1,2 @@
# generated from manifests external_dependencies
python-dateutil

View File

@@ -0,0 +1 @@
../../../../product_contract

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)