From d709d566b7da4688579409394e6a1059d2bab636 Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Tue, 28 Nov 2017 17:35:06 +0100 Subject: [PATCH] [ADD] allow the user to configure which fields are matched --- .../README.rst | 2 +- ...k_statement_import_auto_reconcile_rule.xml | 6 ++++ ...ment_import_auto_reconcile_exact_amount.py | 35 +++++++++++++++---- ...nt_bank_statement_import_auto_reconcile.py | 20 ++++++++++- ...ent_import_auto_reconcile_exact_amount.xml | 12 ++++++- 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/account_bank_statement_import_auto_reconcile/README.rst b/account_bank_statement_import_auto_reconcile/README.rst index 5fc0d67..95870a0 100644 --- a/account_bank_statement_import_auto_reconcile/README.rst +++ b/account_bank_statement_import_auto_reconcile/README.rst @@ -27,7 +27,7 @@ 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 + Strictly only match if we have the same partner, amount and reference. Check at least one field one the statement and one field on the move lines to tell the rule which fields to match with each other. .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot diff --git a/account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml b/account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml index fbe6e72..a0ff38e 100644 --- a/account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml +++ b/account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml @@ -4,6 +4,12 @@ account.bank.statement.import.auto.reconcile.exact.amount + + + + + + diff --git a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py index c56dfb3..2458531 100644 --- a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py +++ b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py @@ -12,6 +12,12 @@ class AccountBankStatementImportAutoReconcileExactAmount(models.AbstractModel): substring_match = fields.Boolean('Match for substrings', default=False) case_sensitive = fields.Boolean('Case sensitive matching', default=False) + match_st_ref = fields.Boolean('Reference from st. line', default=True) + match_st_name = fields.Boolean('Name from st. line', default=True) + match_move_ref = fields.Boolean('Move reference', default=True) + match_move_name = fields.Boolean('Move name', default=True) + match_line_ref = fields.Boolean('Move line reference', default=True) + match_line_name = fields.Boolean('Move line name', default=True) @api.multi def reconcile(self, statement_line): @@ -34,20 +40,35 @@ class AccountBankStatementImportAutoReconcileExactAmount(models.AbstractModel): amount_field = 'credit' sign = -1 + statement_fields = filter(None, [ + self.match_st_name and 'name' or None, + self.match_st_ref and 'ref' or None, + ]) + + move_line_fields = filter(None, [ + self.match_move_ref and 'move_id.ref' or None, + self.match_move_name and 'move_id.name' or None, + self.match_line_ref and 'ref' or None, + self.match_line_name and 'name' or None, + ]) + domain = [ - '|', '|', '|', '|', '|', - ('move_id.ref', operator, statement_line.ref or ''), - ('move_id.name', operator, statement_line.name or ''), - ('ref', operator, statement_line.ref or ''), - ('name', operator, statement_line.name or ''), - ('ref', operator, statement_line.name or ''), - ('name', operator, statement_line.ref or ''), ('reconcile_id', '=', False), ('state', '=', 'valid'), ('account_id.reconcile', '=', True), ('partner_id', '=', statement_line.partner_id.id), (amount_field, '=', self._round(sign * statement_line.amount)), ] + + domain += ( + len(statement_fields) * len(move_line_fields) - 1 + ) * ['|'] + + for move_line_field in move_line_fields: + for statement_field in statement_fields: + value = statement_line[statement_field] + domain.append((move_line_field, operator, value)) + move_lines = self.env['account.move.line'].search(domain, limit=2) if move_lines and len(move_lines) == 1: self._reconcile_move_line(statement_line, move_lines.id) diff --git a/account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py b/account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py index 52dde53..06994d8 100644 --- a/account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py +++ b/account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py @@ -17,6 +17,9 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase): self.original_parse_file = AccountBankStatementImport._parse_file AccountBankStatementImport._parse_file = self._parse_file self.invoice = self.env.ref('account.invoice_4') + self.rule = self.env.ref( + 'account_bank_statement_import_auto_reconcile.rule_amount_exact' + ) def tearDown(self): super(TestAccountBankStatementImportAutoReconcile, self).tearDown() @@ -59,8 +62,23 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase): self.env['account.bank.statement'].browse( action['context']['statement_ids'] ).unlink() + # now we do matching, but manipulate the matching to work on the + # ref field only which is empty in our example + self.rule.write({'match_st_name': False}) + action = self.env['account.bank.statement.import'].create({ + 'data_file': base64.b64encode('hello world'), + 'journal_id': self.env.ref('account.bank_journal').id, + 'auto_reconcile': True, + }).import_file() + # nothing should have happened + self.assertEqual(self.invoice.state, 'open') + self.env['account.bank.statement'].browse( + action['context']['statement_ids'] + ).unlink() # for exact amount matching, our first transaction should be matched - # to the invoice's move line, marking the invoice as paid + # to the invoice's move line, marking the invoice as paid, + # provided we allow matching by name + self.rule.write({'match_st_name': True}) action = self.env['account.bank.statement.import'].create({ 'data_file': base64.b64encode('hello world'), 'journal_id': self.env.ref('account.bank_journal').id, diff --git a/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml index a5260fe..e32bb14 100644 --- a/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml +++ b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml @@ -5,7 +5,17 @@ account.bank.statement.import.auto.reconcile.exact.amount
- + + + + + + + + + + +