Browse Source

[ADD] allow the user to configure which fields are matched

pull/99/head
Holger Brunn 7 years ago
parent
commit
e034b2a580
No known key found for this signature in database GPG Key ID: 1C9760FECA3AE18
  1. 2
      account_bank_statement_import_auto_reconcile/README.rst
  2. 6
      account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml
  3. 35
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py
  4. 20
      account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py
  5. 12
      account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml

2
account_bank_statement_import_auto_reconcile/README.rst

@ -27,7 +27,7 @@ Reconciliation rules
Odoo standard 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 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 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 .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot

6
account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml

@ -4,6 +4,12 @@
<record id="rule_amount_exact" model="account.bank.statement.import.auto.reconcile.rule"> <record id="rule_amount_exact" model="account.bank.statement.import.auto.reconcile.rule">
<field name="journal_id" ref="account.bank_journal" /> <field name="journal_id" ref="account.bank_journal" />
<field name="rule_type">account.bank.statement.import.auto.reconcile.exact.amount</field> <field name="rule_type">account.bank.statement.import.auto.reconcile.exact.amount</field>
<field name="match_st_name" eval="True" />
<field name="match_st_ref" eval="True" />
<field name="match_move_name" eval="True" />
<field name="match_move_ref" eval="True" />
<field name="match_line_name" eval="True" />
<field name="match_line_ref" eval="True" />
</record> </record>
</data> </data>
</openerp> </openerp>

35
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) substring_match = fields.Boolean('Match for substrings', default=False)
case_sensitive = fields.Boolean('Case sensitive matching', 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 @api.multi
def reconcile(self, statement_line): def reconcile(self, statement_line):
@ -34,20 +40,35 @@ class AccountBankStatementImportAutoReconcileExactAmount(models.AbstractModel):
amount_field = 'credit' amount_field = 'credit'
sign = -1 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 = [ 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), ('reconcile_id', '=', False),
('state', '=', 'valid'), ('state', '=', 'valid'),
('account_id.reconcile', '=', True), ('account_id.reconcile', '=', True),
('partner_id', '=', statement_line.partner_id.id), ('partner_id', '=', statement_line.partner_id.id),
(amount_field, '=', self._round(sign * statement_line.amount)), (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) move_lines = self.env['account.move.line'].search(domain, limit=2)
if move_lines and len(move_lines) == 1: if move_lines and len(move_lines) == 1:
self._reconcile_move_line(statement_line, move_lines.id) self._reconcile_move_line(statement_line, move_lines.id)

20
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 self.original_parse_file = AccountBankStatementImport._parse_file
AccountBankStatementImport._parse_file = self._parse_file AccountBankStatementImport._parse_file = self._parse_file
self.invoice = self.env.ref('account.invoice_4') 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): def tearDown(self):
super(TestAccountBankStatementImportAutoReconcile, self).tearDown() super(TestAccountBankStatementImportAutoReconcile, self).tearDown()
@ -59,8 +62,23 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase):
self.env['account.bank.statement'].browse( self.env['account.bank.statement'].browse(
action['context']['statement_ids'] action['context']['statement_ids']
).unlink() ).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 # 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({ action = self.env['account.bank.statement.import'].create({
'data_file': base64.b64encode('hello world'), 'data_file': base64.b64encode('hello world'),
'journal_id': self.env.ref('account.bank_journal').id, 'journal_id': self.env.ref('account.bank_journal').id,

12
account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml

@ -5,7 +5,17 @@
<field name="model">account.bank.statement.import.auto.reconcile.exact.amount</field> <field name="model">account.bank.statement.import.auto.reconcile.exact.amount</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form> <form>
<group>
<group name="statement_fields" string="On the statement, match...">
<field name="match_st_ref" />
<field name="match_st_name" />
</group>
<group name="move_line_fields" string="... with the following fields">
<field name="match_move_ref" />
<field name="match_move_name" />
<field name="match_line_ref" />
<field name="match_line_name" />
</group>
<group name="options" string="Options">
<field name="substring_match" /> <field name="substring_match" />
<field name="case_sensitive" /> <field name="case_sensitive" />
</group> </group>

Loading…
Cancel
Save