Browse Source

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

[10.0] [FIX] product_contract. Correctly create contract from template.
pull/354/head
Pedro M. Baeza 6 years ago
committed by GitHub
parent
commit
dace58094e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      product_contract/README.rst
  2. 4
      product_contract/__init__.py
  3. 7
      product_contract/__manifest__.py
  4. 2
      product_contract/models/__init__.py
  5. 21
      product_contract/models/sale_order.py
  6. 36
      product_contract/models/sale_order_line.py
  7. 2
      product_contract/tests/test_product_template.py
  8. 34
      product_contract/tests/test_sale_order.py

7
product_contract/README.rst

@ -1,5 +1,5 @@
.. 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
================
@ -7,8 +7,8 @@ Product Contract
================
This module adds support for products to be linked to contract templates.
It also adds functionality to automatically create a contract, from the template,
when a ``sale.order`` contains a product that implements a contract.
It also adds functionality to automatically create a contract from the
template, when a ``sale.order`` contains a product that implements a contract.
Usage
=====
@ -48,6 +48,7 @@ Contributors
------------
* Ted Salmon <tsalmon@laslabs.com>
* Ronald Portier <rportier@therp.nl>
Maintainer

4
product_contract/__init__.py

@ -1,5 +1,3 @@
# -*- 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 (https://www.gnu.org/licenses/agpl.html).
from . import models

7
product_contract/__manifest__.py

@ -1,15 +1,14 @@
# -*- 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 (https://www.gnu.org/licenses/agpl.html).
{
'name': 'Product Contract',
'version': '10.0.1.0.0',
'version': '10.0.1.1.0',
'category': 'Contract Management',
'license': 'AGPL-3',
'author': "LasLabs, "
"Odoo Community Association (OCA)",
'website': 'https://laslabs.com',
'website': 'https://github.com/oca/contract',
'depends': [
'contract',
'product',

2
product_contract/models/__init__.py

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

21
product_contract/models/sale_order.py

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
# 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
@ -11,17 +12,7 @@ class SaleOrder(models.Model):
@api.multi
def action_confirm(self):
""" If we have a contract in the order, set it up """
for rec in self:
order_lines = self.mapped('order_line').filtered(
lambda r: r.product_id.is_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()
for order in self:
# create_contract() already filters on contract order lines.
order.order_line.create_contract()
return super(SaleOrder, self).action_confirm()

36
product_contract/models/sale_order_line.py

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
# 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, fields, models
class SaleOrderLine(models.Model):
@ -10,5 +11,30 @@ class SaleOrderLine(models.Model):
contract_id = fields.Many2one(
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)

2
product_contract/tests/test_product_template.py

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

34
product_contract/tests/test_sale_order.py

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from mock import MagicMock
# 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,invalid-name
from odoo.tests.common import TransactionCase
@ -15,26 +15,16 @@ class TestSaleOrder(TransactionCase):
self.contract = self.env['account.analytic.contract'].create({
'name': 'Test',
'recurring_rule_type': 'yearly',
'recurring_interval': 12345,
})
'recurring_interval': 1})
self.product.product_tmpl_id.is_contract = True
self.product.product_tmpl_id.contract_template_id = self.contract.id
def tearDown(self):
self.env['account.analytic.account']._revert_method(
'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()
)
def test_action_confirm(self):
"""Contract should be created when sale is confirmed."""
self.sale.action_confirm()
self.env['account.analytic.account'].create.assert_called_once_with({
'name': '%s Contract' % self.sale.name,
'partner_id': self.sale.partner_id.id,
'contract_template_id': self.contract.id,
})
contract_model = self.env['account.analytic.account']
product_contract = contract_model.search([
('recurring_invoices', '=', True),
('partner_id', '=', self.sale.partner_id.id),
('contract_template_id', '=', self.contract.id)], limit=1)
self.assertTrue(product_contract)
Loading…
Cancel
Save