Holger Brunn
8 years ago
No known key found for this signature in database
GPG Key ID: 1C9760FECA3AE18
15 changed files with 323 additions and 0 deletions
-
81account_bank_statement_import_auto_reconcile/README.rst
-
4account_bank_statement_import_auto_reconcile/__init__.py
-
21account_bank_statement_import_auto_reconcile/__openerp__.py
-
8account_bank_statement_import_auto_reconcile/models/__init__.py
-
43account_bank_statement_import_auto_reconcile/models/account_bank_statement_import.py
-
24account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py
-
31account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py
-
43account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py
-
15account_bank_statement_import_auto_reconcile/models/account_journal.py
-
3account_bank_statement_import_auto_reconcile/security/ir.model.access.csv
-
BINaccount_bank_statement_import_auto_reconcile/static/description/icon.png
-
4account_bank_statement_import_auto_reconcile/tests/__init__.py
-
9account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py
-
23account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_rule.xml
-
14account_bank_statement_import_auto_reconcile/views/account_journal.xml
@ -0,0 +1,81 @@ |
|||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
===================================== |
|||
Automatic reconciliation after import |
|||
===================================== |
|||
|
|||
This addon allows you have Odoo reconcile transactions from a bank statement import automatically in cases where the matching transaction can be determined unambigously. |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
To configure this module, you need to: |
|||
|
|||
#. go to the journal your bank account uses |
|||
#. in the field ``Automatic reconciliation rules``, add at least one rule |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
After a journal is configured for automatic reconciliations, it simply happens during an import on this journal. If there were automatic reconciliations, you'll see a notification about that and the lines in question will also show up as reconciled. |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/174/8.0 |
|||
|
|||
Background |
|||
========== |
|||
|
|||
Mainly, this module is a framework for conveniently (for programmers) adding new custom automatic reconciliation rules. To do this, study the provided AbstractModels. |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* add more matching rules: |
|||
* AmountDiffuse (let the user configure the threshold) |
|||
* SameCompany (if A from company C bought it, but B from the same company/organization pays) |
|||
* AmountTransposedDigits (reconcile if only two digits are swapped. Dangerous and a special case of AmountDiffuse) |
|||
* whatever else we can think of |
|||
* add some helpers/examples for using the options field |
|||
* allow to turn off automatic reconciliations during a specific import |
|||
* allow to fiddle with the parameters of configured rules during a specific import |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues |
|||
<https://github.com/OCA/bank-statement-import/issues>`_. In case of trouble, please |
|||
check there if your issue has already been reported. If you spotted it first, |
|||
help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Images |
|||
------ |
|||
|
|||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Holger Brunn <hbrunn@therp.nl> |
|||
|
|||
Do not contact contributors directly about help with questions or problems concerning this addon, but use the `community mailing list <mailto:community@mail.odoo.com>`_ or the `appropriate specialized mailinglist <https://odoo-community.org/groups>`_ for help, and the bug tracker linked in `Bug Tracker`_ above for technical issues. |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
: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. |
|||
|
|||
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,4 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from . import models |
@ -0,0 +1,21 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
{ |
|||
"name": "Automatic reconciliation after import", |
|||
"version": "8.0.1.0.0", |
|||
"author": "Therp BV,Odoo Community Association (OCA)", |
|||
"license": "AGPL-3", |
|||
"category": 'Banking addons', |
|||
"summary": "This module allows you to define automatic " |
|||
"reconciliation rules to be run after a bank statement is imported", |
|||
"depends": [ |
|||
'account_bank_statement_import', |
|||
'web_widget_one2many_tags', |
|||
], |
|||
"data": [ |
|||
"views/account_journal.xml", |
|||
"views/account_bank_statement_import_auto_reconcile_rule.xml", |
|||
'security/ir.model.access.csv', |
|||
], |
|||
} |
@ -0,0 +1,8 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from . import account_bank_statement_import_auto_reconcile |
|||
from . import account_bank_statement_import_auto_reconcile_rule |
|||
from . import account_journal |
|||
from . import account_bank_statement_import_auto_reconcile_exact_amount |
|||
from . import account_bank_statement_import |
@ -0,0 +1,43 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp import _, api, models |
|||
|
|||
|
|||
class AccountBankStatementImport(models.TransientModel): |
|||
_inherit = 'account.bank.statement.import' |
|||
|
|||
@api.model |
|||
def _create_bank_statement(self, stmt_vals): |
|||
statement_id, notifications = super( |
|||
AccountBankStatementImport, self |
|||
)._create_bank_statement(stmt_vals) |
|||
if not statement_id: |
|||
return statement_id, notifications |
|||
statement = self.env['account.bank.statement'].browse(statement_id) |
|||
reconcile_rules = statement.journal_id\ |
|||
.statement_import_auto_reconcile_rule_ids.mapped( |
|||
lambda x: self.env[x.rule_type].new({ |
|||
'wizard_id': self.id, |
|||
'options': x.options |
|||
}) |
|||
) |
|||
auto_reconciled_ids = [] |
|||
for line in statement.line_ids: |
|||
for rule in reconcile_rules: |
|||
if rule.reconcile(line): |
|||
auto_reconciled_ids.append(line.id) |
|||
break |
|||
if auto_reconciled_ids: |
|||
notifications.append({ |
|||
'type': 'warning', |
|||
'message': |
|||
_("%d transactions were reconciled automatically.") % |
|||
len(auto_reconciled_ids), |
|||
'details': { |
|||
'name': _('Automatically reconciled'), |
|||
'model': 'account.bank.statement.line', |
|||
'ids': auto_reconciled_ids, |
|||
}, |
|||
}) |
|||
return statement_id, notifications |
@ -0,0 +1,24 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp import api, fields, models |
|||
|
|||
|
|||
class AccountBankStatementImportAutoReconcile(models.AbstractModel): |
|||
"""Inherit from this class and implement the reconcile function""" |
|||
|
|||
_name = 'account.bank.statement.import.auto.reconcile' |
|||
_description = 'Base class for automatic reconciliation rules' |
|||
|
|||
wizard_id = fields.Many2one('account.bank.statement.import', required=True) |
|||
# this is meant as a field to save options in and/or to carry state |
|||
# between different reconciliations |
|||
options = fields.Serialized('Options') |
|||
|
|||
@api.multi |
|||
def reconcile(self, statement_line): |
|||
"""Will be called on your model, with wizard_id pointing |
|||
to the currently open statement import wizard. If your rule consumes |
|||
any options or similar, get the values from there. |
|||
Return True if you reconciled this line, something Falsy otherwise""" |
|||
raise NotImplementedError() |
@ -0,0 +1,31 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp import api, models |
|||
from openerp.tools import float_compare |
|||
|
|||
|
|||
class AccountBankStatementImportAutoReconcileExactAmount(models.AbstractModel): |
|||
_inherit = 'account.bank.statement.import.auto.reconcile' |
|||
_name = 'account.bank.statement.import.auto.reconcile.exact.amount' |
|||
_description = 'Exact match on amount' |
|||
|
|||
@api.multi |
|||
def reconcile(self, statement_line): |
|||
"""Find an open invoice for the statement line's partner""" |
|||
# TODO: this is the lazy version, searching a bit more specialized |
|||
# and with some caching should speed this up a lot |
|||
matches = statement_line.get_reconciliation_proposition(statement_line) |
|||
digits = self.env['decimal.precision'].precision_get('Account') |
|||
if len(matches) == 1 and ( |
|||
float_compare( |
|||
matches[0]['debit'], statement_line.amount, |
|||
precision_digits=digits |
|||
) == 0 or |
|||
float_compare( |
|||
-matches[0]['credit'], statement_line.amount, |
|||
precision_digits=digits |
|||
) == 0 |
|||
): |
|||
statement_line.process_reconciliation(matches) |
|||
return True |
@ -0,0 +1,43 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp import _, api, exceptions, fields, models |
|||
from .account_bank_statement_import_auto_reconcile import\ |
|||
AccountBankStatementImportAutoReconcile as auto_reconcile_base |
|||
|
|||
|
|||
class AccountBankStatementImportAutoReconcileRule(models.Model): |
|||
_name = 'account.bank.statement.import.auto.reconcile.rule' |
|||
_description = 'Automatic reconciliation rule' |
|||
|
|||
rule_type = fields.Selection('_sel_rule_type', required=True) |
|||
journal_id = fields.Many2one('account.journal', 'Journal', required=True) |
|||
options = fields.Serialized('Options') |
|||
|
|||
@api.model |
|||
def _sel_rule_type(self): |
|||
model_names = [ |
|||
model for model in self.env.registry |
|||
if self.env[model]._name != auto_reconcile_base._name and |
|||
issubclass(self.env[model].__class__, auto_reconcile_base) |
|||
] |
|||
return self.env['ir.model'].search([ |
|||
('model', 'in', model_names), |
|||
]).mapped(lambda x: (x.model, x.name)) |
|||
|
|||
@api.constrains('rule_type') |
|||
def _check_rule_type(self): |
|||
for this in self: |
|||
if this.mapped( |
|||
'journal_id.statement_import_auto_reconcile_rule_ids' |
|||
).filtered(lambda x: x != this and x.rule_type == this.rule_type): |
|||
raise exceptions.ValidationError( |
|||
_('Reconciliation rules must be unique per journal') |
|||
) |
|||
|
|||
@api.multi |
|||
def name_get(self): |
|||
return [ |
|||
(this.id, self.env[this.rule_type]._description) |
|||
for this in self |
|||
] |
@ -0,0 +1,15 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp import fields, models |
|||
|
|||
|
|||
class AccountJournal(models.Model): |
|||
_inherit = 'account.journal' |
|||
|
|||
statement_import_auto_reconcile_rule_ids = fields.One2many( |
|||
'account.bank.statement.import.auto.reconcile.rule', |
|||
'journal_id', string='Automatic reconciliation rules', |
|||
help='When importing a bank statement into this journal ,' |
|||
'apply the following rules for automatic reconciliation', |
|||
) |
@ -0,0 +1,3 @@ |
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
|||
account_bank_statement_import_auto_reconcile_rule,account.bank.statement.import.auto.reconcile.rule manager,model_account_bank_statement_import_auto_reconcile_rule,account.group_account_user,1,0,0,0 |
|||
account_bank_statement_import_auto_reconcile_rule_manager,account.bank.statement.import.auto.reconcile.rule manager,model_account_bank_statement_import_auto_reconcile_rule,account.group_account_manager,1,1,1,1 |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,4 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from . import test_account_bank_statement_import_auto_reconcile |
@ -0,0 +1,9 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp.tests.common import TransactionCase |
|||
|
|||
|
|||
class TestAccountBankStatementImportAutoReconcile(TransactionCase): |
|||
def test_account_bank_statement_import_auto_reconcile(self): |
|||
pass |
@ -0,0 +1,23 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record id="account_bank_statement_import_auto_reconcile_rule_form" model="ir.ui.view"> |
|||
<field name="model">account.bank.statement.import.auto.reconcile.rule</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group> |
|||
<field name="rule_type" /> |
|||
</group> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<record id="account_bank_statement_import_auto_reconcile_rule_tree" model="ir.ui.view"> |
|||
<field name="model">account.bank.statement.import.auto.reconcile.rule</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="display_name" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -0,0 +1,14 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record id="view_account_journal_form" model="ir.ui.view"> |
|||
<field name="model">account.journal</field> |
|||
<field name="inherit_id" ref="account.view_account_journal_form" /> |
|||
<field name="arch" type="xml"> |
|||
<field name="default_credit_account_id" position="after"> |
|||
<field name="statement_import_auto_reconcile_rule_ids" widget="one2many_tags" /> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue