mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[FIX] product_contract: set 'Contract template' field company depend
This commit is contained in:
36
product_contract/migrations/12.0.4.0.0/pre-migration.py
Normal file
36
product_contract/migrations/12.0.4.0.0/pre-migration.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright 2019 Tecnativa - Ernesto Tejeda
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openupgradelib import openupgrade
|
||||
|
||||
|
||||
@openupgrade.migrate()
|
||||
def migrate(env, version):
|
||||
# Convert contract_template_id field of the product_template table
|
||||
# to a company dependent field
|
||||
model_name = "product.template"
|
||||
model_table_name = "product_template"
|
||||
origin_field_name = "contract_template_id"
|
||||
destination_field_name = "property_contract_template_id"
|
||||
# Add ir.model.fields entry
|
||||
env.cr.execute(
|
||||
"SELECT id FROM ir_model WHERE model = %s", (model_name, ),
|
||||
)
|
||||
model_id = env.cr.fetchone()[0]
|
||||
openupgrade.logged_query(
|
||||
env.cr, """
|
||||
INSERT INTO ir_model_fields (
|
||||
model_id, model, name, field_description, ttype, state, relation
|
||||
) VALUES (
|
||||
%s, %s, %s, %s, %s, %s, %s
|
||||
)""",
|
||||
(model_id, model_name, destination_field_name, 'OU', "many2one",
|
||||
'base', 'contract.template'),
|
||||
)
|
||||
openupgrade.convert_to_company_dependent(
|
||||
env,
|
||||
model_name,
|
||||
origin_field_name,
|
||||
destination_field_name,
|
||||
model_table_name,
|
||||
)
|
||||
@@ -10,8 +10,10 @@ class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
is_contract = fields.Boolean('Is a contract')
|
||||
contract_template_id = fields.Many2one(
|
||||
comodel_name='contract.template', string='Contract Template'
|
||||
property_contract_template_id = fields.Many2one(
|
||||
comodel_name='contract.template',
|
||||
string='Contract Template',
|
||||
company_dependent=True,
|
||||
)
|
||||
default_qty = fields.Integer(string="Default Quantity", default=1)
|
||||
recurring_rule_type = fields.Selection(
|
||||
@@ -58,13 +60,13 @@ class ProductTemplate(models.Model):
|
||||
help="Specify Interval for automatic renewal.",
|
||||
)
|
||||
|
||||
@api.onchange('is_contract')
|
||||
def _change_is_contract(self):
|
||||
""" Clear the relation to contract_template_id when downgrading
|
||||
product from contract
|
||||
"""
|
||||
if not self.is_contract:
|
||||
self.contract_template_id = False
|
||||
@api.multi
|
||||
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(
|
||||
{'property_contract_template_id': False})
|
||||
super().write(vals)
|
||||
|
||||
@api.constrains('is_contract', 'type')
|
||||
def _check_contract_product_type(self):
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
# Copyright 2018 ACSONE SA/NV.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, api, models
|
||||
from odoo import _, fields, api, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
@@ -70,12 +71,23 @@ class SaleOrder(models.Model):
|
||||
'sale_order_line_id'
|
||||
)
|
||||
)
|
||||
for contract_template in line_to_create_contract.mapped(
|
||||
'product_id.contract_template_id'
|
||||
):
|
||||
for order_line in line_to_create_contract:
|
||||
contract_template = order_line.product_id.with_context(
|
||||
force_company=rec.company_id.id
|
||||
).property_contract_template_id
|
||||
if not contract_template:
|
||||
raise ValidationError(
|
||||
_("You must specify a contract "
|
||||
"template for '{}' product in '{}' company.").format(
|
||||
order_line.product_id.name,
|
||||
rec.company_id.name
|
||||
)
|
||||
)
|
||||
order_lines = line_to_create_contract.filtered(
|
||||
lambda r, template=contract_template:
|
||||
r.product_id.contract_template_id == template
|
||||
r.product_id.with_context(
|
||||
force_company=r.order_id.company_id.id
|
||||
).property_contract_template_id == template
|
||||
)
|
||||
contract = contract_model.create(
|
||||
rec._prepare_contract_value(contract_template)
|
||||
|
||||
@@ -19,8 +19,7 @@ class SaleOrderLine(models.Model):
|
||||
contract_template_id = fields.Many2one(
|
||||
comodel_name='contract.template',
|
||||
string='Contract Template',
|
||||
related='product_id.product_tmpl_id.contract_template_id',
|
||||
readonly=True,
|
||||
compute='_compute_contract_template_id',
|
||||
)
|
||||
recurring_rule_type = fields.Selection(
|
||||
[
|
||||
@@ -68,6 +67,14 @@ class SaleOrderLine(models.Model):
|
||||
help="Specify Interval for automatic renewal.",
|
||||
)
|
||||
|
||||
@api.multi
|
||||
@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
|
||||
).property_contract_template_id
|
||||
|
||||
@api.multi
|
||||
def _get_auto_renew_rule_type(self):
|
||||
"""monthly last day don't make sense for auto_renew_rule_type"""
|
||||
|
||||
@@ -16,13 +16,14 @@ class TestProductTemplate(TransactionCase):
|
||||
)
|
||||
|
||||
def test_change_is_contract(self):
|
||||
""" It should verify that the contract_template_id is removed
|
||||
when is_contract is False """
|
||||
""" It should verify that the property_contract_template_id
|
||||
field value is removed for all the companies when
|
||||
is_contract is set to False """
|
||||
self.service_product.is_contract = True
|
||||
self.service_product.contract_template_id = self.contract.id
|
||||
self.service_product.property_contract_template_id = self.contract.id
|
||||
self.service_product.is_contract = False
|
||||
self.service_product.product_tmpl_id._change_is_contract()
|
||||
self.assertEquals(len(self.service_product.contract_template_id), 0)
|
||||
self.assertEquals(len(
|
||||
self.service_product.property_contract_template_id), 0)
|
||||
|
||||
def test_check_contract_product_type(self):
|
||||
"""
|
||||
|
||||
@@ -38,19 +38,21 @@ class TestSaleOrder(TransactionCase):
|
||||
],
|
||||
}
|
||||
)
|
||||
self.product1.write(
|
||||
self.product1.with_context(
|
||||
force_company=self.sale.company_id.id).write(
|
||||
{
|
||||
'is_contract': True,
|
||||
'default_qty': 12,
|
||||
'recurring_rule_type': "monthlylastday",
|
||||
'recurring_invoicing_type': "post-paid",
|
||||
'contract_template_id': self.contract_template1.id,
|
||||
'property_contract_template_id': self.contract_template1.id,
|
||||
}
|
||||
)
|
||||
self.product2.write(
|
||||
self.product2.with_context(
|
||||
force_company=self.sale.company_id.id).write(
|
||||
{
|
||||
'is_contract': True,
|
||||
'contract_template_id': self.contract_template2.id,
|
||||
'property_contract_template_id': self.contract_template2.id,
|
||||
}
|
||||
)
|
||||
self.order_line1 = self.sale.order_line.filtered(
|
||||
@@ -111,15 +113,28 @@ class TestSaleOrder(TransactionCase):
|
||||
contract_line.recurring_next_date, Date.to_date('2018-01-31')
|
||||
)
|
||||
|
||||
def test_contract_company(self):
|
||||
"""
|
||||
contract company must be the sale order company and not the user one
|
||||
"""
|
||||
def test_change_sale_company(self):
|
||||
self.assertTrue(self.sale.company_id)
|
||||
other_company = self.env['res.company'].create(
|
||||
{'name': 'other company', 'parent_id': self.sale.company_id.id}
|
||||
)
|
||||
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)
|
||||
@@ -132,7 +147,7 @@ class TestSaleOrder(TransactionCase):
|
||||
self.assertEqual(self.order_line1.invoice_status, 'no')
|
||||
invoice = self.order_line1.contract_id.recurring_create_invoice()
|
||||
self.assertTrue(invoice)
|
||||
self.assertEqual(self.order_line1.invoice_qty, 1)
|
||||
self.assertEqual(self.order_line1.qty_invoiced, 1)
|
||||
self.assertEqual(self.order_line1.qty_to_invoice, 0)
|
||||
|
||||
def test_action_confirm_without_contract_creation(self):
|
||||
@@ -217,7 +232,7 @@ class TestSaleOrder(TransactionCase):
|
||||
self.sale.action_confirm()
|
||||
self.assertEqual(self.order_line1.invoice_status, 'no')
|
||||
|
||||
def test_sale_order_invoice_status(self):
|
||||
def test_sale_order_invoice_status_2(self):
|
||||
"""Sale order with only contract product should have nothing to
|
||||
invoice status directtly"""
|
||||
self.sale.order_line.filtered(
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
name="contract"
|
||||
attrs="{'invisible': [('is_contract', '=', False)],}">
|
||||
<group>
|
||||
<field name="contract_template_id"
|
||||
attrs="{'required':[('is_contract', '=', True)]}"/>
|
||||
<field name="property_contract_template_id"/>
|
||||
</group>
|
||||
<group name="recurrence_info">
|
||||
<group>
|
||||
|
||||
Reference in New Issue
Block a user