mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[12.0][IMP] - option to decide if we automaticallt create contract a sale confirm
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
'website': 'https://github.com/oca/contract',
|
'website': 'https://github.com/oca/contract',
|
||||||
'depends': ['product', 'contract_sale'],
|
'depends': ['product', 'contract_sale'],
|
||||||
'data': [
|
'data': [
|
||||||
|
'views/res_config_settings.xml',
|
||||||
'views/contract.xml',
|
'views/contract.xml',
|
||||||
'views/product_template.xml',
|
'views/product_template.xml',
|
||||||
'views/sale_order.xml'
|
'views/sale_order.xml'
|
||||||
|
|||||||
@@ -7,3 +7,5 @@ from . import contract_line
|
|||||||
from . import product_template
|
from . import product_template
|
||||||
from . import sale_order
|
from . import sale_order
|
||||||
from . import sale_order_line
|
from . import sale_order_line
|
||||||
|
from . import res_company
|
||||||
|
from . import res_config_settings
|
||||||
|
|||||||
14
product_contract/models/res_company.py
Normal file
14
product_contract/models/res_company.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copyright 2019 ACSONE SA/NV
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ResCompany(models.Model):
|
||||||
|
|
||||||
|
_inherit = 'res.company'
|
||||||
|
|
||||||
|
create_contract_at_sale_order_confirmation = fields.Boolean(
|
||||||
|
string="Automatically Create Contracts At Sale Order Confirmation",
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
14
product_contract/models/res_config_settings.py
Normal file
14
product_contract/models/res_config_settings.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copyright 2019 ACSONE SA/NV
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ResConfigSettings(models.TransientModel):
|
||||||
|
|
||||||
|
_inherit = 'res.config.settings'
|
||||||
|
|
||||||
|
create_contract_at_sale_order_confirmation = fields.Boolean(
|
||||||
|
related="company_id.create_contract_at_sale_order_confirmation",
|
||||||
|
readonly=False
|
||||||
|
)
|
||||||
@@ -12,6 +12,27 @@ class SaleOrder(models.Model):
|
|||||||
string='Is a contract', compute='_compute_is_contract'
|
string='Is a contract', compute='_compute_is_contract'
|
||||||
)
|
)
|
||||||
contract_count = fields.Integer(compute='_compute_contract_count')
|
contract_count = fields.Integer(compute='_compute_contract_count')
|
||||||
|
need_contract_creation = fields.Boolean(
|
||||||
|
compute='_compute_need_contract_creation'
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends('order_line.contract_id', 'state')
|
||||||
|
def _compute_need_contract_creation(self):
|
||||||
|
for rec in self:
|
||||||
|
if rec.state not in ('draft', 'sent'):
|
||||||
|
line_to_create_contract = rec.order_line.filtered(
|
||||||
|
lambda r: not r.contract_id and r.product_id.is_contract
|
||||||
|
)
|
||||||
|
line_to_update_contract = rec.order_line.filtered(
|
||||||
|
lambda r: r.contract_id
|
||||||
|
and r.product_id.is_contract
|
||||||
|
and r
|
||||||
|
not in r.contract_id.recurring_invoice_line_ids.mapped(
|
||||||
|
'sale_order_line_id'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if line_to_create_contract or line_to_update_contract:
|
||||||
|
rec.need_contract_creation = True
|
||||||
|
|
||||||
@api.depends('order_line')
|
@api.depends('order_line')
|
||||||
def _compute_is_contract(self):
|
def _compute_is_contract(self):
|
||||||
@@ -34,15 +55,20 @@ class SaleOrder(models.Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def action_confirm(self):
|
def action_create_contract(self):
|
||||||
""" If we have a contract in the order, set it up """
|
|
||||||
contract_env = self.env['account.analytic.account']
|
contract_env = self.env['account.analytic.account']
|
||||||
|
contracts = self.env['account.analytic.account']
|
||||||
for rec in self.filtered('is_contract'):
|
for rec in self.filtered('is_contract'):
|
||||||
line_to_create_contract = rec.order_line.filtered(
|
line_to_create_contract = rec.order_line.filtered(
|
||||||
lambda r: not r.contract_id and r.product_id.is_contract
|
lambda r: not r.contract_id and r.product_id.is_contract
|
||||||
)
|
)
|
||||||
line_to_update_contract = rec.order_line.filtered(
|
line_to_update_contract = rec.order_line.filtered(
|
||||||
lambda r: r.contract_id and r.product_id.is_contract
|
lambda r: r.contract_id
|
||||||
|
and r.product_id.is_contract
|
||||||
|
and r
|
||||||
|
not in r.contract_id.recurring_invoice_line_ids.mapped(
|
||||||
|
'sale_order_line_id'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
for contract_template in line_to_create_contract.mapped(
|
for contract_template in line_to_create_contract.mapped(
|
||||||
'product_id.contract_template_id'
|
'product_id.contract_template_id'
|
||||||
@@ -54,11 +80,20 @@ class SaleOrder(models.Model):
|
|||||||
contract = contract_env.create(
|
contract = contract_env.create(
|
||||||
rec._prepare_contract_value(contract_template)
|
rec._prepare_contract_value(contract_template)
|
||||||
)
|
)
|
||||||
|
contracts |= contract
|
||||||
contract._onchange_contract_template_id()
|
contract._onchange_contract_template_id()
|
||||||
order_lines.create_contract_line(contract)
|
order_lines.create_contract_line(contract)
|
||||||
order_lines.write({'contract_id': contract.id})
|
order_lines.write({'contract_id': contract.id})
|
||||||
for line in line_to_update_contract:
|
for line in line_to_update_contract:
|
||||||
line.create_contract_line(line.contract_id)
|
line.create_contract_line(line.contract_id)
|
||||||
|
return contracts
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def action_confirm(self):
|
||||||
|
""" If we have a contract in the order, set it up """
|
||||||
|
self.filtered(
|
||||||
|
lambda order: order.company_id.create_contract_at_sale_order_confirmation
|
||||||
|
).action_create_contract()
|
||||||
return super(SaleOrder, self).action_confirm()
|
return super(SaleOrder, self).action_confirm()
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
|
|||||||
@@ -110,7 +110,29 @@ class TestSaleOrder(TransactionCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
contract_line.recurring_next_date, Date.to_date('2018-01-31')
|
contract_line.recurring_next_date, Date.to_date('2018-01-31')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_action_confirm_without_contract_creation(self):
|
||||||
|
""" It should create a contract for each contract template used in
|
||||||
|
order_line """
|
||||||
|
self.sale.company_id.create_contract_at_sale_order_confirmation = False
|
||||||
|
self.order_line1.onchange_product()
|
||||||
|
self.sale.action_confirm()
|
||||||
|
self.assertEqual(len(self.sale.order_line.mapped('contract_id')), 0)
|
||||||
|
self.assertTrue(self.sale.need_contract_creation)
|
||||||
|
self.sale.action_create_contract()
|
||||||
|
self.assertEqual(len(self.sale.order_line.mapped('contract_id')), 2)
|
||||||
|
self.assertFalse(self.sale.need_contract_creation)
|
||||||
|
self.assertEqual(
|
||||||
|
self.order_line1.contract_id.contract_template_id,
|
||||||
|
self.contract_template1,
|
||||||
|
)
|
||||||
|
contract_line = self.order_line1.contract_id.recurring_invoice_line_ids
|
||||||
|
self.assertEqual(contract_line.date_start, Date.to_date('2018-01-01'))
|
||||||
|
self.assertEqual(contract_line.date_end, Date.to_date('2018-12-31'))
|
||||||
|
self.assertEqual(
|
||||||
|
contract_line.recurring_next_date, Date.to_date('2018-01-31')
|
||||||
|
)
|
||||||
|
|
||||||
def test_sale_contract_count(self):
|
def test_sale_contract_count(self):
|
||||||
"""It should count contracts as many different contract template used
|
"""It should count contracts as many different contract template used
|
||||||
in order_line"""
|
in order_line"""
|
||||||
|
|||||||
31
product_contract/views/res_config_settings.xml
Normal file
31
product_contract/views/res_config_settings.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2019 ACSONE SA/NV
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="res_config_settings_form_view">
|
||||||
|
<field name="name">res.config.settings.form (in product_contract)
|
||||||
|
</field>
|
||||||
|
<field name="model">res.config.settings</field>
|
||||||
|
<field name="inherit_id" ref="sale.res_config_settings_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//div[@id='sales_settings_invoicing_policy']/.."
|
||||||
|
position="inside">
|
||||||
|
<div class="col-12 col-lg-6 o_setting_box">
|
||||||
|
<div class="o_setting_left_pane">
|
||||||
|
<field name="create_contract_at_sale_order_confirmation"/>
|
||||||
|
</div>
|
||||||
|
<div class="o_setting_right_pane">
|
||||||
|
<label for="create_contract_at_sale_order_confirmation"/>
|
||||||
|
<div class="text-muted">
|
||||||
|
Automatically Create Contracts At Sale Order Confirmation
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
@@ -12,6 +12,13 @@
|
|||||||
<field name="model">sale.order</field>
|
<field name="model">sale.order</field>
|
||||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//header" position="inside">
|
||||||
|
<field name="need_contract_creation" invisible="1"/>
|
||||||
|
<button name="action_create_contract"
|
||||||
|
string="Create Contracts"
|
||||||
|
type="object"
|
||||||
|
class="oe_highlight" attrs="{'invisible': [('need_contract_creation', '=', False)]}"/>
|
||||||
|
</xpath>
|
||||||
<xpath expr="//div[@name='button_box']" position="inside">
|
<xpath expr="//div[@name='button_box']" position="inside">
|
||||||
<button name="action_show_contracts"
|
<button name="action_show_contracts"
|
||||||
type="object" icon="fa-book"
|
type="object" icon="fa-book"
|
||||||
|
|||||||
Reference in New Issue
Block a user