Merge pull request #141 from cyrilgdn/9.0-account_statement_operation_rule

account_operation_rule: Migration V9
This commit is contained in:
Joël Grand-Guillaume
2016-06-29 08:32:47 +02:00
committed by GitHub
22 changed files with 1895 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License
Bank Statement Operation Rules
==============================
This module complements the Reconciliation of the bank statements. When
the bank statement matches one or more journal entry for a line and
there is a remaining balance, Odoo proposes you to click on buttons that
will generate write-off entries according to pre-configured *Statement
Operation Templates*. The aim of this module is to automatically click
for you on these buttons (i.e. create the write-off journal entries)
when some rules are respected, rules that you can configure.
It contains 2 types of rules (but can be extended with additional rules),
described below:
Roundings
The most basic rule: when the remaining balance is within a range, 1
or more operations are applied.
Currencies
When the remaining balance is within a range and the currency of all
the lines is the same but different from the company's, and the amount
currency is the same, 1 or more operations are applied.
Configuration
-------------
As this module aims to automatize the ``Reconciliation Models``,
you first want to ensure that you have at least one operation configured.
You can find them in ``Invoicing > Dashboard > Bank card > More
> Reconciliation Models``. An example of a common operation is:
=================== ========================== ======= ========
Account Amount Type Amount Label
=================== ========================== ======= ========
Depends of the l10n Percentage of open balance 100.0 % Rounding
=================== ========================== ======= ========
The configuration of the rules themselves happens in ``Invoicing >
Dashboard > Bank card > More > Reconciliation Rules``. Refer to
the description of the types of rules above in case of doubt. The form
is divided in 2 parts: **Rule** and **Result**. The rule part is where
you will set the conditions and the result part is what operations will
be done if the conditions are valid.
For the **Roundings** rules, you will set a min. and a max. amount. It
can be negative or positive. The amount is compared to the remaining
balance when lines are matched in the bank statement. Example: if you
want to create a move line in a loss account when you received 1.- not
enough, you can create a rule with an min. amount of -1.0 and a max.
amount of 0.0.
For the **Currencies** rules, the min. and max. amount have the same
properties, but you will also set the currencies for which the rule
applies. Setting the currency allows to configure different amounts
according to the currencies.
Only the first rule matching the current situation is used, so if you
have several rules overlapping for some reason, be sure to order them
appropriately in the list view.
Usage
-----
When you use the *Reconcile* button of a bank statement, Odoo
automatically proposes you matching journal entries for each statement
line. This module automatically adds journal entries generated from the
*Reconciliation Models* if a rule matches with the current
situation, so there is nothing special to do once the rules are
configured.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/98/9.0
Credits
=======
Contributors
------------
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
* Cyril Gaudin <cyril.gaudin@camptocamp.com>
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization
whose mission is to support the collaborative development of Odoo
features and promote its widespread use.
To contribute to this module, please visit
http://odoo-community.org.

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import model

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{'name': 'Bank Statement Operation Rules',
'version': '9.0.1.0.0',
'author': 'Camptocamp, Odoo Community Association (OCA)',
'maintainer': 'Odoo Community Association (OCA)',
'license': 'AGPL-3',
'category': 'Accounting & Finance',
'depends': [
'account',
],
'website': 'http://www.camptocamp.com',
'data': [
'view/account_operation_rule.xml',
'view/account_operation_rule_view.xml',
'security/ir.model.access.csv',
],
'installable': True,
'auto_install': False,
}

View File

@@ -0,0 +1,152 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_operation_rule
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-16 14:46+0000\n"
"PO-Revision-Date: 2015-03-16 14:46+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid "<p class=\"oe_view_nocontent_create\">\n"
" Click to create a statement operation rule.\n"
" </p><p>\n"
" Those can be used to automatically create a move line when reconciling\n"
" your bank statements.\n"
" </p>\n"
" "
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And the currency is one of"
msgstr ""
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,create_uid:0
msgid "Created by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,create_date:0
msgid "Created on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,currencies:0
#: selection:account.operation.rule,rule_type:0
msgid "Currencies"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,currencies:0
msgid "For 'Currencies' rules, you can choose for which currencies the rule will be applicable."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,id:0
msgid "ID"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,sequence:0
msgid "If several rules match, the first one is used."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_max:0
msgid "Max. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_min:0
msgid "Min. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,name:0
msgid "Name"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,operations:0
msgid "Operations"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Result"
msgstr ""
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Roundings"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Rule"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,sequence:0
msgid "Sequence"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Statement Operation Rule"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_search
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_tree
#: model:ir.actions.act_window,name:account_operation_rule.action_account_operation_rule
#: model:ir.ui.menu,name:account_operation_rule.menu_action_account_operation_rule
msgid "Statement Operation Rules"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Then the following operations will be applied:"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,rule_type:0
msgid "Type"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "When the balance is between"
msgstr ""

