diff --git a/product_contract/__manifest__.py b/product_contract/__manifest__.py index 2a4bac6f..f2a3411c 100644 --- a/product_contract/__manifest__.py +++ b/product_contract/__manifest__.py @@ -20,4 +20,5 @@ ], 'installable': True, 'application': False, + "external_dependencies": {"python": ["dateutil"]}, } diff --git a/product_contract/models/__init__.py b/product_contract/models/__init__.py index 25aa0c93..c16c95bb 100644 --- a/product_contract/models/__init__.py +++ b/product_contract/models/__init__.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- # Copyright 2017 LasLabs Inc. +# Copyright 2018 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import contract diff --git a/product_contract/models/contract.py b/product_contract/models/contract.py index 7149eae4..e7aeb5b3 100644 --- a/product_contract/models/contract.py +++ b/product_contract/models/contract.py @@ -6,18 +6,17 @@ from odoo.exceptions import AccessError from odoo.tools.translate import _ -class AccountAnalyticAccount(models.Model): - _name = 'account.analytic.account' - _inherit = 'account.analytic.account' +class ContractContract(models.Model): + _inherit = 'contract.contract' sale_order_count = fields.Integer(compute="_compute_sale_order_count") - @api.depends('recurring_invoice_line_ids') + @api.depends('contract_line_ids') def _compute_sale_order_count(self): for rec in self: try: order_count = len( - rec.recurring_invoice_line_ids.mapped( + rec.contract_line_ids.mapped( 'sale_order_line_id.order_id' ) ) @@ -28,7 +27,7 @@ class AccountAnalyticAccount(models.Model): @api.multi def action_view_sales_orders(self): self.ensure_one() - orders = self.recurring_invoice_line_ids.mapped( + orders = self.contract_line_ids.mapped( 'sale_order_line_id.order_id' ) return { diff --git a/product_contract/models/contract_line.py b/product_contract/models/contract_line.py index 504ae6b9..2a85f73e 100644 --- a/product_contract/models/contract_line.py +++ b/product_contract/models/contract_line.py @@ -1,12 +1,13 @@ # Copyright 2017 LasLabs Inc. +# Copyright 2018 ACSONE SA/NV. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import api, fields, models -class AccountAnalyticInvoiceLine(models.Model): - _inherit = 'account.analytic.invoice.line' +class ContractLine(models.Model): + _inherit = 'contract.line' _rec_name = 'display_name' sale_order_line_id = fields.Many2one( @@ -16,9 +17,10 @@ class AccountAnalyticInvoiceLine(models.Model): copy=False, ) display_name = fields.Char(compute='_compute_display_name_2') + @api.multi def _prepare_invoice_line(self, invoice_id=False): - res = super(AccountAnalyticInvoiceLine, self)._prepare_invoice_line( + res = super(ContractLine, self)._prepare_invoice_line( invoice_id=invoice_id ) if self.sale_order_line_id and res: diff --git a/product_contract/models/product_template.py b/product_contract/models/product_template.py index f09cec8b..1ca3f75e 100644 --- a/product_contract/models/product_template.py +++ b/product_contract/models/product_template.py @@ -11,7 +11,7 @@ class ProductTemplate(models.Model): is_contract = fields.Boolean('Is a contract') contract_template_id = fields.Many2one( - comodel_name='account.analytic.contract', string='Contract Template' + comodel_name='contract.template', string='Contract Template' ) default_qty = fields.Integer(string="Default Quantity", default=1) recurring_rule_type = fields.Selection( diff --git a/product_contract/models/sale_order.py b/product_contract/models/sale_order.py index 0d528a51..bbc1345c 100644 --- a/product_contract/models/sale_order.py +++ b/product_contract/models/sale_order.py @@ -27,7 +27,7 @@ class SaleOrder(models.Model): lambda r: r.contract_id and r.product_id.is_contract and r - not in r.contract_id.recurring_invoice_line_ids.mapped( + not in r.contract_id.contract_line_ids.mapped( 'sale_order_line_id' ) ) @@ -46,7 +46,6 @@ class SaleOrder(models.Model): template_name=contract_template.name, sale_name=self.name ), 'partner_id': self.partner_id.id, - 'recurring_invoices': True, 'contract_template_id': contract_template.id, 'user_id': self.user_id.id, 'payment_term_id': self.payment_term_id.id, @@ -56,8 +55,8 @@ class SaleOrder(models.Model): @api.multi def action_create_contract(self): - contract_env = self.env['account.analytic.account'] - contracts = self.env['account.analytic.account'] + contract_model = self.env['contract.contract'] + contracts = self.env['contract.contract'] 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 @@ -66,7 +65,7 @@ class SaleOrder(models.Model): lambda r: r.contract_id and r.product_id.is_contract and r - not in r.contract_id.recurring_invoice_line_ids.mapped( + not in r.contract_id.contract_line_ids.mapped( 'sale_order_line_id' ) ) @@ -74,10 +73,10 @@ class SaleOrder(models.Model): 'product_id.contract_template_id' ): order_lines = line_to_create_contract.filtered( - lambda r: r.product_id.contract_template_id - == contract_template + lambda r, template=contract_template: + r.product_id.contract_template_id == template ) - contract = contract_env.create( + contract = contract_model.create( rec._prepare_contract_value(contract_template) ) contracts |= contract @@ -92,7 +91,9 @@ class SaleOrder(models.Model): 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 + lambda order: ( + order.company_id.create_contract_at_sale_order_confirmation + ) ).action_create_contract() return super(SaleOrder, self).action_confirm() @@ -109,7 +110,7 @@ class SaleOrder(models.Model): "contract.action_account_analytic_sale_overdue_all" ).read()[0] contracts = ( - self.env['account.analytic.invoice.line'] + self.env['contract.line'] .search([('sale_order_line_id', 'in', self.order_line.ids)]) .mapped('contract_id') ) diff --git a/product_contract/models/sale_order_line.py b/product_contract/models/sale_order_line.py index 00213bac..1be510c0 100644 --- a/product_contract/models/sale_order_line.py +++ b/product_contract/models/sale_order_line.py @@ -14,10 +14,10 @@ class SaleOrderLine(models.Model): string='Is a contract', related="product_id.is_contract" ) contract_id = fields.Many2one( - comodel_name='account.analytic.account', string='Contract', copy=False + comodel_name='contract.contract', string='Contract', copy=False ) contract_template_id = fields.Many2one( - comodel_name='account.analytic.contract', + comodel_name='contract.template', string='Contract Template', related='product_id.product_tmpl_id.contract_template_id', readonly=True, @@ -45,7 +45,7 @@ class SaleOrderLine(models.Model): date_end = fields.Date(string='Date End') contract_line_id = fields.Many2one( - comodel_name="account.analytic.invoice.line", + comodel_name="contract.line", string="Contract Line to replace", required=False, copy=False, @@ -61,7 +61,7 @@ class SaleOrderLine(models.Model): @api.onchange('product_id') def onchange_product(self): - contract_line_env = self.env['account.analytic.invoice.line'] + 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 @@ -73,7 +73,7 @@ class SaleOrderLine(models.Model): rec.date_end = ( rec.date_start - + contract_line_env.get_relative_delta( + + contract_line_model.get_relative_delta( rec._get_auto_renew_rule_type(), int(rec.product_uom_qty), ) @@ -82,14 +82,14 @@ class SaleOrderLine(models.Model): @api.onchange('date_start', 'product_uom_qty', 'recurring_rule_type') def onchange_date_start(self): - contract_line_env = self.env['account.analytic.invoice.line'] + 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_env.get_relative_delta( + + contract_line_model.get_relative_delta( rec._get_auto_renew_rule_type(), int(rec.product_uom_qty), ) @@ -107,7 +107,7 @@ class SaleOrderLine(models.Model): """ self.ensure_one() recurring_next_date = self.env[ - 'account.analytic.invoice.line' + 'contract.line' ]._compute_first_recurring_next_date( self.date_start or fields.Date.today(), self.recurring_invoicing_type, @@ -158,8 +158,8 @@ class SaleOrderLine(models.Model): @api.multi def create_contract_line(self, contract): - contract_line_env = self.env['account.analytic.invoice.line'] - contract_line = self.env['account.analytic.invoice.line'] + contract_line_model = self.env['contract.line'] + contract_line = self.env['contract.line'] predecessor_contract_line = False for rec in self: if rec.contract_line_id: @@ -180,7 +180,7 @@ class SaleOrderLine(models.Model): ) predecessor_contract_line = rec.contract_line_id if predecessor_contract_line: - new_contract_line = contract_line_env.create( + new_contract_line = contract_line_model.create( rec._prepare_contract_line_values( contract, predecessor_contract_line.id ) @@ -189,7 +189,7 @@ class SaleOrderLine(models.Model): new_contract_line ) else: - new_contract_line = contract_line_env.create( + new_contract_line = contract_line_model.create( rec._prepare_contract_line_values(contract) ) contract_line |= new_contract_line @@ -221,9 +221,10 @@ class SaleOrderLine(models.Model): ) def _compute_invoice_status(self): - super(SaleOrderLine, self)._compute_invoice_status() + res = super(SaleOrderLine, self)._compute_invoice_status() for line in self.filtered('contract_id'): line.invoice_status = 'no' + return res @api.multi def invoice_line_create(self, invoice_id, qty): diff --git a/product_contract/tests/test_product.py b/product_contract/tests/test_product.py index 76d1aef8..64a125c8 100644 --- a/product_contract/tests/test_product.py +++ b/product_contract/tests/test_product.py @@ -11,7 +11,7 @@ class TestProductTemplate(TransactionCase): super(TestProductTemplate, self).setUp() self.service_product = self.env.ref('product.product_product_1') self.consu_product = self.env.ref('product.product_product_5') - self.contract = self.env['account.analytic.contract'].create( + self.contract = self.env['contract.template'].create( {'name': 'Test'} ) diff --git a/product_contract/tests/test_sale_order.py b/product_contract/tests/test_sale_order.py index 14ea93b7..4d859c67 100644 --- a/product_contract/tests/test_sale_order.py +++ b/product_contract/tests/test_sale_order.py @@ -14,13 +14,13 @@ class TestSaleOrder(TransactionCase): self.product1 = self.env.ref('product.product_product_1') self.product2 = self.env.ref('product.product_product_2') self.sale = self.env.ref('sale.sale_order_2') - self.contract_template1 = self.env['account.analytic.contract'].create( + self.contract_template1 = self.env['contract.template'].create( {'name': 'Template 1'} ) - self.contract_template2 = self.env['account.analytic.contract'].create( + self.contract_template2 = self.env['contract.template'].create( { 'name': 'Template 2', - 'recurring_invoice_line_ids': [ + 'contract_line_ids': [ ( 0, 0, @@ -58,15 +58,14 @@ class TestSaleOrder(TransactionCase): self.order_line1.date_start = '2018-01-01' self.order_line1.product_uom_qty = 12 pricelist = self.sale.partner_id.property_product_pricelist.id - self.contract = self.env["account.analytic.account"].create( + self.contract = self.env["contract.contract"].create( { "name": "Test Contract 2", "partner_id": self.sale.partner_id.id, "pricelist_id": pricelist, - "recurring_invoices": True, "contract_type": "sale", "contract_template_id": self.contract_template1.id, - "recurring_invoice_line_ids": [ + "contract_line_ids": [ ( 0, 0, @@ -86,7 +85,7 @@ class TestSaleOrder(TransactionCase): ], } ) - self.contract_line = self.contract.recurring_invoice_line_ids[0] + self.contract_line = self.contract.contract_line_ids[0] def test_compute_is_contract(self): """Sale Order should have is_contract true if one of its lines is @@ -104,13 +103,13 @@ class TestSaleOrder(TransactionCase): self.order_line1.contract_id.contract_template_id, self.contract_template1, ) - contract_line = self.order_line1.contract_id.recurring_invoice_line_ids + contract_line = self.order_line1.contract_id.contract_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_action_confirm_without_contract_creation(self): """ It should create a contract for each contract template used in order_line """ @@ -126,13 +125,13 @@ class TestSaleOrder(TransactionCase): self.order_line1.contract_id.contract_template_id, self.contract_template1, ) - contract_line = self.order_line1.contract_id.recurring_invoice_line_ids + contract_line = self.order_line1.contract_id.contract_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""" @@ -157,7 +156,7 @@ class TestSaleOrder(TransactionCase): def test_check_contract_sale_partner(self): """Can't link order line to a partner contract different then the order one""" - contract2 = self.env['account.analytic.account'].create( + contract2 = self.env['contract.contract'].create( { 'name': 'Contract', 'contract_template_id': self.contract_template2.id, @@ -170,9 +169,10 @@ class TestSaleOrder(TransactionCase): def test_check_contract_sale_contract_template(self): """Can't link order line to a contract with different contract template then the product one""" - contract1 = self.env['account.analytic.account'].create( + contract1 = self.env['contract.contract'].create( { 'name': 'Contract', + 'partner_id': self.env.user.partner_id.id, 'contract_template_id': self.contract_template1.id, } ) @@ -235,7 +235,7 @@ class TestSaleOrder(TransactionCase): self.contract_line.date_end, Date.to_date("2018-05-31") ) self.assertFalse(self.contract_line.is_auto_renew) - new_contract_line = self.env['account.analytic.invoice.line'].search( + new_contract_line = self.env['contract.line'].search( [('sale_order_line_id', '=', self.order_line1.id)] ) self.assertEqual( diff --git a/product_contract/views/contract.xml b/product_contract/views/contract.xml index abf53e6e..95208855 100644 --- a/product_contract/views/contract.xml +++ b/product_contract/views/contract.xml @@ -7,9 +7,9 @@ - account.analytic.account + contract.contract + ref="contract.contract_contract_customer_form_view"/>