Merge pull request #321 from NL66278/10.0-product_contract-fix-recurring

[10.0] [FIX] product_contract. Correctly create contract from template.
This commit is contained in:
Pedro M. Baeza
2019-05-27 16:52:53 +02:00
committed by GitHub
8 changed files with 58 additions and 55 deletions

View File

@@ -1,5 +1,5 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg .. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
================ ================
@@ -7,8 +7,8 @@ Product Contract
================ ================
This module adds support for products to be linked to contract templates. This module adds support for products to be linked to contract templates.
It also adds functionality to automatically create a contract, from the template, It also adds functionality to automatically create a contract from the
when a ``sale.order`` contains a product that implements a contract. template, when a ``sale.order`` contains a product that implements a contract.
Usage Usage
===== =====
@@ -48,6 +48,7 @@ Contributors
------------ ------------
* Ted Salmon <tsalmon@laslabs.com> * Ted Salmon <tsalmon@laslabs.com>
* Ronald Portier <rportier@therp.nl>
Maintainer Maintainer

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models from . import models

View File

@@ -1,15 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc. # Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{ {
'name': 'Product Contract', 'name': 'Product Contract',
'version': '10.0.1.0.0', 'version': '10.0.1.1.0',
'category': 'Contract Management', 'category': 'Contract Management',
'license': 'AGPL-3', 'license': 'AGPL-3',
'author': "LasLabs, " 'author': "LasLabs, "
"Odoo Community Association (OCA)", "Odoo Community Association (OCA)",
'website': 'https://laslabs.com', 'website': 'https://github.com/oca/contract',
'depends': [ 'depends': [
'contract', 'contract',
'product', 'product',

View File

@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
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

View File

@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc. # Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # Copyright 2019 Therp BV <https://therp.nl>.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
# pylint: disable=missing-docstring,protected-access
from odoo import api, models from odoo import api, models
@@ -11,17 +12,7 @@ class SaleOrder(models.Model):
@api.multi @api.multi
def action_confirm(self): def action_confirm(self):
""" If we have a contract in the order, set it up """ """ If we have a contract in the order, set it up """
for rec in self: for order in self:
order_lines = self.mapped('order_line').filtered( # create_contract() already filters on contract order lines.
lambda r: r.product_id.is_contract order.order_line.create_contract()
)
for line in order_lines:
contract_tmpl = line.product_id.contract_template_id
contract = self.env['account.analytic.account'].create({
'name': '%s Contract' % rec.name,
'partner_id': rec.partner_id.id,
'contract_template_id': contract_tmpl.id,
})
line.contract_id = contract.id
contract.recurring_create_invoice()
return super(SaleOrder, self).action_confirm() return super(SaleOrder, self).action_confirm()

View File

@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc. # Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # Copyright 2019 Therp BV <https://therp.nl>.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import fields, models # pylint: disable=missing-docstring,protected-access
from odoo import api, fields, models
class SaleOrderLine(models.Model): class SaleOrderLine(models.Model):
@@ -10,5 +11,30 @@ class SaleOrderLine(models.Model):
contract_id = fields.Many2one( contract_id = fields.Many2one(
comodel_name='account.analytic.account', comodel_name='account.analytic.account',
string='Contract' string='Contract')
)
@api.multi
def create_contract(self):
"""Create contract for sale order line.
Should be called on confirmation of sale order.
"""
for line in self.filtered('product_id.is_contract'):
contract_vals = line._prepare_contract_vals()
contract = self.env['account.analytic.account'].create(
contract_vals)
line.contract_id = contract.id
@api.multi
def _prepare_contract_vals(self):
"""Prepare values to create contract from template."""
self.ensure_one()
contract_tmpl = self.product_id.contract_template_id
order = self.order_id
contract = self.env['account.analytic.account'].new({
'name': '%s Contract' % order.name,
'partner_id': order.partner_id.id,
'contract_template_id': contract_tmpl.id,
'recurring_invoices': True})
contract._onchange_contract_template_id()
return contract._convert_to_write(contract._cache)

View File

@@ -15,7 +15,7 @@ class TestProductTemplate(TransactionCase):
self.contract = self.env['account.analytic.contract'].create({ self.contract = self.env['account.analytic.contract'].create({
'name': 'Test', 'name': 'Test',
'recurring_rule_type': 'yearly', 'recurring_rule_type': 'yearly',
'recurring_interval': 12345, 'recurring_interval': 1,
}) })
def test_change_is_contract(self): def test_change_is_contract(self):

View File

@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc. # Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # Copyright 2019 Therp BV <https://therp.nl>.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from mock import MagicMock # pylint: disable=missing-docstring,protected-access,invalid-name
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
@@ -15,26 +15,16 @@ class TestSaleOrder(TransactionCase):
self.contract = self.env['account.analytic.contract'].create({ self.contract = self.env['account.analytic.contract'].create({
'name': 'Test', 'name': 'Test',
'recurring_rule_type': 'yearly', 'recurring_rule_type': 'yearly',
'recurring_interval': 12345, 'recurring_interval': 1})
})
self.product.product_tmpl_id.is_contract = True self.product.product_tmpl_id.is_contract = True
self.product.product_tmpl_id.contract_template_id = self.contract.id self.product.product_tmpl_id.contract_template_id = self.contract.id
def tearDown(self): def test_action_confirm(self):
self.env['account.analytic.account']._revert_method( """Contract should be created when sale is confirmed."""
'create',
)
super(TestSaleOrder, self).tearDown()
def test_action_done(self):
""" It should create a contract when the sale for a contract is set
to done for the first time """
self.env['account.analytic.account']._patch_method(
'create', MagicMock()
)
self.sale.action_confirm() self.sale.action_confirm()
self.env['account.analytic.account'].create.assert_called_once_with({ contract_model = self.env['account.analytic.account']
'name': '%s Contract' % self.sale.name, product_contract = contract_model.search([
'partner_id': self.sale.partner_id.id, ('recurring_invoices', '=', True),
'contract_template_id': self.contract.id, ('partner_id', '=', self.sale.partner_id.id),
}) ('contract_template_id', '=', self.contract.id)], limit=1)
self.assertTrue(product_contract)