View File

@@ -0,0 +1,161 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_operation_rule
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: bank-statement-reconcile (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-04-20 02:39+0000\n"
"PO-Revision-Date: 2016-04-19 11:45+0000\n"
"Last-Translator: <>\n"
"Language-Team: German (http://www.transifex.com/oca/OCA-bank-statement-reconcile-8-0/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to create a statement operation rule.\n"
" </p><p>\n"
" Those can be used to automatically create a move line when reconciling\n"
" your bank statements.\n"
" </p>\n"
" "
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And the currency is one of"
msgstr ""
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Kontoauszugzeile"
#. module: account_operation_rule
#: field:account.operation.rule,create_uid:0
msgid "Created by"
msgstr "Angelegt durch"
#. module: account_operation_rule
#: field:account.operation.rule,create_date:0
msgid "Created on"
msgstr "Angelegt am"
#. module: account_operation_rule
#: field:account.operation.rule,currencies:0
#: selection:account.operation.rule,rule_type:0
msgid "Currencies"
msgstr ""
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Dunning Fees"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,currencies:0
msgid ""
"For 'Currencies' rules, you can choose for which currencies the rule will be"
" applicable."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,id:0
msgid "ID"
msgstr "ID"
#. module: account_operation_rule
#: help:account.operation.rule,sequence:0
msgid "If several rules match, the first one is used."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_uid:0
msgid "Last Updated by"
msgstr "Letzte Aktualisierung durch"
#. module: account_operation_rule
#: field:account.operation.rule,write_date:0
msgid "Last Updated on"
msgstr "Letzte Aktualisierung am"
#. module: account_operation_rule
#: field:account.operation.rule,amount_max:0
msgid "Max. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_min:0
msgid "Min. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,name:0
msgid "Name"
msgstr "Bezeichnung"
#. module: account_operation_rule
#: field:account.operation.rule,operations:0
msgid "Operations"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Result"
msgstr ""
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Roundings"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Rule"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,sequence:0
msgid "Sequence"
msgstr "Reihenfolge"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Statement Operation Rule"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_search
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_tree
#: model:ir.actions.act_window,name:account_operation_rule.action_account_operation_rule
#: model:ir.ui.menu,name:account_operation_rule.menu_action_account_operation_rule
msgid "Statement Operation Rules"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Then the following operations will be applied:"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,rule_type:0
msgid "Type"
msgstr "Art"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "When the balance is between"
msgstr ""

View File

@@ -0,0 +1,161 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_operation_rule
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: bank-statement-reconcile (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-04-20 02:39+0000\n"
"PO-Revision-Date: 2016-04-19 11:45+0000\n"
"Last-Translator: <>\n"
"Language-Team: Spanish (http://www.transifex.com/oca/OCA-bank-statement-reconcile-8-0/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to create a statement operation rule.\n"
" </p><p>\n"
" Those can be used to automatically create a move line when reconciling\n"
" your bank statements.\n"
" </p>\n"
" "
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And the currency is one of"
msgstr ""
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,create_uid:0
msgid "Created by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,create_date:0
msgid "Created on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,currencies:0
#: selection:account.operation.rule,rule_type:0
msgid "Currencies"
msgstr ""
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Dunning Fees"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,currencies:0
msgid ""
"For 'Currencies' rules, you can choose for which currencies the rule will be"
" applicable."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,id:0
msgid "ID"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,sequence:0
msgid "If several rules match, the first one is used."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_max:0
msgid "Max. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_min:0
msgid "Min. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,name:0
msgid "Name"
msgstr "Nombre"
#. module: account_operation_rule
#: field:account.operation.rule,operations:0
msgid "Operations"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Result"
msgstr ""
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Roundings"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Rule"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,sequence:0
msgid "Sequence"
msgstr "Secuencia"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Statement Operation Rule"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_search
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_tree
#: model:ir.actions.act_window,name:account_operation_rule.action_account_operation_rule
#: model:ir.ui.menu,name:account_operation_rule.menu_action_account_operation_rule
msgid "Statement Operation Rules"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Then the following operations will be applied:"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,rule_type:0
msgid "Type"
msgstr "Tipo"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "When the balance is between"
msgstr ""

View File

@@ -0,0 +1,158 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_operation_rule
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-16 14:46+0000\n"
"PO-Revision-Date: 2015-03-16 14:46+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid "<p class=\"oe_view_nocontent_create\">\n"
" Click to create a statement operation rule.\n"
" </p><p>\n"
" Those can be used to automatically create a move line when reconciling\n"
" your bank statements.\n"
" </p>\n"
" "
msgstr "<p class=\"oe_view_nocontent_create\">\n"
" Cliquer pour créer une nouvelle règle d'opération relevé.\n"
" </p><p>\n"
" Elles peuvent être utilisées pour automatiser la création de lignes "
" quand vous réconciliez des relevés bancaires."
" </p>\n"
" "
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And"
msgstr "Et"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And the currency is one of"
msgstr "Et la devise est une des suivantes"
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Ligne de relevé bancaire"
#. module: account_operation_rule
#: field:account.operation.rule,create_uid:0
msgid "Created by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,create_date:0
msgid "Created on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,currencies:0
#: selection:account.operation.rule,rule_type:0
msgid "Currencies"
msgstr "Devises"
#. module: account_operation_rule
#: help:account.operation.rule,currencies:0
msgid "For 'Currencies' rules, you can choose for which currencies the rule will be applicable."
msgstr "Pour les règles 'Devises', vous pouvez sélectionner les devises pour lesquelles la règle s'applique."
#. module: account_operation_rule
#: field:account.operation.rule,id:0
msgid "ID"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,sequence:0
msgid "If several rules match, the first one is used."
msgstr "Si plusieurs règles correspondent, la première est utilisée."
#. module: account_operation_rule
#: field:account.operation.rule,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_max:0
msgid "Max. Amount"
msgstr "Montant max."
#. module: account_operation_rule
#: field:account.operation.rule,amount_min:0
msgid "Min. Amount"
msgstr "Montant min."
#. module: account_operation_rule
#: field:account.operation.rule,name:0
msgid "Name"
msgstr "Nom"
#. module: account_operation_rule
#: field:account.operation.rule,operations:0
msgid "Operations"
msgstr "Opérations"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Result"
msgstr "Résultat"
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Roundings"
msgstr "Arrondis"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Rule"
msgstr "Règle"
#. module: account_operation_rule
#: field:account.operation.rule,sequence:0
msgid "Sequence"
msgstr "Séquence"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Statement Operation Rule"
msgstr "Règle d'opération de relevé"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_search
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_tree
#: model:ir.actions.act_window,name:account_operation_rule.action_account_operation_rule
#: model:ir.ui.menu,name:account_operation_rule.menu_action_account_operation_rule
msgid "Statement Operation Rules"
msgstr "Règles d'opération de relevé"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Then the following operations will be applied:"
msgstr "Alors l'opération suivant sera appliquée :"
#. module: account_operation_rule
#: field:account.operation.rule,rule_type:0
msgid "Type"
msgstr "Type"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "When the balance is between"
msgstr "Quand la balance est entre"

View File

@@ -0,0 +1,161 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_operation_rule
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: bank-statement-reconcile (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-04-20 02:39+0000\n"
"PO-Revision-Date: 2016-04-19 11:45+0000\n"
"Last-Translator: <>\n"
"Language-Team: Italian (http://www.transifex.com/oca/OCA-bank-statement-reconcile-8-0/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to create a statement operation rule.\n"
" </p><p>\n"
" Those can be used to automatically create a move line when reconciling\n"
" your bank statements.\n"
" </p>\n"
" "
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And the currency is one of"
msgstr ""
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Linea estratto conto"
#. module: account_operation_rule
#: field:account.operation.rule,create_uid:0
msgid "Created by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,create_date:0
msgid "Created on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,currencies:0
#: selection:account.operation.rule,rule_type:0
msgid "Currencies"
msgstr ""
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Dunning Fees"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,currencies:0
msgid ""
"For 'Currencies' rules, you can choose for which currencies the rule will be"
" applicable."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,id:0
msgid "ID"
msgstr ""
#. module: account_operation_rule
#: help:account.operation.rule,sequence:0
msgid "If several rules match, the first one is used."
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_max:0
msgid "Max. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,amount_min:0
msgid "Min. Amount"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,name:0
msgid "Name"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,operations:0
msgid "Operations"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Result"
msgstr ""
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Roundings"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Rule"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,sequence:0
msgid "Sequence"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Statement Operation Rule"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_search
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_tree
#: model:ir.actions.act_window,name:account_operation_rule.action_account_operation_rule
#: model:ir.ui.menu,name:account_operation_rule.menu_action_account_operation_rule
msgid "Statement Operation Rules"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Then the following operations will be applied:"
msgstr ""
#. module: account_operation_rule
#: field:account.operation.rule,rule_type:0
msgid "Type"
msgstr ""
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "When the balance is between"
msgstr ""

View File

@@ -0,0 +1,162 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_operation_rule
#
# Translators:
# Matjaž Mozetič <m.mozetic@matmoz.si>, 2016
msgid ""
msgstr ""
"Project-Id-Version: bank-statement-reconcile (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-04-20 02:39+0000\n"
"PO-Revision-Date: 2016-04-20 05:32+0000\n"
"Last-Translator: Matjaž Mozetič <m.mozetic@matmoz.si>\n"
"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-bank-statement-reconcile-8-0/language/sl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: sl\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to create a statement operation rule.\n"
" </p><p>\n"
" Those can be used to automatically create a move line when reconciling\n"
" your bank statements.\n"
" </p>\n"
" "
msgstr "<p class=\"oe_view_nocontent_create\">\n Dodaj pravilo za operacije na izpiskih.\n </p><p>\n Uporabijo se lahko za samodejno ustvarjanje postavk premikov ob usklajevanju\n bančnih izpiskov.\n </p>\n "
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And"
msgstr "in"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "And the currency is one of"
msgstr "in je valuta ena izmed"
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Postavka bančnega izpiska"
#. module: account_operation_rule
#: field:account.operation.rule,create_uid:0
msgid "Created by"
msgstr "Ustvaril"
#. module: account_operation_rule
#: field:account.operation.rule,create_date:0
msgid "Created on"
msgstr "Ustvarjeno"
#. module: account_operation_rule
#: field:account.operation.rule,currencies:0
#: selection:account.operation.rule,rule_type:0
msgid "Currencies"
msgstr "Valute"
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Dunning Fees"
msgstr "Provizije pri izterjavi"
#. module: account_operation_rule
#: help:account.operation.rule,currencies:0
msgid ""
"For 'Currencies' rules, you can choose for which currencies the rule will be"
" applicable."
msgstr "Pri pravilih 'valut' lahko izberete, na katere valute se pravilo nanaša."
#. module: account_operation_rule
#: field:account.operation.rule,id:0
msgid "ID"
msgstr "ID"
#. module: account_operation_rule
#: help:account.operation.rule,sequence:0
msgid "If several rules match, the first one is used."
msgstr "Če se ujema več pravil, se uporabi prvo."
#. module: account_operation_rule
#: field:account.operation.rule,write_uid:0
msgid "Last Updated by"
msgstr "Zadnji posodobil"
#. module: account_operation_rule
#: field:account.operation.rule,write_date:0
msgid "Last Updated on"
msgstr "Zadnjič posodobljeno"
#. module: account_operation_rule
#: field:account.operation.rule,amount_max:0
msgid "Max. Amount"
msgstr "Maks. znesek"
#. module: account_operation_rule
#: field:account.operation.rule,amount_min:0
msgid "Min. Amount"
msgstr "Min. znesek"
#. module: account_operation_rule
#: field:account.operation.rule,name:0
msgid "Name"
msgstr "Naziv"
#. module: account_operation_rule
#: field:account.operation.rule,operations:0
msgid "Operations"
msgstr "Operacije"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Result"
msgstr "Rezultat"
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Roundings"
msgstr "Zaokroževanja"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Rule"
msgstr "Pravilo"
#. module: account_operation_rule
#: field:account.operation.rule,sequence:0
msgid "Sequence"
msgstr "Zaporedje"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Statement Operation Rule"
msgstr "Pravilo operacij z izpiski"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_search
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_tree
#: model:ir.actions.act_window,name:account_operation_rule.action_account_operation_rule
#: model:ir.ui.menu,name:account_operation_rule.menu_action_account_operation_rule
msgid "Statement Operation Rules"
msgstr "Pravilo operacij z izpiski"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "Then the following operations will be applied:"
msgstr "se izvedejo naslednje operacije"
#. module: account_operation_rule
#: field:account.operation.rule,rule_type:0
msgid "Type"
msgstr "Tip"
#. module: account_operation_rule
#: view:account.operation.rule:account_operation_rule.view_account_operation_rule_form
msgid "When the balance is between"
msgstr "Ko je stanje med"

View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
from . import account_journal
from . import account_operation_rule
from . import account_statement_line

View File

@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# © 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, models
class AccountJournal(models.Model):
_inherit = 'account.journal'
@api.multi
def open_reconciliation_rules(self):
return self.env['ir.actions.act_window'].for_xml_id(
"account_operation_rule",
"action_account_operation_rule"
)

View File

@@ -0,0 +1,168 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
from openerp.addons import decimal_precision as dp
class AccountOperationRule(models.Model):
_name = 'account.operation.rule'
_order = 'sequence ASC, id ASC'
name = fields.Char()
rule_type = fields.Selection(
selection=[('rounding', 'Roundings'),
('currency', 'Currencies')],
string='Type',
default='rounding',
required=True,
)
operations = fields.Many2many(
comodel_name='account.operation.template',
)
amount_min = fields.Float(
string='Min. Amount',
digits=dp.get_precision('Account'),
)
amount_max = fields.Float(
string='Max. Amount',
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(
default=20,
help="If several rules match, the first one is used.",
)
@staticmethod
def _between_with_bounds(low, value, high, currency):
""" Equivalent to a three way comparison: ``min <= value <= high``
The comparisons are done with the currency to use the correct
precision.
"""
if currency.compare_amounts(value, low) == -1:
return False
if currency.compare_amounts(value, high) == 1:
return False
return True
@api.multi
def _balance_in_range(self, balance, currency):
amount_min = self.amount_min
amount_max = self.amount_max
return self._between_with_bounds(amount_min, balance,
amount_max, currency)
@api.model
def _is_multicurrency(self, statement_line):
currency = statement_line.currency_for_rules()
company_currency = statement_line.company_id.currency_id
return currency != company_currency
@api.multi
def _is_valid_balance(self, statement_line, balance):
if self._is_multicurrency(statement_line):
return False
currency = statement_line.currency_for_rules()
return self._balance_in_range(balance, currency)
@api.multi
def _is_valid_multicurrency(self, statement_line, move_lines, balance):
""" Check if the multi-currency rule can be applied
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
currency = statement_line.currency_for_rules()
if currency not in self.currencies:
return False
amount_currency = statement_line.amount_currency
for move_line in move_lines:
if move_line.currency_id != statement_line.currency_id:
# use case not supported, no rule found
return False
amount_currency -= move_line.amount_currency
# amount in currency is the same, so the balance is
# a difference due to currency rates
if statement_line.currency_id.is_zero(amount_currency):
return self._balance_in_range(balance, currency)
return False
@api.multi
def is_valid(self, statement_line, move_lines, balance):
""" Returns True if a rule applies to a group of statement_line +
move lines.
This is the public method where the rule is evaluated whatever
its type is. When a rule returns True, it means that it is a
candidate for the current reconciliation. The rule with the lowest
number in the ``sequence`` field is chosen.
:param statement_line: the line to reconcile
:param move_lines: the selected move lines for reconciliation
:param balance: the balance between the statement_line and the
move_lines. It could be computed here but it is
computed before to avoid to compute it for each
rule when called on multiple rules.
"""
self.ensure_one()
if self.rule_type == 'rounding':
return self._is_valid_balance(statement_line, balance)
elif self.rule_type == 'currency':
return self._is_valid_multicurrency(statement_line,
move_lines,
balance)
@api.model
def find_first_rule(self, statement_line, move_lines):
""" Find the rules that apply to a statement line and
a selection of move lines.
:param statement_line: the line to reconcile
:param move_lines: the selected move lines for reconciliation
"""
balance = statement_line.amount
for move_line in move_lines:
balance += move_line.credit - move_line.debit
currency = statement_line.currency_for_rules()
if currency.is_zero(balance):
return self.browse()
rules = self.search([])
# return the first applicable rule
for rule in rules:
if rule.is_valid(statement_line, move_lines, balance):
return rule
return self.browse()
@api.model
@api.returns('account.operation.template')
def operations_for_reconciliation(self, statement_line_id, move_line_ids):
""" Find the rule for the current reconciliation and returns the
``account.operation.template`` of the found rule.
Called from the javascript reconciliation view.
"""
line_obj = self.env['account.bank.statement.line']
move_line_obj = self.env['account.move.line']
statement_line = line_obj.browse(statement_line_id)
move_lines = move_line_obj.browse(move_line_ids)
rules = self.find_first_rule(statement_line, move_lines)
return rules.operations

View File

@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, api
class AccountBankStatementLine(models.Model):
_inherit = 'account.bank.statement.line'
@api.multi
def currency_for_rules(self):
return self.currency_id or self.statement_id.currency_id

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_operation_rule,account.statement.operation.rule,model_account_operation_rule,account.group_account_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_operation_rule account.statement.operation.rule model_account_operation_rule account.group_account_user 1 1 1 1

View File

@@ -0,0 +1,62 @@
odoo.define('account_operation_rule', function (require) {
"use strict";
var core = require('web.core');
var Model = require('web.Model');
var reconciliation = require('account.reconciliation');
reconciliation.bankStatementReconciliationLine.include({
init: function(parent, context) {
this._super(parent, context);
this.preset_auto_clicked = false;
},
operation_rules: function () {
var self = this;
var model_operation_rule = new Model("account.operation.rule");
model_operation_rule.call("operations_for_reconciliation",
[self.st_line.id, _.pluck(self.get("mv_lines_selected"), 'id')]
).then(function (operations) {
_.each(operations, function (operation_id) {
var preset_btn = self.$("button.preset[data-presetid='" + operation_id + "']");
preset_btn.trigger('click');
// Cannot click on add_line link for user here
// even with a when().done()
// because preset_btn click handler makes a rpc call
// via formCreateInputChanged method
// and we have to wait for response
self.preset_auto_clicked = true;
});
});
},
/**
* Click on add_line link if preset button have been clicked
* automatically.
*/
formCreateInputChanged: function(elt, val) {
var self = this;
var deferred = this._super(elt, val);
deferred.done(function() {
if (self.preset_auto_clicked) {
self.addLineBeingEdited();
}
});
},
render: function () {
var deferred = this._super();
if (deferred) {
deferred.done(this.operation_rules());
}
return deferred;
},
restart: function () {
var deferred = this._super();
deferred.done(this.operation_rules());
return deferred;
}
});
});

View File

@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import test_journal
from . import test_rule_rounding
from . import test_rule_currency

View File

@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
class AccountOperationTestCase(TransactionCase):
def setUp(self):
super(AccountOperationTestCase, self).setUp()
self.cash_journal = self.env['account.journal'].create({
'name': 'Unittest Cash journal',
'code': 'CASH',
'type': 'cash',
})
self.sale_journal = self.env['account.journal'].create({
'name': 'Unittest Customer Invoices',
'code': 'INV',
'type': 'sale',
})
receivable_type = self.env['account.account.type'].create({
'name': 'Receivable',
'type': 'receivable'
})
self.account_receivable = self.env['account.account'].create({
'name': 'Unittest Account Receivable',
'user_type_id': receivable_type.id,
'code': 'TEST101200',
'reconcile': True,
})
income_type = self.env['account.account.type'].create({
'name': 'Unittest Income',
'type': 'other'
})
self.account_sale = self.env['account.account'].create({
'name': 'Unittest Account Sale',
'user_type_id': income_type.id,
'code': 'TEST200000',
'reconcile': False,
})
def prepare_statement(self, difference,
statement_line_currency=None,
move_line_currency=None,
amount_currency_difference=0):
""" Prepare a bank statement line and a move line
The difference is applied on the bank statement line relatively to
the move line.
"""
amount = 100
amount_currency = 120
statement = self.env['account.bank.statement'].create({
'name': '/',
'journal_id': self.cash_journal.id
})
line_vals = {
'name': '001',
'amount': amount + difference,
'statement_id': statement.id,
}
if statement_line_currency:
line_vals.update({
'currency_id': statement_line_currency.id,
'amount_currency':
amount_currency + amount_currency_difference,
})
statement_line = self.env['account.bank.statement.line'].create(
line_vals
)
debit_line_vals = {
'name': '001',
'account_id': self.account_receivable.id,
'debit': amount,
}
if move_line_currency:
debit_line_vals.update({
'currency_id': move_line_currency.id,
'amount_currency': amount_currency,
})
credit_line_vals = {
'name': '001',
'account_id': self.account_sale.id,
'credit': amount,
}
if move_line_currency:
credit_line_vals['currency_id'] = move_line_currency.id
move = self.env['account.move'].create({
'journal_id': self.sale_journal.id,
'line_ids': [(0, 0, debit_line_vals), (0, 0, credit_line_vals)],
})
return statement_line, move.line_ids.filtered(
lambda l: l.debit != 0.0
)

View File

@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# © 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
class TestJournal(TransactionCase):
def test_open_reconciliation_rules(self):
# Just test that method returned the good view
result = self.env['account.journal'].open_reconciliation_rules()
self.assertEqual('account.operation.rule', result['res_model'])
self.assertEqual('form', result['view_type'])

View File

@@ -0,0 +1,152 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .common import AccountOperationTestCase
class TestRuleCurrency(AccountOperationTestCase):
def setUp(self):
super(TestRuleCurrency, self).setUp()
self.operation_obj = self.env['account.operation.template']
self.rule_obj = self.env['account.operation.rule']
self.aed = self.browse_ref('base.AED')
self.aed.active = True
self.afn = self.browse_ref('base.AFN')
self.afn.active = True
self.all = self.browse_ref('base.ALL')
self.all.active = True
self.amd = self.browse_ref('base.AMD')
self.amd.active = True
self.aoa = self.browse_ref('base.AOA')
self.aoa.active = True
self.operation_currency_1 = self.operation_obj.create({
'name': 'Currency AED, AFR, ALL -1.0 to 0.0',
'label': 'Currency',
'account_id': self.account_receivable.id,
'amount_type': 'percentage',
'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',
'amount_type': 'percentage',
'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',
'amount_type': 'percentage',
'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 = self.prepare_statement(
-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 = self.prepare_statement(-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 = self.prepare_statement(
-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 = self.prepare_statement(
-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 = self.prepare_statement(
-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 = self.prepare_statement(
-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 = self.prepare_statement(
-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 = self.prepare_statement(
-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

@@ -0,0 +1,145 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .common import AccountOperationTestCase
class TestRuleRounding(AccountOperationTestCase):
def setUp(self):
super(TestRuleRounding, self).setUp()
self.operation_obj = self.env['account.operation.template']
self.rule_obj = self.env['account.operation.rule']
self.operation_round_1 = self.operation_obj.create({
'name': 'Rounding -1.0 to 0.0',
'label': 'Rounding',
'amount_type': 'percentage',
'amount': 100.0,
})
self.rule_round_1 = self.rule_obj.create({
'name': 'Rounding -1.0 to 0.0',
'rule_type': 'rounding',
'operations': [(6, 0, (self.operation_round_1.id, ))],
'amount_min': -1.0,
'amount_max': 0,
'sequence': 1,
})
self.operation_round_2 = self.operation_obj.create({
'name': 'Rounding -2.0 to -1.0',
'label': 'Rounding',
'amount_type': 'percentage',
'amount': 100.0,
})
self.rule_round_2 = self.rule_obj.create({
'name': 'Rounding -1.0 to 0.0',
'rule_type': 'rounding',
'operations': [(6, 0, (self.operation_round_2.id, ))],
'amount_min': -2.0,
'amount_max': -1.0,
'sequence': 2,
})
self.operation_round_3 = self.operation_obj.create({
'name': 'Rounding 0.0 to 2.0',
'label': 'Rounding',
'amount_type': 'percentage',
'amount': 100.0,
})
self.rule_round_3 = self.rule_obj.create({
'name': 'Rounding 0.0 to 2.0',
'rule_type': 'rounding',
'operations': [(6, 0, (self.operation_round_3.id, ))],
'amount_min': 0,
'amount_max': 2,
'sequence': 2,
})
def test_rule_round_1(self):
"""-0.5 => rule round 1"""
statement_line, move_line = self.prepare_statement(-0.5)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_round_1)
def test_rule_round_1_limit(self):
"""-1 => rule round 1"""
statement_line, move_line = self.prepare_statement(-1)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_round_1)
def test_rule_round_1_near_limit(self):
"""-1.0001 => rule round 1"""
statement_line, move_line = self.prepare_statement(-1.0001)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_round_1)
def test_rule_round_2(self):
"""-1.01 => rule round 2"""
statement_line, move_line = self.prepare_statement(-1.01)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_round_2)
def test_rule_round_2_limit(self):
"""-2 => rule round 2"""
statement_line, move_line = self.prepare_statement(-2)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_round_2)
def test_rule_round_3(self):
"""+1.5 => rule round 3"""
statement_line, move_line = self.prepare_statement(1.5)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_round_3)
def test_rule_round_3_limit(self):
"""+2 => rule round 3"""
statement_line, move_line = self.prepare_statement(2)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertEquals(rule, self.rule_round_3)
def test_rule_no_round_below(self):
"""-3 => no rule"""
statement_line, move_line = self.prepare_statement(-3)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertFalse(rule)
def test_rule_no_round_above(self):
"""+3 => no rule"""
statement_line, move_line = self.prepare_statement(3)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertFalse(rule)
def test_rule_no_round_zero(self):
"""0 => no rule"""
statement_line, move_line = self.prepare_statement(0)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertFalse(rule)
def test_rule_no_round_near_zero(self):
"""0.0001 => no rule"""
statement_line, move_line = self.prepare_statement(0.0001)
rule = self.rule_obj.find_first_rule(statement_line, [move_line])
self.assertFalse(rule)
def test_operations(self):
"""test operations_for_reconciliation()"""
statement_line, move_line = self.prepare_statement(-0.5)
ops = self.rule_obj.operations_for_reconciliation(statement_line.id,
move_line.ids)
self.assertEquals(ops, self.operation_round_1)
def test_multicurrency_lines(self):
"""No rounding rules on multi-currency lines"""
currency = self.browse_ref('base.AED')
statement_line, move_line = self.prepare_statement(
-0.5,
statement_line_currency=currency,
move_line_currency=currency
)
ops = self.rule_obj.operations_for_reconciliation(statement_line.id,
move_line.ids)
self.assertFalse(ops)

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="assets_backend" name="account assets" inherit_id="account.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/account_operation_rule/static/src/js/account_widgets.js"></script>
</xpath>
</template>
</data>
</openerp>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Account operation rule form view -->
<record id="view_account_operation_rule_form" model="ir.ui.view">
<field name="name">account.operation.rule.form</field>
<field name="model">account.operation.rule</field>
<field name="arch" type="xml">
<form string="Statement Operation Rule">
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name"/>
</h1>
</div>
<group name="options">
<field name="rule_type"/>
</group>
<group name="rule" string="Rule">
<group name="amount" attrs="{'invisible': [('rule_type', 'not in', ('rounding', 'currency'))]}">
<label for="amount" string="When the balance is between"/>
<div>
<field name="amount_min" class="oe_inline" /> And
<field name="amount_max" class="oe_inline" />
</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" string="Result">
<label for="operations" string="Then the following operations will be applied:" colspan="2"/>
<field name="operations" nolabel="1"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Account operation rule tree view -->
<record id="view_account_operation_rule_tree" model="ir.ui.view">
<field name="name">account.operation.rule.tree</field>
<field name="model">account.operation.rule</field>
<field name="arch" type="xml">
<tree string="Statement Operation Rules">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="rule_type"/>
<field name="amount_min"/>
<field name="amount_max"/>
<field name="operations"/>
</tree>
</field>
</record>
<!-- Account operation rule search view -->
<record id="view_account_operation_rule_search" model="ir.ui.view">
<field name="name">account.operation.rule.search</field>
<field name="model">account.operation.rule</field>
<field name="arch" type="xml">
<search string="Statement Operation Rules">
<field name="name"/>
<field name="rule_type"/>
<field name="amount_min"/>
<field name="amount_max"/>
<field name="operations"/>
</search>
</field>
</record>
<!-- Account operation rule action -->
<record id="action_account_operation_rule" model="ir.actions.act_window">
<field name="name">Reconciliation Rules</field>
<field name="res_model">account.operation.rule</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_account_operation_rule_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a reconciliation rule.
</p><p>
Those can be used to automatically create a move line when reconciling
your bank statements.
</p>
</field>
</record>
<!-- Add operation rule link in Bank card menu in Accounting Dashboard -->
<record id="account_journal_dashboard_kanban_view" model="ir.ui.view">
<field name="name">account.journal.dashboard.kanban.inherit</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view"/>
<field name="arch" type="xml">
<xpath expr="//a[contains(@context, 'action_account_operation_template')]/parent::div" position="after">
<div>
<a type="object" name="open_reconciliation_rules" groups="account.group_account_manager">
Reconciliation Rules
</a>
</div>
</xpath>
</field>
</record>
</odoo>