[ADD] credit control dunning fees module

[ADD] docstring

[FIX] FeesComputer model specification to act as a abstract class without needing overriding

[IMP] fees column in report and mail

[FIX] dunning fees computer to register itself

[RM] unused import

[PEP8]

[IMP] module documentation

[ADD] dunniing fees translations

[FIX] name of level in tests

[TYPOS]

Set all addons to uninstallable

[ADD] credit control dunning fees module

[ADD] docstring

[FIX] FeesComputer model specification to act as a abstract class without needing overriding

[IMP] fees column in report and mail

[FIX] dunning fees computer to register itself

[RM] unused import

[PEP8]

[IMP] module documentation

[ADD] dunniing fees translations

[FIX] name of level in tests

[TYPOS]

Set all addons to uninstallable

Rename all addons to xxx_unported to be travis compliant

[ADD] credit control dunning fees module

[ADD] docstring

[FIX] FeesComputer model specification to act as a abstract class without needing overriding

[IMP] fees column in report and mail

[FIX] dunning fees computer to register itself

[RM] unused import

[PEP8]

[IMP] module documentation

[ADD] dunniing fees translations

[FIX] name of level in tests

[TYPOS]

Set all addons to uninstallable

Rename all addons to xxx_unported to be travis compliant

Revert "Rename all addons to xxx_unported to be travis compliant"

This reverts commit 7eb182744f.

[ADD] credit control dunning fees module

[ADD] docstring

[FIX] FeesComputer model specification to act as a abstract class without needing overriding

[IMP] fees column in report and mail

[FIX] dunning fees computer to register itself

[RM] unused import

[PEP8]

[IMP] module documentation

[ADD] dunniing fees translations

[FIX] name of level in tests

[TYPOS]

Set all addons to uninstallable

Rename all addons to xxx_unported to be travis compliant

Revert "Rename all addons to xxx_unported to be travis compliant"

This reverts commit 7eb182744f.

[FIX] move all unported addons into __unported__ folder instead of adding _unported suffix

[FIX] flake8 PEP8 for module account_credit_control_dunning_fees

[FIX] flake8 PEP8 for module account_credit_control_dunning_fees

[FIX] pep8 line length to 80, activate pep8 check in travis, and add noqa on scenario while waiting improvement of quality-tools

Add missing security on `credit.control.dunning.fees.computer`
This commit is contained in:
Nicolas Bessi
2014-04-14 13:57:02 +02:00
committed by Akim Juillerat
parent 44f33802cd
commit 089b4846b4
5 changed files with 338 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Nicolas Bessi
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{'name': 'Credit control dunning fees',
'version': '0.1.0',
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Accounting',
'complexity': 'normal',
'depends': ['account_credit_control'],
'description': """
Dunning Fees for Credit Control
===============================
This extention of credit control adds the notion of dunning fees
on credit control lines.
Configuration
-------------
For release 0.1 only fixed fees are supported.
You can specifiy a fixed fees amount, a product and a currency
on the credit control level form.
The amount will be used as fees values the currency will determine
the currency of the fee. If the credit control line has not the
same currency as the fees currency, fees will be converted to
the credit control line currency.
The product is used to compute taxes in reconciliation process.
Run
---
Fees are automatically computed on credit run and saved
on the generated credit lines.
Fees can be manually edited as long credit line is draft
Credit control Summary report includes a new fees column.
-------
Support of fees price list
""",
'website': 'http://www.camptocamp.com',
'data': ['view/policy_view.xml',
'view/line_view.xml',
'report/report.xml',
'security/ir.model.access.csv'],
'demo': [],
'test': [],
'installable': True,
'auto_install': False,
'license': 'AGPL-3',
'application': False}

