mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user