diff --git a/product_contract/__manifest__.py b/product_contract/__manifest__.py index 5f112894..2a4bac6f 100644 --- a/product_contract/__manifest__.py +++ b/product_contract/__manifest__.py @@ -13,6 +13,7 @@ 'website': 'https://github.com/oca/contract', 'depends': ['product', 'contract_sale'], 'data': [ + 'views/res_config_settings.xml', 'views/contract.xml', 'views/product_template.xml', 'views/sale_order.xml' diff --git a/product_contract/models/__init__.py b/product_contract/models/__init__.py index 6ec5fa03..25aa0c93 100644 --- a/product_contract/models/__init__.py +++ b/product_contract/models/__init__.py @@ -7,3 +7,5 @@ from . import contract_line from . import product_template from . import sale_order from . import sale_order_line +from . import res_company +from . import res_config_settings diff --git a/product_contract/models/res_company.py b/product_contract/models/res_company.py new file mode 100644 index 00000000..ab0c760c --- /dev/null +++ b/product_contract/models/res_company.py @@ -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, + ) diff --git a/product_contract/models/res_config_settings.py b/product_contract/models/res_config_settings.py new file mode 100644 index 00000000..803b095a --- /dev/null +++ b/product_contract/models/res_config_settings.py @@ -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 + ) diff --git a/product_contract/models/sale_order.py b/product_contract/models/sale_order.py index 045bd736..6eb6a973 100644 --- a/product_contract/models/sale_order.py +++ b/product_contract/models/sale_order.py @@ -12,6 +12,27 @@ class SaleOrder(models.Model): string='Is a contract', compute='_compute_is_contract' ) 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') def _compute_is_contract(self): @@ -34,15 +55,20 @@ class SaleOrder(models.Model): } @api.multi - def action_confirm(self): - """ If we have a contract in the order, set it up """ + def action_create_contract(self): contract_env = self.env['account.analytic.account'] + contracts = self.env['account.analytic.account'] for rec in self.filtered('is_contract'): 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 + 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( 'product_id.contract_template_id' @@ -54,11 +80,20 @@ class SaleOrder(models.Model): contract = contract_env.create( rec._prepare_contract_value(contract_template) ) + contracts |= contract contract._onchange_contract_template_id() order_lines.create_contract_line(contract) order_lines.write({'contract_id': contract.id}) for line in line_to_update_contract: 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() @api.multi diff --git a/product_contract/tests/test_sale_order.py b/product_contract/tests/test_sale_order.py index 054a362e..14ea93b7 100644 --- a/product_contract/tests/test_sale_order.py +++ b/product_contract/tests/test_sale_order.py @@ -110,7 +110,29 @@ class TestSaleOrder(TransactionCase): self.assertEqual( 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): """It should count contracts as many different contract template used in order_line""" diff --git a/product_contract/views/res_config_settings.xml b/product_contract/views/res_config_settings.xml new file mode 100644 index 00000000..d73ae8ac --- /dev/null +++ b/product_contract/views/res_config_settings.xml @@ -0,0 +1,31 @@ + + + + + + + res.config.settings.form (in product_contract) + + res.config.settings + + + +
+
+ +
+
+
+
+
+
+
+ + +
diff --git a/product_contract/views/sale_order.xml b/product_contract/views/sale_order.xml index 41b8b0b8..0428cac6 100644 --- a/product_contract/views/sale_order.xml +++ b/product_contract/views/sale_order.xml @@ -12,6 +12,13 @@ sale.order + + +