diff --git a/product_contract/models/contract_line.py b/product_contract/models/contract_line.py index 101e544c..23fcb306 100644 --- a/product_contract/models/contract_line.py +++ b/product_contract/models/contract_line.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import api, fields, models class AccountAnalyticInvoiceLine(models.Model): @@ -14,3 +14,12 @@ class AccountAnalyticInvoiceLine(models.Model): required=False, copy=False, ) + + @api.multi + def _prepare_invoice_line(self, invoice_id): + res = super(AccountAnalyticInvoiceLine, self)._prepare_invoice_line( + invoice_id + ) + if self.sale_order_line_id: + res['sale_line_ids'] = [(6, 0, [self.sale_order_line_id.id])] + return res diff --git a/product_contract/models/sale_order.py b/product_contract/models/sale_order.py index e53fbb91..3a38c116 100644 --- a/product_contract/models/sale_order.py +++ b/product_contract/models/sale_order.py @@ -24,9 +24,11 @@ class SaleOrder(models.Model): contract_env = 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 + 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 ) - line_to_update_contract = rec.order_line.filtered('contract_id') for contract_template in line_to_create_contract.mapped( 'product_id.contract_template_id' ): diff --git a/product_contract/models/sale_order_line.py b/product_contract/models/sale_order_line.py index 70e868c4..6b0dc1f8 100644 --- a/product_contract/models/sale_order_line.py +++ b/product_contract/models/sale_order_line.py @@ -113,3 +113,14 @@ class SaleOrderLine(models.Model): raise ValidationError( _("Contract product has different contract template") ) + + def _compute_invoice_status(self): + super(SaleOrderLine, self)._compute_invoice_status() + for line in self.filtered('contract_id'): + line.invoice_status = 'no' + + @api.multi + def invoice_line_create(self, invoice_id, qty): + return super( + SaleOrderLine, self.filtered(lambda l: not l.contract_id) + ).invoice_line_create(invoice_id, qty) diff --git a/product_contract/tests/test_sale_order.py b/product_contract/tests/test_sale_order.py index 36e690b1..b3b505e8 100644 --- a/product_contract/tests/test_sale_order.py +++ b/product_contract/tests/test_sale_order.py @@ -73,6 +73,8 @@ 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( { 'name': 'Contract', @@ -84,6 +86,8 @@ class TestSaleOrder(TransactionCase): self.order_line1.contract_id = contract2 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( { 'name': 'Contract', @@ -92,3 +96,42 @@ class TestSaleOrder(TransactionCase): ) with self.assertRaises(ValidationError): self.order_line1.contract_id = contract1 + + def test_no_contract_proudct(self): + """it should create contract for only product contract""" + self.product1.is_contract = False + self.sale.action_confirm() + self.assertFalse(self.order_line1.contract_id) + + def test_sale_order_line_invoice_status(self): + """Sale order line for contract product should have nothing to + invoice as status""" + self.sale.action_confirm() + self.assertEqual(self.order_line1.invoice_status, 'no') + + def test_sale_order_invoice_status(self): + """Sale order with only contract product should have nothing to + invoice status directtly""" + self.sale.order_line.filtered( + lambda line: not line.product_id.is_contract + ).unlink() + self.sale.action_confirm() + self.assertEqual(self.sale.invoice_status, 'no') + + def test_sale_order_create_invoice(self): + """Should not invoice contract product on sale order create invoice""" + self.product2.is_contract = False + self.product2.invoice_policy = 'order' + self.sale.action_confirm() + self.sale.action_invoice_create() + self.assertEqual(len(self.sale.invoice_ids), 1) + invoice_line = self.sale.invoice_ids.invoice_line_ids.filtered( + lambda line: line.product_id.is_contract + ) + self.assertEqual(len(invoice_line), 0) + + def test_link_contract_invoice_to_sale_order(self): + """It should link contract invoice to sale order""" + self.sale.action_confirm() + invoice = self.order_line1.contract_id.recurring_create_invoice() + self.assertTrue(invoice in self.sale.invoice_ids)