View File

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Nicolas Bessi
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
class FeesComputer(orm.BaseModel):
"""Model that compute dunnig fees.
This class does not need any database storage as
it contains pure logic.
It inherits form ``orm.BaseModel`` to benefit of orm facility
Similar to AbstractModel but log access and actions
"""
_name = 'credit.control.dunning.fees.computer'
_auto = False
_log_access = True
_register = True
_transient = False
def _get_compute_fun(self, level_fees_type):
"""Retrieve function of class that should compute the fees based on type
:param level_fee_type: type exisiting in model
`credit.control.policy.level`
for field dunning_fees_type
:returns: a function of class :class:`FeesComputer`
with following signature
self, cr, uid, credit_line (record), context
"""
if level_fees_type == 'fixed':
return self.compute_fixed_fees
else:
raise NotImplementedError('fees type %s is not supported' %
level_fees_type)
def _compute_fees(self, cr, uid, credit_line_ids, context=None):
"""Compute fees for `credit_line_ids` parameter
Fees amount is written on credit line in field dunning_fees_amount
:param credit_line_ids: list of `credit.control.line` ids
:returns: `credit_line_ids` list of `credit.control.line` ids
"""
if context is None:
context = {}
if not credit_line_ids:
return credit_line_ids
c_model = self.pool['credit.control.line']
credit_lines = c_model.browse(cr, uid, credit_line_ids,
context=context)
for credit in credit_lines:
# if there is no dependence between generated credit lines
# this could be threaded
self._compute(cr, uid, credit, context=context),
return credit_line_ids
def _compute(self, cr, uid, credit_line, context=None):
"""Compute fees for a given credit line
Fees amount is written on credit line in field dunning_fees_amount
:param credit_line: credit line record
:returns: `credit_line` record
"""
fees_type = credit_line.policy_level_id.dunning_fees_type
compute = self._get_compute_fun(fees_type)
fees = compute(cr, uid, credit_line, context=context)
if fees:
credit_line.write({'dunning_fees_amount': fees},
context=context)
return credit_line
def compute_fixed_fees(self, cr, uid, credit_line, context=None):
"""Compute fees amount for fixed fees.
Correspond to the fixed dunning fees type
if currency of the fees is not the same as the currency
of the credit line, fees amount is converted to
currency of credit line.
:param credit_line: credit line record
:return: fees amount float (in credit line currency)
"""
currency_model = self.pool['res.currency']
credit_currency = credit_line.currency_id
level = credit_line.policy_level_id
fees_amount = level.dunning_fixed_amount
if not fees_amount:
return 0.0
fees_currency = level.dunning_currency_id
if fees_currency == credit_currency:
return fees_amount
else:
return currency_model.compute(cr, uid, fees_currency.id,
credit_currency.id, fees_amount,
context=context)

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Nicolas Bessi
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
class credit_control_run(orm.Model):
"""Add computation of fees"""
_inherit = "credit.control.run"
def _generate_credit_lines(self, cr, uid, run_id, context=None):
"""Override method to add fees computation"""
credit_line_ids = super(credit_control_run,
self)._generate_credit_lines(
cr,
uid,
run_id,
context=context)
fees_model = self.pool['credit.control.dunning.fees.computer']
fees_model._compute_fees(cr, uid, credit_line_ids, context=context)
return credit_line_ids

View File

