Merge pull request #63 from guewen/8.0-account_credit_control_dunning_fees-migr

Port account_credit_control_dunning_fees to 8.0
This commit is contained in:
Nicolas Bessi (nbessi)
2014-12-02 14:59:12 +01:00
18 changed files with 119 additions and 131 deletions

View File

@@ -1,12 +0,0 @@
<openerp>
<data>
<report auto="False"
id="account_credit_control.report_webkit_html"
model="credit.control.communication"
name="credit_control_summary"
file="account_credit_control_dunning_fees/report/credit_control_summary.html.mako"
string="Credit Summary"
report_type="webkit"
webkit_header="report_webkit.ir_header_webkit_basesample0"/>
</data>
</openerp>

View File

@@ -0,0 +1,30 @@
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

View File

@@ -25,47 +25,15 @@
'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'],
'report/report_credit_control_summary.xml',
'security/ir.model.access.csv',
],
'demo': [],
'test': [],
'installable': False,
'installable': True,
'auto_install': False,
'license': 'AGPL-3',
'application': False}

View File

@@ -18,16 +18,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
from openerp import models, api
class FeesComputer(orm.BaseModel):
class FeesComputer(models.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
It inherits form ``models.BaseModel`` to benefit of orm facility
Similar to AbstractModel but log access and actions
"""
@@ -38,16 +38,18 @@ class FeesComputer(orm.BaseModel):
_register = True
_transient = False
@api.model
def _get_compute_fun(self, level_fees_type):
"""Retrieve function of class that should compute the fees based on type
"""Retrieve function of class that should compute the fees based
on type
:param level_fee_type: type exisiting in model
:param level_fee_type: type existing 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
self, credit_line (record)
"""
if level_fees_type == 'fixed':
@@ -56,33 +58,30 @@ class FeesComputer(orm.BaseModel):
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
@api.model
def _compute_fees(self, credit_lines):
"""Compute fees for `credit_lines` parameter
Fees amount is written on credit line in field dunning_fees_amount
Fees amount is written on credit lines in the field dunning_fees_amount
:param credit_line_ids: list of `credit.control.line` ids
:param credit_lines: recordset of `credit.control.line`
:returns: `credit_line_ids` list of `credit.control.line` ids
:returns: recordset of `credit.control.line`
"""
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)
if not credit_lines:
return credit_lines
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
self._compute(credit)
return credit_lines
def _compute(self, cr, uid, credit_line, context=None):
@api.model
def _compute(self, credit_line):
"""Compute fees for a given credit line
Fees amount is written on credit line in field dunning_fees_amount
Fees amount is written on credit line in then field dunning_fees_amount
:param credit_line: credit line record
@@ -90,13 +89,13 @@ class FeesComputer(orm.BaseModel):
"""
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)
fees = compute(credit_line)
if fees:
credit_line.write({'dunning_fees_amount': fees},
context=context)
credit_line.write({'dunning_fees_amount': fees})
return credit_line
def compute_fixed_fees(self, cr, uid, credit_line, context=None):
@api.model
def compute_fixed_fees(self, credit_line):
"""Compute fees amount for fixed fees.
Correspond to the fixed dunning fees type
@@ -109,7 +108,6 @@ class FeesComputer(orm.BaseModel):
: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
@@ -119,6 +117,4 @@ class FeesComputer(orm.BaseModel):
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)
return fees_currency.compute(fees_amount, credit_currency)

View File

@@ -18,12 +18,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp import models, fields
class credit_control_line(orm.Model):
class CreditControlLine(models.Model):
"""Add dunning_fees_amount_fees field"""
_inherit = "credit.control.line"
_columns = {'dunning_fees_amount': fields.float('Fees')}
dunning_fees_amount = fields.Float(string='Fees')

View File

@@ -18,19 +18,23 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp import models, fields
class credit_control_policy(orm.Model):
class CreditControlPolicy(models.Model):
"""ADD dunning fees fields"""
_inherit = "credit.control.policy.level"
_columns = {'dunning_product_id': fields.many2one('product.product',
'Fees Product'),
'dunning_fixed_amount': fields.float('Fees Fixed Amount'),
'dunning_currency_id': fields.many2one('res.currency',
'Fees currency'),
# planned type are fixed, percent, compound
'dunning_fees_type': fields.selection([('fixed', 'Fixed')])}
_defaults = {'dunning_fees_type': 'fixed'}
dunning_product_id = fields.Many2one('product.product',
string='Fees Product')
dunning_fixed_amount = fields.Float(string='Fees Fixed Amount')
dunning_currency_id = fields.Many2one('res.currency',
string='Fees currency')
# planned type are fixed, percent, compound
dunning_fees_type = fields.Selection([('fixed', 'Fixed')],
string='Type',
default='fixed')

View File

@@ -18,22 +18,19 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
from openerp import models, api
class credit_control_run(orm.Model):
class CreditControlRun(models.Model):
"""Add computation of fees"""
_inherit = "credit.control.run"
def _generate_credit_lines(self, cr, uid, run_id, context=None):
@api.multi
@api.returns('credit.control.line')
def _generate_credit_lines(self):
"""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
credit_lines = super(CreditControlRun, self)._generate_credit_lines()
fees_model = self.env['credit.control.dunning.fees.computer']
fees_model._compute_fees(credit_lines)
return credit_lines

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="report_credit_control_summary_document_fees"
inherit_id="account_credit_control.report_credit_control_summary_document">
<xpath expr="//table[@id='summary_table']/thead/tr/th[last()]" position="after">
<th class="text-right">Fees</th>
</xpath>
<xpath expr="//span[@t-field='l.balance_due']" position="replace">
<span t-field="l.balance_due"/>
</xpath>
<xpath expr="//table[@id='summary_table']/tbody/tr/td[last()]" position="after">
<td class="text-right">
<span t-field="l.dunning_fees_amount"
t-field-options='{"widget": "monetary",
"display_currency": "l.currency_id or l.company_id.currency_id"}'/>
</td>
</xpath>
</template>
</data>
</openerp>

View File

@@ -19,5 +19,3 @@
#
##############################################################################
from . import test_fees_generation
checks = [test_fees_generation]

View File

@@ -19,28 +19,21 @@
#
##############################################################################
from mock import MagicMock
import openerp.tests.common as test_common
from openerp.tests import common
class FixedFeesTester(test_common.TransactionCase):
@common.at_install(True)
@common.post_install(True)
class FixedFeesTester(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.currency_model = self.env['res.currency']
self.euro = self.currency_model.search([('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.usd = self.currency_model.search([('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
@@ -51,9 +44,7 @@ class FixedFeesTester(test_common.TransactionCase):
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'
)
self.dunning_model = self.env['credit.control.dunning.fees.computer']
def test_type_getter(self):
"""Test that correct compute function is returned for "fixed" type"""
@@ -70,9 +61,7 @@ class FixedFeesTester(test_common.TransactionCase):
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,
{})
fees = self.dunning_model.compute_fixed_fees(credit_line)
self.assertEqual(fees, self.euro_level.dunning_fixed_amount)
def test_computation_different_currency(self):
@@ -80,9 +69,7 @@ class FixedFeesTester(test_common.TransactionCase):
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,
{})
fees = self.dunning_model.compute_fixed_fees(credit_line)
self.assertNotEqual(fees, self.euro_level.dunning_fixed_amount)
def test_no_fees(self):
@@ -91,7 +78,5 @@ class FixedFeesTester(test_common.TransactionCase):
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,
{})
fees = self.dunning_model.compute_fixed_fees(credit_line)
self.assertEqual(fees, 0.0)