diff --git a/account_bank_statement_import_auto_reconcile/__manifest__.py b/account_bank_statement_import_auto_reconcile/__manifest__.py
index 7d8a7bf..b16a3f6 100644
--- a/account_bank_statement_import_auto_reconcile/__manifest__.py
+++ b/account_bank_statement_import_auto_reconcile/__manifest__.py
@@ -13,9 +13,6 @@
'account_bank_statement_import',
'base_domain_operator',
],
- "demo": [
- "demo/account_bank_statement_import_auto_reconcile_rule.xml",
- ],
"data": [
"views/account_bank_statement_import_reapply_rules.xml",
"views/account_bank_statement.xml",
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
deleted file mode 100644
index 46c7976..0000000
--- a/account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- account.bank.statement.import.auto.reconcile.exact.amount
-
-
-
-
-
-
-
-
diff --git a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import.py b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import.py
index eb63cb1..6dca184 100644
--- a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import.py
+++ b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import.py
@@ -19,8 +19,8 @@ class AccountBankStatementImport(models.TransientModel):
return statement_ids, notifications
statements = self.env['account.bank.statement'].browse(statement_ids)
for statement in statements.filtered(
- lambda x: x.journal_id.
- statement_import_auto_reconcile_rule_ids):
+ 'journal_id.statement_import_auto_reconcile_rule_ids'
+ ):
reconcile_rules = statement.journal_id\
.statement_import_auto_reconcile_rule_ids.get_rules()
auto_reconciled_ids = []
diff --git a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py
index e4a536d..7caf137 100644
--- a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py
+++ b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py
@@ -20,7 +20,7 @@ class AccountBankStatementImportAutoReconcile(models.AbstractModel):
def _digits(self):
try:
return self.__digits
- except:
+ except AttributeError:
self.__digits = self.env['decimal.precision'].precision_get(
'Account'
)
@@ -52,16 +52,13 @@ class AccountBankStatementImportAutoReconcile(models.AbstractModel):
:param statement_line: The account.bank.statement.line to reconcile.
:param move_line_id: The id of the account.move.line to reconcile.
"""
- acc_move_line = self.env['account.move.line']
- acc_move = self.env['account.move']
- move = acc_move.create(statement_line._prepare_reconciliation_move(
- statement_line.ref))
- move_line_dict = statement_line._prepare_reconciliation_move_line(
- move,
- -acc_move_line.browse(move_line_id).balance,
- )
- move_line = acc_move_line.with_context(
- check_move_validity=False).create(move_line_dict)
+ move_line = self.env['account.move.line'].browse(move_line_id)
+ return statement_line.process_reconciliation(counterpart_aml_dicts=[{
+ 'name': statement_line.name,
+ 'debit': move_line.credit,
+ 'credit': move_line.debit,
+ 'move_line': move_line,
+ }])
@api.multi
def reconcile(self, statement_line):
diff --git a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py
index 7ff3ebf..3ba03af 100644
--- a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py
+++ b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py
@@ -11,6 +11,7 @@ class AccountBankStatementImportAutoReconcileRule(models.Model):
_name = 'account.bank.statement.import.auto.reconcile.rule'
_description = 'Automatic reconciliation rule'
+ display_name = fields.Char(string='Rule')
rule_type = fields.Selection('_sel_rule_type', required=True)
journal_id = fields.Many2one('account.journal', 'Journal', required=True)
options = fields.Serialized('Options')
diff --git a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_reapply_rules.py b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_reapply_rules.py
index fc410f6..7e46a94 100644
--- a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_reapply_rules.py
+++ b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_reapply_rules.py
@@ -23,13 +23,12 @@ class AccountBankStatementImportReapplyRules(models.TransientModel):
'journal!'
))
- self.write({'journal_id': journal.id})
reconcile_rules = journal.statement_import_auto_reconcile_rule_ids\
.get_rules()
for line in self.env['account.bank.statement.line'].search([
('statement_id', 'in', statements.ids),
- ('journal_entry_id', '=', False),
+ ('journal_entry_ids', '=', False),
]):
for rule in reconcile_rules:
if rule.reconcile(line):
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 d04cd84..9706e48 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
@@ -4,35 +4,43 @@
import base64
from datetime import timedelta
from odoo import fields
-from odoo.tests.common import TransactionCase
+from odoo.addons.account.tests.account_test_classes import AccountingTestCase
from odoo.addons.account_bank_statement_import\
.account_bank_statement_import import AccountBankStatementImport
-class TestAccountBankStatementImportAutoReconcile(TransactionCase):
-
- post_install = True
- at_install = False
-
+class TestAccountBankStatementImportAutoReconcile(AccountingTestCase):
def setUp(self):
super(TestAccountBankStatementImportAutoReconcile, self).setUp()
# we don't really have something to import, so we patch the
# import routine to return what we want for our tests
self.original_parse_file = AccountBankStatementImport._parse_file
AccountBankStatementImport._parse_file = self._parse_file
- invoice_account = self.env['account.account'].search([
- ('user_type_id', '=', self.env.ref(
- 'account.data_account_type_receivable').id)],
- limit=1,
- )
+ self.bank_account = self.env['res.partner.bank'].create({
+ 'acc_number': '42424242',
+ 'partner_id': self.env.ref('base.main_partner').id,
+ })
+ partner = self.env.ref('base.res_partner_2')
self.invoice = self.env['account.invoice'].create({
- 'partner_id': self.env.ref('base.res_partner_2').id,
- 'account_id': invoice_account.id,
- 'type': 'in_invoice',
+ 'partner_id': partner.id,
+ 'account_id': partner.property_account_receivable_id.id,
+ 'type': 'out_invoice',
+ })
+ self.invoice.with_context(
+ journal_id=self.invoice.journal_id.id
+ ).write({
+ 'invoice_line_ids': [(0, 0, {
+ 'name': '/',
+ 'price_unit': 42,
+ })],
+ })
+ self.invoice.action_invoice_open()
+ self.journal = self.env['account.journal'].create({
+ 'name': 'Journal for automatic reconciliations',
+ 'code': 'BNKAU',
+ 'type': 'bank',
+ 'bank_account_id': self.bank_account.id,
})
- self.rule = self.env.ref(
- 'account_bank_statement_import_auto_reconcile.rule_amount_exact'
- )
def tearDown(self):
super(TestAccountBankStatementImportAutoReconcile, self).tearDown()
@@ -40,34 +48,58 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase):
def _parse_file(self, data):
date = self.invoice.date_invoice
- return [
- {
- 'currency_code': self.invoice.company_id.currency_id.name,
- 'account_number': False,
+ return (
+ self.invoice.company_id.currency_id.name,
+ self.bank_account.acc_number,
+ [{
'name': 'Auto reconcile test',
'date': fields.Date.to_string(
fields.Date.from_string(date) + timedelta(days=5)
),
- 'transactions': [
- {
- 'name': self.invoice.number,
- 'date': fields.Date.to_string(
- fields.Date.from_string(date) + timedelta(days=5)
- ),
- 'amount': self.invoice.residual,
- 'unique_import_id': '42',
- 'account_number':
- self.invoice.partner_id.bank_ids[:1].acc_number,
- },
- ],
- },
- ]
+ 'transactions': [{
+ 'name': self.invoice.number,
+ 'date': fields.Date.to_string(
+ fields.Date.from_string(date) + timedelta(days=5)
+ ),
+ 'amount': self.invoice.residual,
+ 'unique_import_id': '42',
+ 'account_number':
+ self.invoice.partner_id.bank_ids[:1].acc_number,
+ }],
+ }],
+ )
- def test_account_bank_statement_import_auto_reconcile(self):
+ def test_account_bank_statement_import_auto_reconcile_odoo(self):
+ self.env[
+ 'account.bank.statement.import.auto.reconcile.rule'
+ ].create({
+ 'journal_id': self.journal.id,
+ 'rule_type': 'account.bank.statement.import.auto.reconcile.odoo',
+ })
+ self.env['account.bank.statement.import'].create({
+ 'data_file': base64.b64encode('hello world'),
+ 'auto_reconcile': True,
+ }).import_file()
+ # should find our move line
+ self.assertEqual(self.invoice.state, 'paid')
+
+ def test_account_bank_statement_import_auto_reconcile_exact_amount(self):
+ rule = self.env[
+ 'account.bank.statement.import.auto.reconcile.rule'
+ ].create({
+ 'journal_id': self.journal.id,
+ 'rule_type':
+ 'account.bank.statement.import.auto.reconcile.exact.amount',
+ 'match_st_name': True,
+ 'match_st_ref': True,
+ 'match_move_name': True,
+ 'match_move_ref': True,
+ 'match_line_name': True,
+ 'match_line_ref': True,
+ })
# first, we do an import with auto reconciliation turned off
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': False,
}).import_file()
# nothing should have happened
@@ -77,10 +109,9 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase):
).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})
+ 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
@@ -91,24 +122,45 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase):
# for exact amount matching, our first transaction should be matched
# to the invoice's move line, marking the invoice as paid,
# provided we allow matching by name
- self.rule.write({'match_st_name': True})
+ 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,
'auto_reconcile': True,
}).import_file()
+ # with the changed rules, we should have found a match
+ self.assertEqual(self.invoice.state, 'paid')
+ # undo reconciliations, reapply rules on the statement
+ statement = self.env['account.bank.statement'].browse(
+ action['context']['statement_ids']
+ )
+ statement.mapped(
+ 'line_ids.journal_entry_ids.line_ids'
+ ).remove_move_reconcile()
+ self.assertEqual(self.invoice.state, 'open')
+ statement.mapped('line_ids.journal_entry_ids').write({
+ 'statement_line_id': False,
+ })
+ # fiddle a bit with the options
+ rule.write({'case_sensitive': True})
+ self.env['account.bank.statement.import.reapply.rules'].with_context(
+ active_ids=statement.ids,
+ ).create({}).action_reapply_rules()
+ # we should have found the match from before
self.assertEqual(self.invoice.state, 'paid')
def test_rule_options(self):
- self.rule.unlink()
rule = self.env[
'account.bank.statement.import.auto.reconcile.rule'
].create({
- 'journal_id': self.env.ref('account.bank_journal').id,
+ 'journal_id': self.journal.id,
'rule_type':
'account.bank.statement.import.auto.reconcile.exact.amount',
'match_st_name': False,
})
+ # be sure our options are patched into the view
+ fields_view = rule.fields_view_get(view_type='form')
+ self.assertIn('match_st_name', fields_view['arch'])
+ # check option values
rules = rule.get_rules()
# explicitly written
self.assertFalse(rules.match_st_name)
diff --git a/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import.xml b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import.xml
index e6b3421..d8b40c4 100644
--- a/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import.xml
+++ b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import.xml
@@ -5,8 +5,10 @@
-
-
+
+
+
+
diff --git a/account_bank_statement_import_auto_reconcile/views/account_journal.xml b/account_bank_statement_import_auto_reconcile/views/account_journal.xml
index ae5dd08..a7ee22e 100644
--- a/account_bank_statement_import_auto_reconcile/views/account_journal.xml
+++ b/account_bank_statement_import_auto_reconcile/views/account_journal.xml
@@ -4,9 +4,26 @@
account.journal
-
-
-
+
+
+
+
+
+
+
+
+ account.journal
+
+
+
+
+
+
+