Add a selection of currencies for the 'Currencies' rules

It allows to have a different setup for different currencies (the amounts won't
be the same).
This commit is contained in:
Guewen Baconnier
2014-12-04 08:51:30 +01:00
committed by Cyril Gaudin
parent fd2430747e
commit cb488c6329
6 changed files with 200 additions and 8 deletions

View File

@@ -48,6 +48,12 @@ class AccountStatementOperationRule(models.Model):
string='Max. Amount', string='Max. Amount',
digits=dp.get_precision('Account'), digits=dp.get_precision('Account'),
) )
currencies = fields.Many2many(
comodel_name='res.currency',
string='Currencies',
help="For 'Currencies' rules, you can choose for which currencies "
"the rule will be applicable.",
)
sequence = fields.Integer( sequence = fields.Integer(
default=20, default=20,
help="If several rules match, the first one is used.", help="If several rules match, the first one is used.",
@@ -88,15 +94,24 @@ class AccountStatementOperationRule(models.Model):
@api.multi @api.multi
def _is_valid_multicurrency(self, statement_line, move_lines, balance): def _is_valid_multicurrency(self, statement_line, move_lines, balance):
# FIXME: surely wrong """ Check if the multi-currency rule can be applied
if self._is_multicurrency(statement_line):
The rule is applied if and only if:
* The currency is not company's one
* The currency of the statement line and all the lines is the same
* The balance of the amount currencies is 0
* The balance is between the bounds configured on the rule
"""
if not self._is_multicurrency(statement_line):
return False return False
currency = statement_line.currency_for_rules() currency = statement_line.currency_for_rules()
if currency not in self.currencies:
return False
amount_currency = statement_line.amount_currency amount_currency = statement_line.amount_currency
for move_line in move_lines: for move_line in move_lines:
if move_line.currency_id != statement_line.currency_id: if move_line.currency_id != statement_line.currency_id:
# use case not supported, no rule found # use case not supported, no rule found
return self.browse() return False
amount_currency -= move_line.amount_currency amount_currency -= move_line.amount_currency
# amount in currency is the same, so the balance is # amount in currency is the same, so the balance is

View File

@@ -20,3 +20,4 @@
############################################################################## ##############################################################################
from . import test_rule_rounding from . import test_rule_rounding
from . import test_rule_currency

View File

@@ -22,13 +22,15 @@
def prepare_statement(test, difference, def prepare_statement(test, difference,
statement_line_currency=None, statement_line_currency=None,
move_line_currency=None): move_line_currency=None,
amount_currency_difference=0):
""" Prepare a bank statement line and a move line """ Prepare a bank statement line and a move line
The difference is applied on the bank statement line relatively to The difference is applied on the bank statement line relatively to
the move line. the move line.
""" """
amount = 100 amount = 100
amount_currency = 120
statement_obj = test.env['account.bank.statement'] statement_obj = test.env['account.bank.statement']
statement_line_obj = test.env['account.bank.statement.line'] statement_line_obj = test.env['account.bank.statement.line']
move_obj = test.env['account.move'] move_obj = test.env['account.move']
@@ -43,7 +45,11 @@ def prepare_statement(test, difference,
'statement_id': statement.id, 'statement_id': statement.id,
} }
if statement_line_currency: if statement_line_currency:
line_vals['currency_id'] = statement_line_currency.id line_vals.update({
'currency_id': statement_line_currency.id,
'amount_currency': amount_currency + amount_currency_difference,
})
statement_line = statement_line_obj.create(line_vals) statement_line = statement_line_obj.create(line_vals)
move = move_obj.create({ move = move_obj.create({
'journal_id': test.ref('account.sales_journal') 'journal_id': test.ref('account.sales_journal')
@@ -55,7 +61,10 @@ def prepare_statement(test, difference,
'debit': amount, 'debit': amount,
} }
if move_line_currency: if move_line_currency:
line_vals['currency_id'] = move_line_currency.id line_vals.update({
'currency_id': move_line_currency.id,
'amount_currency': amount_currency,
})
move_line = move_line_obj.create(line_vals) move_line = move_line_obj.create(line_vals)
line_vals = { line_vals = {
'move_id': move.id, 'move_id': move.id,

View File

@@ -0,0 +1,164 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Guewen Baconnier
# 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.tests import common
from .common import prepare_statement
class TestRuleCurrency(common.TransactionCase):
def setUp(self):
super(TestRuleCurrency, self).setUp()
self.operation_obj = self.env['account.statement.operation.template']
self.rule_obj = self.env['account.statement.operation.rule']
self.aed = self.browse_ref('base.AED')
self.afn = self.browse_ref('base.AFN')
self.all = self.browse_ref('base.ALL')
self.amd = self.browse_ref('base.AMD')
self.aoa = self.browse_ref('base.AOA')
self.operation_currency_1 = self.operation_obj.create({
'name': 'Currency AED, AFR, ALL -1.0 to 0.0',
'label': 'Currency',
'account_id': self.ref('account.rsa'),
'amount_type': 'percentage_of_total',
'amount': 100.0,
})
self.rule_currency_1 = self.rule_obj.create({
'name': 'Currency AED, AFR, ALL -1.0 to 0.0',
'rule_type': 'currency',
'operations': [(6, 0, (self.operation_currency_1.id, ))],
'amount_min': -1.0,
'amount_max': 0,
'sequence': 1,
'currencies': [(6, 0, [self.aed.id, self.afn.id, self.all.id])],
})
self.operation_currency_2 = self.operation_obj.create({
'name': 'Currency AED, AFR, ALL -2.0 to -1.0',
'label': 'Currency',
'account_id': self.ref('account.rsa'),
'amount_type': 'percentage_of_total',
'amount': 100.0,
})
self.rule_currency_2 = self.rule_obj.create({
'name': 'Currency AED, AFR, ALL -2.0 to 1.0',
'rule_type': 'currency',
'operations': [(6, 0, (self.operation_currency_2.id, ))],
'amount_min': -2.0,
'amount_max': -1.0,
'sequence': 2,
'currencies': [(6, 0, [self.aed.id, self.afn.id, self.all.id])],
})
self.operation_currency_3 = self.operation_obj.create({
'name': 'Currency AMD, AOA -2.0 to 0.0',
'label': 'Currency',
'account_id': self.ref('account.rsa'),
'amount_type': 'percentage_of_total',
'amount': 100.0,
})
self.rule_currency_3 = self.rule_obj.create({
'name': 'Currency AMD, AOA -2.0 to 0.0',
'rule_type': 'currency',
'operations': [(6, 0, (self.operation_currency_3.id, ))],
'amount_min': -2,
'amount_max': 0,
'sequence': 2,
'currencies': [(6, 0, [self.amd.id, self.aoa.id])],
})
def test_no_currency_match(self):
"""No rules for the current currency"""
sek = self.browse_ref('base.SEK')
statement_line, move_line = prepare_statement(
self, -0.5,
statement_line_currency=sek,
move_line_currency=sek)
ops = self.rule_obj.operations_for_reconciliation(statement_line.id,
move_line.ids)
self.assertFalse(ops)
def test_rounding_lines(self):
"""No Currencies rules on lines with company currency"""
statement_line, move_line = prepare_statement(self, -0.5)
ops = self.rule_obj.operations_for_reconciliation(statement_line.id,
move_line.ids)
self.assertFalse(ops)
def test_currency_rule_1(self):
"""Rule 1 is found with -0.5 AED"""
statement_line, move_line = prepare_statement(
self, -0.5,
statement_line_currency=self.aed,
move_line_currency=self.aed,
amount_currency_difference=0)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_currency_1)
def test_currency_rule_2(self):
"""Rule 2 is found with -2 AED"""
statement_line, move_line = prepare_statement(
self, -2,
statement_line_currency=self.aed,
move_line_currency=self.aed,
amount_currency_difference=0)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_currency_2)
def test_currency_rule_3(self):
"""Rule 3 is found with -2 AOA"""
statement_line, move_line = prepare_statement(
self, -2,
statement_line_currency=self.aoa,
move_line_currency=self.aoa,
amount_currency_difference=0)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_currency_3)
def test_currency_rule_not_in_bounds(self):
"""No rule is found with -3 AOA"""
statement_line, move_line = prepare_statement(
self, -3,
statement_line_currency=self.aoa,
move_line_currency=self.aoa,
amount_currency_difference=0)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertFalse(rule)
def test_no_rule_amount_currency_different(self):
"""No rule when amount currency is different"""
statement_line, move_line = prepare_statement(
self, -0.5,
statement_line_currency=self.aed,
move_line_currency=self.aed,
amount_currency_difference=0.5)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertFalse(rule)
def test_rule_amount_currency_difference_near_zero(self):
"""Apply the rule when the difference is near 0"""
statement_line, move_line = prepare_statement(
self, -0.5,
statement_line_currency=self.aed,
move_line_currency=self.aed,
amount_currency_difference=-0.001)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_currency_1)

View File

@@ -19,7 +19,6 @@
# #
############################################################################## ##############################################################################
import unittest2
from openerp.tests import common from openerp.tests import common
from .common import prepare_statement from .common import prepare_statement

View File

@@ -23,9 +23,13 @@
<field name="amount_min" class="oe_inline" /> And <field name="amount_min" class="oe_inline" /> And
<field name="amount_max" class="oe_inline" /> <field name="amount_max" class="oe_inline" />
</div> </div>
<label for="currencies" string="And the currency is one of" attrs="{'invisible': [('rule_type', '!=', 'currency')]}"/>
<div attrs="{'invisible': [('rule_type', '!=', 'currency')]}">
<field name="currencies" class="oe_inline" widget="many2many_tags"/>
</div>
</group> </group>
<group name="operations"> <group name="operations">
<label string="Then the following operations will be applied:" colspan="2"/> <label for="operations" string="Then the following operations will be applied:" colspan="2"/>
<field name="operations" nolabel="1"/> <field name="operations" nolabel="1"/>
</group> </group>
</sheet> </sheet>