[MIG] account_operation_rule : Migration to 11.0 (account_reconcile_rule)

This commit is contained in:
Akim Juillerat
2018-04-23 11:22:05 +02:00
committed by OCA-git-bot
parent 2950d91d45
commit 683b94ec04
38 changed files with 241 additions and 586 deletions

View File

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

View File

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

@@ -1,182 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_operation_rule
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-06-30 02:44+0000\n"
"PO-Revision-Date: 2016-06-30 02:44+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.ui.view,arch_db:account_operation_rule.view_account_operation_rule_form
msgid "And"
msgstr "And"
#. module: account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_form
msgid "And the currency is one of"
msgstr "And the currency is one of"
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Bank Statement Line"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid "Click to create a reconciliation rule."
msgstr "Click to create a reconciliation rule."
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_create_uid
msgid "Created by"
msgstr "Created by"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_create_date
msgid "Created on"
msgstr "Created on"
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_currencies
msgid "Currencies"
msgstr "Currencies"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_display_name
msgid "Display Name"
msgstr "Display Name"
#. module: account_operation_rule
#: model:ir.model.fields,help:account_operation_rule.field_account_operation_rule_currencies
msgid ""
"For 'Currencies' rules, you can choose for which currencies the rule will be"
" applicable."
msgstr ""
"For 'Currencies' rules, you can choose for which currencies the rule will be"
" applicable."
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_id
msgid "ID"
msgstr "ID"
#. module: account_operation_rule
#: model:ir.model.fields,help:account_operation_rule.field_account_operation_rule_sequence
msgid "If several rules match, the first one is used."
msgstr "If several rules match, the first one is used."
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_journal
msgid "Journal"
msgstr "Journal"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule___last_update
msgid "Last Modified on"
msgstr "Last Modified on"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_write_uid
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_write_date
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_amount_max
msgid "Max. Amount"
msgstr "Max. Amount"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_amount_min
msgid "Min. Amount"
msgstr "Min. Amount"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_name
msgid "Name"
msgstr "Name"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_operations
msgid "Operations"
msgstr "Operations"
#. module: account_operation_rule
#: model:ir.actions.act_window,name:account_operation_rule.action_account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.account_journal_dashboard_kanban_view
msgid "Reconciliation Rules"
msgstr "Reconciliation Rules"
#. module: account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_form
msgid "Result"
msgstr "Result"
#. module: account_operation_rule
#: selection:account.operation.rule,rule_type:0
msgid "Roundings"
msgstr "Roundings"
#. module: account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_form
msgid "Rule"
msgstr "Rule"
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_sequence
msgid "Sequence"
msgstr "Sequence"
#. module: account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_form
msgid "Statement Operation Rule"
msgstr "Statement Operation Rule"
#. module: account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_search
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_tree
msgid "Statement Operation Rules"
msgstr "Statement Operation Rules"
#. module: account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_form
msgid "Then the following operations will be applied:"
msgstr "Then the following operations will be applied:"
#. module: account_operation_rule
#: model:ir.actions.act_window,help:account_operation_rule.action_account_operation_rule
msgid ""
"Those can be used to automatically create a move line when reconciling\n"
" your bank statements."
msgstr ""
"Those can be used to automatically create a move line when reconciling\n"
" your bank statements."
#. module: account_operation_rule
#: model:ir.model.fields,field_description:account_operation_rule.field_account_operation_rule_rule_type
msgid "Type"
msgstr "Type"
#. module: account_operation_rule
#: model:ir.ui.view,arch_db:account_operation_rule.view_account_operation_rule_form
msgid "When the balance is between"
msgstr "When the balance is between"
#. module: account_operation_rule
#: model:ir.model,name:account_operation_rule.model_account_operation_rule
msgid "account.operation.rule"
msgstr "account.operation.rule"

View File

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

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

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

