Browse Source

[ADD] operator to match for an exact amount, reference and partner

pull/204/head
Holger Brunn 8 years ago
parent
commit
3dd2158546
No known key found for this signature in database GPG Key ID: 1C9760FECA3AE18
  1. 8
      account_bank_statement_import_auto_reconcile/README.rst
  2. 1
      account_bank_statement_import_auto_reconcile/__openerp__.py
  3. 3
      account_bank_statement_import_auto_reconcile/models/__init__.py
  4. 50
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py
  5. 71
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py
  6. 20
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_odoo.py

8
account_bank_statement_import_auto_reconcile/README.rst

@ -21,6 +21,14 @@ 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. 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.
Reconciliation rules
--------------------
Odoo standard
Do exactly what Odoo does when proposing reconciliations. This searches for an exact match on amount and reference first, but falls back to less exact matches if none are found before. If there's only one match, do the reconciliation
Exact amount and reference
Strictly only match if we have the same partner, amount and reference
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/174/8.0 :target: https://runbot.odoo-community.org/runbot/174/8.0

1
account_bank_statement_import_auto_reconcile/__openerp__.py

@ -12,6 +12,7 @@
"depends": [ "depends": [
'account_bank_statement_import', 'account_bank_statement_import',
'web_widget_one2many_tags', 'web_widget_one2many_tags',
'base_domain_operator',
], ],
"demo": [ "demo": [
"demo/account_bank_statement_import_auto_reconcile_rule.xml", "demo/account_bank_statement_import_auto_reconcile_rule.xml",

3
account_bank_statement_import_auto_reconcile/models/__init__.py

@ -4,5 +4,6 @@
from . import account_bank_statement_import_auto_reconcile from . import account_bank_statement_import_auto_reconcile
from . import account_bank_statement_import_auto_reconcile_rule from . import account_bank_statement_import_auto_reconcile_rule
from . import account_journal from . import account_journal
from . import account_bank_statement_import_auto_reconcile_exact_amount
from . import account_bank_statement_import_auto_reconcile_odoo
from . import account_bank_statement_import from . import account_bank_statement_import
from . import account_bank_statement_import_auto_reconcile_exact_amount

50
account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2017 Therp BV <http://therp.nl> # © 2017 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tools import float_compare, float_round
from openerp import api, fields, models from openerp import api, fields, models
@ -15,6 +16,55 @@ class AccountBankStatementImportAutoReconcile(models.AbstractModel):
# between different reconciliations # between different reconciliations
options = fields.Serialized('Options') options = fields.Serialized('Options')
@property
def _digits(self):
try:
return self.__digits
except:
self.__digits = self.env['decimal.precision'].precision_get(
'Account'
)
return self.__digits
@api.model
def _round(self, value):
return float_round(value, precision_digits=self._digits)
@api.model
def _matches_amount(self, statement_line, debit, credit):
"""helper to compare if an amount matches some move line data"""
return (
float_compare(
debit, statement_line.amount,
precision_digits=self._digits
) == 0 or
float_compare(
-credit, statement_line.amount,
precision_digits=self._digits
) == 0
)
@api.model
def _reconcile_move_line(self, statement_line, move_line_id):
"""Helper to reconcile some move line with a bank statement.
This will create a move to reconcile with and assigns journal_entry_id
"""
move = self.env['account.move'].create(
self.env['account.bank.statement']._prepare_move(
statement_line,
(
statement_line.statement_id.name or statement_line.name
) + "/" + str(statement_line.sequence or '')
)
)
move_line_dict = self.env['account.bank.statement']\
._prepare_bank_move_line(
statement_line, move.id, -statement_line.amount,
statement_line.statement_id.company_id.currency_id.id,
)
move_line_dict['counterpart_move_line_id'] = move_line_id
statement_line.process_reconciliation([move_line_dict])
@api.multi @api.multi
def reconcile(self, statement_line): def reconcile(self, statement_line):
"""Will be called on your model, with wizard_id pointing """Will be called on your model, with wizard_id pointing

71
account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py

@ -1,45 +1,52 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2017 Therp BV <http://therp.nl> # © 2017 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, models
from openerp.tools import float_compare
from openerp import api, fields, models
class AccountBankStatementImportAutoReconcileExactAmount(models.AbstractModel): class AccountBankStatementImportAutoReconcileExactAmount(models.AbstractModel):
_inherit = 'account.bank.statement.import.auto.reconcile' _inherit = 'account.bank.statement.import.auto.reconcile'
_name = 'account.bank.statement.import.auto.reconcile.exact.amount' _name = 'account.bank.statement.import.auto.reconcile.exact.amount'
_description = 'Exact match on amount'
_description = 'Exact partner, amount and reference'
substring_match = fields.Boolean('Match for substrings', default=False)
case_sensitive = fields.Boolean('Case sensitive matching', default=False)
@api.multi @api.multi
def reconcile(self, statement_line): 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
if not statement_line.partner_id or (
not statement_line.ref and not statement_line.name
): ):
move = self.env['account.move'].create(
self.env['account.bank.statement']._prepare_move(
statement_line,
(
statement_line.statement_id.name or statement_line.name
) + "/" + str(statement_line.sequence or '')
)
)
move_line_dict = self.env['account.bank.statement']\
._prepare_bank_move_line(
statement_line, move.id, -statement_line.amount,
statement_line.statement_id.company_id.currency_id.id,
)
move_line_dict['counterpart_move_line_id'] = matches[0]['id']
statement_line.process_reconciliation([move_line_dict])
return
operator = '=ilike'
if self.substring_match:
operator = 'substring_of'
elif self.case_sensitive:
operator = '=like'
amount_field = 'debit'
sign = 1
if statement_line.currency_id or statement_line.journal_id.currency:
if statement_line.amount < 0:
amount_field = 'credit'
sign = -1
else:
amount_field = 'amount_currency'
domain = [
'|', '|', '|',
('ref', operator, statement_line.ref),
('name', operator, statement_line.name),
('ref', operator, statement_line.name),
('name', operator, statement_line.ref),
('reconcile_id', '=', False),
('state', '=', 'valid'),
('account_id.reconcile', '=', True),
('partner_id', '=', statement_line.partner_id.id),
(amount_field, '=', self._round(sign * statement_line.amount)),
]
move_lines = self.env['account.move.line'].search(domain, limit=1)
if move_lines:
self._reconcile_move_line(statement_line, move_lines.id)
return True return True

20
account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_odoo.py

@ -0,0 +1,20 @@
# -*- 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 AccountBankStatementImportAutoReconcileOdoo(models.AbstractModel):
_inherit = 'account.bank.statement.import.auto.reconcile'
_name = 'account.bank.statement.import.auto.reconcile.odoo'
_description = 'Odoo standard'
@api.multi
def reconcile(self, statement_line):
"""Find an open invoice for the statement line's partner"""
matches = statement_line.get_reconciliation_proposition(statement_line)
if len(matches) == 1 and self._matches_amount(
statement_line, matches[0]['debit'], -matches[0]['credit'],
):
self._reconcile_move_line(statement_line, matches[0]['id'])
return True
Loading…
Cancel
Save