@@ -0,0 +1,7 @@
id,group_id/id,name,model_id/id,perm_read,perm_write,perm_create,perm_unlink
dunning_fees_manager,account_credit_control.group_account_credit_control_manager,dunning_fees_manager,model_credit_control_dunning_fees_computer,1,1,1,1
dunning_fees_user,account_credit_control.group_account_credit_control_user,dunning_fees_user,model_credit_control_dunning_fees_computer,1,1,1,1
dunning_fees_user,account_credit_control.group_account_credit_control_info,dunning_fees_user,model_credit_control_dunning_fees_computer,1,0,0,0
dunning_fees_account_user,account.group_account_user,dunning_fees_account_user,model_credit_control_dunning_fees_computer,1,0,0,0
dunning_fees_account_manager,account.group_account_manager,dunning_fees_account_manager,model_credit_control_dunning_fees_computer,1,1,1,1
dunning_fees_invoices,account.group_account_invoice,dunning_fees_invoice,model_credit_control_dunning_fees_computer,1,0,0,0
1 id group_id/id name model_id/id perm_read perm_write perm_create perm_unlink
2 dunning_fees_manager account_credit_control.group_account_credit_control_manager dunning_fees_manager model_credit_control_dunning_fees_computer 1 1 1 1
3 dunning_fees_user account_credit_control.group_account_credit_control_user dunning_fees_user model_credit_control_dunning_fees_computer 1 1 1 1
4 dunning_fees_user account_credit_control.group_account_credit_control_info dunning_fees_user model_credit_control_dunning_fees_computer 1 0 0 0
5 dunning_fees_account_user account.group_account_user dunning_fees_account_user model_credit_control_dunning_fees_computer 1 0 0 0
6 dunning_fees_account_manager account.group_account_manager dunning_fees_account_manager model_credit_control_dunning_fees_computer 1 1 1 1
7 dunning_fees_invoices account.group_account_invoice dunning_fees_invoice model_credit_control_dunning_fees_computer 1 0 0 0

View File

@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Nicolas Bessi
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from mock import MagicMock
import openerp.tests.common as test_common
class FixedFeesTester(test_common.TransactionCase):
def setUp(self):
"""Initialize credit control level mock to test fees computations"""
super(FixedFeesTester, self).setUp()
self.currency_model = self.registry('res.currency')
self.euro = self.currency_model.search(self.cr, self.uid,
[('name', '=', 'EUR')])
self.assertTrue(self.euro)
self.euro = self.registry('res.currency').browse(self.cr,
self.uid,
self.euro[0])
self.usd = self.currency_model.search(self.cr, self.uid,
[('name', '=', 'USD')])
self.assertTrue(self.usd)
self.usd = self.registry('res.currency').browse(self.cr,
self.uid,
self.usd[0])
self.euro_level = MagicMock(name='Euro policy level')
self.euro_level.dunning_fixed_amount = 5.0
self.euro_level.dunning_currency_id = self.euro
self.euro_level.dunning_type = 'fixed'
self.usd_level = MagicMock(name='USD policy level')
self.usd_level.dunning_fixed_amount = 5.0
self.usd_level.dunning_currency_id = self.usd
self.usd_level.dunning_type = 'fixed'
self.dunning_model = self.registry(
'credit.control.dunning.fees.computer'
)
def test_type_getter(self):
"""Test that correct compute function is returned for "fixed" type"""
c_fun = self.dunning_model._get_compute_fun('fixed')
self.assertEqual(c_fun, self.dunning_model.compute_fixed_fees)
def test_unknow_type(self):
"""Test that non implemented error is raised if invalide fees type"""
with self.assertRaises(NotImplementedError):
self.dunning_model._get_compute_fun('bang')
def test_computation_same_currency(self):
"""Test that fees are correctly computed with same currency"""
credit_line = MagicMock(name='Euro credit line')
credit_line.policy_level_id = self.euro_level
credit_line.currency_id = self.euro
fees = self.dunning_model.compute_fixed_fees(self.cr, self.uid,
credit_line,
{})
self.assertEqual(fees, self.euro_level.dunning_fixed_amount)
def test_computation_different_currency(self):
"""Test that fees are correctly computed with different currency"""
credit_line = MagicMock(name='USD credit line')
credit_line.policy_level_id = self.euro_level
credit_line.currency_id = self.usd
fees = self.dunning_model.compute_fixed_fees(self.cr, self.uid,
credit_line,
{})
self.assertNotEqual(fees, self.euro_level.dunning_fixed_amount)
def test_no_fees(self):
"""Test that fees are not generated if no amount defined on level"""
credit_line = MagicMock(name='USD credit line')
credit_line.policy_level_id = self.euro_level
self.euro_level.dunning_fixed_amount = 0.0
credit_line.currency_id = self.usd
fees = self.dunning_model.compute_fixed_fees(self.cr, self.uid,
credit_line,
{})
self.assertEqual(fees, 0.0)