@@ -1,14 +1,16 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
Bank Statement Operation Rules
==============================
=======================
Account Reconcile 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
will generate write-off entries according to pre-configured *Reconciliation
Models*. 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.
@@ -29,7 +31,7 @@ Configuration
-------------
As this module aims to automatize the ``Reconciliation Models``,
you first want to ensure that you have at least one operation configured.
you first want to ensure that you have at least one model configured.
You can find them in ``Invoicing > Dashboard > Bank card > More
> Reconciliation Models``. An example of a common operation is:
@@ -74,29 +76,42 @@ 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
:target: https://runbot.odoo-community.org/runbot/98/11.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/account-reconcile/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.
Contributors
------------
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
* Cyril Gaudin <cyril.gaudin@camptocamp.com>
* Akim Juillerat <akim.juillerat@camptocamp.com>
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
:target: https://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.
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.
To contribute to this module, please visit https://odoo-community.org.

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# Copyright 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',
{'name': 'Account Reconcile Rules',
'version': '11.0.1.0.0',
'author': 'Camptocamp, Odoo Community Association (OCA)',
'maintainer': 'Odoo Community Association (OCA)',
'license': 'AGPL-3',
@@ -13,12 +12,10 @@
'depends': [
'account',
],
'website': 'http://www.camptocamp.com',
'website': 'https://github.com/OCA/account-reconcile',
'data': [
'view/account_operation_rule.xml',
'view/account_operation_rule_view.xml',
'views/account_reconcile_rule.xml',
'views/account_reconcile_rule_view.xml',
'security/ir.model.access.csv',
],
'installable': False,
'auto_install': False,
}

View File

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

View File

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

View File

@@ -1,14 +1,13 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# Copyright 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
from odoo import models, fields, api
from odoo.addons import decimal_precision as dp
class AccountOperationRule(models.Model):
_name = 'account.operation.rule'
class AccountReconcileRule(models.Model):
_name = 'account.reconcile.rule'
_order = 'sequence ASC, id ASC'
@@ -20,8 +19,9 @@ class AccountOperationRule(models.Model):
default='rounding',
required=True,
)
operations = fields.Many2many(
comodel_name='account.operation.template',
reconcile_model_ids = fields.Many2many(
comodel_name='account.reconcile.model',
string='Reconciliation models',
)
amount_min = fields.Float(
string='Min. Amount',
@@ -31,7 +31,7 @@ class AccountOperationRule(models.Model):
string='Max. Amount',
digits=dp.get_precision('Account'),
)
currencies = fields.Many2many(
currency_ids = fields.Many2many(
comodel_name='res.currency',
string='Currencies',
help="For 'Currencies' rules, you can choose for which currencies "
@@ -44,7 +44,7 @@ class AccountOperationRule(models.Model):
@staticmethod
def _between_with_bounds(low, value, high, currency):
""" Equivalent to a three way comparison: ``min <= value <= high``
"""Equivalent to a three way comparison: ``min <= value <= high``
The comparisons are done with the currency to use the correct
precision.
@@ -57,10 +57,8 @@ class AccountOperationRule(models.Model):
@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)
return self._between_with_bounds(self.amount_min, balance,
self.amount_max, currency)
@api.model
def _is_multicurrency(self, statement_line):
@@ -77,7 +75,7 @@ class AccountOperationRule(models.Model):
@api.multi
def _is_valid_multicurrency(self, statement_line, move_lines, balance):
""" Check if the multi-currency rule can be applied
"""Check if the multi-currency rule can be applied.
The rule is applied if and only if:
* The currency is not company's one
@@ -88,7 +86,7 @@ class AccountOperationRule(models.Model):
if not self._is_multicurrency(statement_line):
return False
currency = statement_line.currency_for_rules()
if currency not in self.currencies:
if currency not in self.currency_ids:
return False
amount_currency = statement_line.amount_currency
for move_line in move_lines:
@@ -105,8 +103,7 @@ class AccountOperationRule(models.Model):
@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.
"""Check 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
@@ -130,8 +127,7 @@ class AccountOperationRule(models.Model):
@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.
"""Find rules to apply to given statement line and move lines.
:param statement_line: the line to reconcile
:param move_lines: the selected move lines for reconciliation
@@ -152,17 +148,18 @@ class AccountOperationRule(models.Model):
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.
@api.returns('account.reconcile.model')
def models_for_reconciliation(self, statement_line_id, move_line_ids):
"""Find the reconcile models for the for given statement and move lines.
Look for the first reconciliation rule to apply and return its
reconciliation models.
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
return rules.reconcile_model_ids

View File

@@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# Copyright 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, api
from odoo import models, api
class AccountBankStatementLine(models.Model):

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_reconcile_rule,account.statement.reconcile.rule,model_account_reconcile_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_reconcile_rule account.statement.reconcile.rule model_account_reconcile_rule account.group_account_user 1 1 1 1

View File

@@ -0,0 +1,50 @@
odoo.define('account_reconcile_rule', function (require) {
"use strict";
var core = require('web.core');
var reconciliation_renderer = require('account.ReconciliationRenderer');
/**
* Automatically apply reconciliation models according to the
* reconciliation rules matching the current statement line and move
* lines being reconciled.
*/
reconciliation_renderer.LineRenderer.include({
/**
* Get the reconciliation models to apply through RPC call and
* create the write off entries.
*/
reconciliation_rule_models: function() {
var self = this;
// Get the statement line
var line = this.model.getLine(this.handle)
// Call the models_for_reconciliation through RPC
this._rpc({
model: 'account.reconcile.rule',
method: 'models_for_reconciliation',
args: [
line.st_line.id,
_.pluck(line.reconciliation_proposition, 'id')
],
}).done(function(rule_models) {
// Loop on each models and create the corresponding write off
// entries
_.each(rule_models, function (rule_model_id) {
self.trigger_up('quick_create_proposition',
{'data': rule_model_id});
})
})
},
/*
* Add the write off entries after the the line renderer is ready
*/
start: function () {
var self = this;
var deferred = this._super();
if (deferred) {
deferred.done(this.reconciliation_rule_models());
}
return deferred;
},
});
});

View File

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

View File

@@ -1,45 +1,45 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# Copyright 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
from odoo.tests.common import SavepointCase
class AccountOperationTestCase(TransactionCase):
class AccountReconciliationModelTestCase(SavepointCase):
def setUp(self):
super(AccountOperationTestCase, self).setUp()
self.cash_journal = self.env['account.journal'].create({
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.reconcile_model_obj = cls.env['account.reconcile.model']
cls.rule_obj = cls.env['account.reconcile.rule']
cls.journal_obj = cls.env['account.journal']
cls.account_type_obj = cls.env['account.account.type']
cls.account_obj = cls.env['account.account']
cls.cash_journal = cls.journal_obj.create({
'name': 'Unittest Cash journal',
'code': 'CASH',
'type': 'cash',
})
self.sale_journal = self.env['account.journal'].create({
cls.sale_journal = cls.journal_obj.create({
'name': 'Unittest Customer Invoices',
'code': 'INV',
'type': 'sale',
})
receivable_type = self.env['account.account.type'].create({
receivable_type = cls.account_type_obj.create({
'name': 'Receivable',
'type': 'receivable'
})
self.account_receivable = self.env['account.account'].create({
cls.account_receivable = cls.account_obj.create({
'name': 'Unittest Account Receivable',
'user_type_id': receivable_type.id,
'code': 'TEST101200',
'reconcile': True,
})
income_type = self.env['account.account.type'].create({
income_type = cls.account_type_obj.create({
'name': 'Unittest Income',
'type': 'other'
})
self.account_sale = self.env['account.account'].create({
cls.account_sale = cls.account_obj.create({
'name': 'Unittest Account Sale',
'user_type_id': income_type.id,
'code': 'TEST200000',

View File

@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
# © 2016 Cyril Gaudin (Camptocamp)
# Copyright 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
from odoo.tests.common import TransactionCase
class TestJournal(TransactionCase):
@@ -11,5 +10,5 @@ class TestJournal(TransactionCase):
# 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('account.reconcile.rule', result['res_model'])
self.assertEqual('form', result['view_type'])

View File

@@ -1,76 +1,78 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# Copyright 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .common import AccountOperationTestCase
from .common import AccountReconciliationModelTestCase
class TestRuleCurrency(AccountOperationTestCase):
class TestRuleCurrency(AccountReconciliationModelTestCase):
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
@classmethod
def setUpClass(cls):
super().setUpClass()
self.operation_currency_1 = self.operation_obj.create({
cls.aed = cls.env.ref('base.AED')
cls.aed.active = True
cls.afn = cls.env.ref('base.AFN')
cls.afn.active = True
cls.all = cls.env.ref('base.ALL')
cls.all.active = True
cls.amd = cls.env.ref('base.AMD')
cls.amd.active = True
cls.aoa = cls.env.ref('base.AOA')
cls.aoa.active = True
cls.reconcile_model_currency_1 = cls.reconcile_model_obj.create({
'name': 'Currency AED, AFR, ALL -1.0 to 0.0',
'label': 'Currency',
'account_id': self.account_receivable.id,
'account_id': cls.account_receivable.id,
'amount_type': 'percentage',
'amount': 100.0,
})
self.rule_currency_1 = self.rule_obj.create({
cls.rule_currency_1 = cls.rule_obj.create({
'name': 'Currency AED, AFR, ALL -1.0 to 0.0',
'rule_type': 'currency',
'operations': [(6, 0, (self.operation_currency_1.id, ))],
'reconcile_model_ids': [
(6, 0, (cls.reconcile_model_currency_1.id,))],
'amount_min': -1.0,
'amount_max': 0,
'sequence': 1,
'currencies': [(6, 0, [self.aed.id, self.afn.id, self.all.id])],
'currency_ids': [(6, 0, [cls.aed.id, cls.afn.id, cls.all.id])],
})
self.operation_currency_2 = self.operation_obj.create({
cls.reconcile_model_currency_2 = cls.reconcile_model_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({
cls.rule_currency_2 = cls.rule_obj.create({
'name': 'Currency AED, AFR, ALL -2.0 to 1.0',
'rule_type': 'currency',
'operations': [(6, 0, (self.operation_currency_2.id, ))],
'reconcile_model_ids': [
(6, 0, (cls.reconcile_model_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])],
'currency_ids': [(6, 0, [cls.aed.id, cls.afn.id, cls.all.id])],
})
self.operation_currency_3 = self.operation_obj.create({
cls.reconcile_model_currency_3 = cls.reconcile_model_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({
cls.rule_currency_3 = cls.rule_obj.create({
'name': 'Currency AMD, AOA -2.0 to 0.0',
'rule_type': 'currency',
'operations': [(6, 0, (self.operation_currency_3.id, ))],
'reconcile_model_ids': [
(6, 0, (cls.reconcile_model_currency_3.id, ))],
'amount_min': -2,
'amount_max': 0,
'sequence': 2,
'currencies': [(6, 0, [self.amd.id, self.aoa.id])],
'currency_ids': [(6, 0, [cls.amd.id, cls.aoa.id])],
})
def test_no_currency_match(self):
@@ -80,15 +82,15 @@ class TestRuleCurrency(AccountOperationTestCase):
-0.5,
statement_line_currency=sek,
move_line_currency=sek)
ops = self.rule_obj.operations_for_reconciliation(statement_line.id,
move_line.ids)
ops = self.rule_obj.models_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)
ops = self.rule_obj.models_for_reconciliation(statement_line.id,
move_line.ids)
self.assertFalse(ops)
def test_currency_rule_1(self):
@@ -99,7 +101,7 @@ class TestRuleCurrency(AccountOperationTestCase):
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)
self.assertEqual(rule, self.rule_currency_1)
def test_currency_rule_2(self):
"""Rule 2 is found with -2 AED"""
@@ -109,7 +111,7 @@ class TestRuleCurrency(AccountOperationTestCase):
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)
self.assertEqual(rule, self.rule_currency_2)
def test_currency_rule_3(self):
"""Rule 3 is found with -2 AOA"""
@@ -119,7 +121,7 @@ class TestRuleCurrency(AccountOperationTestCase):
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)
self.assertEqual(rule, self.rule_currency_3)
def test_currency_rule_not_in_bounds(self):
"""No rule is found with -3 AOA"""
@@ -149,4 +151,4 @@ class TestRuleCurrency(AccountOperationTestCase):
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)
self.assertEqual(rule, self.rule_currency_1)

View File

@@ -1,59 +1,60 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# © 2014-2016 Camptocamp SA
# Copyright 2014-2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .common import AccountOperationTestCase
from .common import AccountReconciliationModelTestCase
class TestRuleRounding(AccountOperationTestCase):
class TestRuleRounding(AccountReconciliationModelTestCase):
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({
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.reconcile_model_round_1 = cls.reconcile_model_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({
cls.rule_round_1 = cls.rule_obj.create({
'name': 'Rounding -1.0 to 0.0',
'rule_type': 'rounding',
'operations': [(6, 0, (self.operation_round_1.id, ))],
'reconcile_model_ids': [
(6, 0, (cls.reconcile_model_round_1.id, ))],
'amount_min': -1.0,
'amount_max': 0,
'sequence': 1,
})
self.operation_round_2 = self.operation_obj.create({
cls.reconcile_model_round_2 = cls.reconcile_model_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({
cls.rule_round_2 = cls.rule_obj.create({
'name': 'Rounding -1.0 to 0.0',
'rule_type': 'rounding',
'operations': [(6, 0, (self.operation_round_2.id, ))],
'reconcile_model_ids': [
(6, 0, (cls.reconcile_model_round_2.id, ))],
'amount_min': -2.0,
'amount_max': -1.0,
'sequence': 2,
})
self.operation_round_3 = self.operation_obj.create({
cls.reconcile_model_round_3 = cls.reconcile_model_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({
cls.rule_round_3 = cls.rule_obj.create({
'name': 'Rounding 0.0 to 2.0',
'rule_type': 'rounding',
'operations': [(6, 0, (self.operation_round_3.id, ))],
'reconcile_model_ids': [
(6, 0, (cls.reconcile_model_round_3.id, ))],
'amount_min': 0,
'amount_max': 2,
'sequence': 2,
@@ -63,43 +64,43 @@ class TestRuleRounding(AccountOperationTestCase):
"""-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)
self.assertEqual(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)
self.assertEqual(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)
self.assertEqual(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)
self.assertEqual(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)
self.assertEqual(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)
self.assertEqual(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)
self.assertEqual(rule, self.rule_round_3)
def test_rule_no_round_below(self):
"""-3 => no rule"""
@@ -126,20 +127,20 @@ class TestRuleRounding(AccountOperationTestCase):
self.assertFalse(rule)
def test_operations(self):
"""test operations_for_reconciliation()"""
"""test models_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)
ops = self.rule_obj.models_for_reconciliation(statement_line.id,
move_line.ids)
self.assertEqual(ops, self.reconcile_model_round_1)
def test_multicurrency_lines(self):
"""No rounding rules on multi-currency lines"""
currency = self.browse_ref('base.AED')
currency = self.env.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)
ops = self.rule_obj.models_for_reconciliation(statement_line.id,
move_line.ids)
self.assertFalse(ops)

View File

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

View File

@@ -1,9 +1,9 @@
<?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>
<record id="view_account_reconcile_rule_form" model="ir.ui.view">
<field name="name">account.reconcile.rule.form</field>
<field name="model">account.reconcile.rule</field>
<field name="arch" type="xml">
<form string="Statement Operation Rule">
<sheet>
@@ -23,15 +23,15 @@
<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')]}"/>
<label for="currency_ids" 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"/>
<field name="currency_ids" 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 name="reconcile_model_ids" string="Result">
<label for="reconcile_model_ids" string="Then the following reconciliation models will be applied:" colspan="2"/>
<field name="reconcile_model_ids" nolabel="1"/>
</group>
</sheet>
</form>
@@ -39,9 +39,9 @@
</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>
<record id="view_account_reconcile_rule_tree" model="ir.ui.view">
<field name="name">account.reconcile.rule.tree</field>
<field name="model">account.reconcile.rule</field>
<field name="arch" type="xml">
<tree string="Statement Operation Rules">
<field name="sequence" widget="handle"/>
@@ -49,33 +49,33 @@
<field name="rule_type"/>
<field name="amount_min"/>
<field name="amount_max"/>
<field name="operations"/>
<field name="reconcile_model_ids"/>
</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>
<record id="view_account_reconcile_rule_search" model="ir.ui.view">
<field name="name">account.reconcile.rule.search</field>
<field name="model">account.reconcile.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"/>
<field name="reconcile_model_ids"/>
</search>
</field>
</record>
<!-- Account operation rule action -->
<record id="action_account_operation_rule" model="ir.actions.act_window">
<record id="action_account_reconcile_rule" model="ir.actions.act_window">
<field name="name">Reconciliation Rules</field>
<field name="res_model">account.operation.rule</field>
<field name="res_model">account.reconcile.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="search_view_id" ref="view_account_reconcile_rule_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a reconciliation rule.
@@ -92,7 +92,7 @@
<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">
<xpath expr="//a[contains(@context, 'action_account_reconcile_model')]/parent::div" position="after">
<div>
<a type="object" name="open_reconciliation_rules" groups="account.group_account_manager">
Reconciliation Rules