Browse Source

fixup! [MIG] Migrate account_bank_statement_import_auto_reconcile

pull/204/head
Holger Brunn 6 years ago
parent
commit
4ca0a23418
No known key found for this signature in database GPG Key ID: 1C9760FECA3AE18
  1. 3
      account_bank_statement_import_auto_reconcile/__manifest__.py
  2. 13
      account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml
  3. 4
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import.py
  4. 19
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile.py
  5. 1
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py
  6. 3
      account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_reapply_rules.py
  7. 138
      account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py
  8. 6
      account_bank_statement_import_auto_reconcile/views/account_bank_statement_import.xml
  9. 23
      account_bank_statement_import_auto_reconcile/views/account_journal.xml

3
account_bank_statement_import_auto_reconcile/__manifest__.py

@ -13,9 +13,6 @@
'account_bank_statement_import', 'account_bank_statement_import',
'base_domain_operator', 'base_domain_operator',
], ],
"demo": [
"demo/account_bank_statement_import_auto_reconcile_rule.xml",
],
"data": [ "data": [
"views/account_bank_statement_import_reapply_rules.xml", "views/account_bank_statement_import_reapply_rules.xml",
"views/account_bank_statement.xml", "views/account_bank_statement.xml",

13
account_bank_statement_import_auto_reconcile/demo/account_bank_statement_import_auto_reconcile_rule.xml

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="rule_amount_exact" model="account.bank.statement.import.auto.reconcile.rule">
<field name="journal_id" ref="account.bank_journal" />
<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>
</odoo>

4
account_bank_statement_import_auto_reconcile/models/account_bank_statement_import.py

@ -19,8 +19,8 @@ class AccountBankStatementImport(models.TransientModel):
return statement_ids, notifications return statement_ids, notifications
statements = self.env['account.bank.statement'].browse(statement_ids) statements = self.env['account.bank.statement'].browse(statement_ids)
for statement in statements.filtered( 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\ reconcile_rules = statement.journal_id\
.statement_import_auto_reconcile_rule_ids.get_rules() .statement_import_auto_reconcile_rule_ids.get_rules()
auto_reconciled_ids = [] auto_reconciled_ids = []

19
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): def _digits(self):
try: try:
return self.__digits return self.__digits
except:
except AttributeError:
self.__digits = self.env['decimal.precision'].precision_get( self.__digits = self.env['decimal.precision'].precision_get(
'Account' 'Account'
) )
@ -52,16 +52,13 @@ class AccountBankStatementImportAutoReconcile(models.AbstractModel):
:param statement_line: The account.bank.statement.line to reconcile. :param statement_line: The account.bank.statement.line to reconcile.
:param move_line_id: The id of the account.move.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 @api.multi
def reconcile(self, statement_line): def reconcile(self, statement_line):

1
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' _name = 'account.bank.statement.import.auto.reconcile.rule'
_description = 'Automatic reconciliation rule' _description = 'Automatic reconciliation rule'
display_name = fields.Char(string='Rule')
rule_type = fields.Selection('_sel_rule_type', required=True) rule_type = fields.Selection('_sel_rule_type', required=True)
journal_id = fields.Many2one('account.journal', 'Journal', required=True) journal_id = fields.Many2one('account.journal', 'Journal', required=True)
options = fields.Serialized('Options') options = fields.Serialized('Options')

3
account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_reapply_rules.py

@ -23,13 +23,12 @@ class AccountBankStatementImportReapplyRules(models.TransientModel):
'journal!' 'journal!'
)) ))
self.write({'journal_id': journal.id})
reconcile_rules = journal.statement_import_auto_reconcile_rule_ids\ reconcile_rules = journal.statement_import_auto_reconcile_rule_ids\
.get_rules() .get_rules()
for line in self.env['account.bank.statement.line'].search([ for line in self.env['account.bank.statement.line'].search([
('statement_id', 'in', statements.ids), ('statement_id', 'in', statements.ids),
('journal_entry_id', '=', False),
('journal_entry_ids', '=', False),
]): ]):
for rule in reconcile_rules: for rule in reconcile_rules:
if rule.reconcile(line): if rule.reconcile(line):

138
account_bank_statement_import_auto_reconcile/tests/test_account_bank_statement_import_auto_reconcile.py

@ -4,35 +4,43 @@
import base64 import base64
from datetime import timedelta from datetime import timedelta
from odoo import fields 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\ from odoo.addons.account_bank_statement_import\
.account_bank_statement_import import AccountBankStatementImport .account_bank_statement_import import AccountBankStatementImport
class TestAccountBankStatementImportAutoReconcile(TransactionCase):
post_install = True
at_install = False
class TestAccountBankStatementImportAutoReconcile(AccountingTestCase):
def setUp(self): def setUp(self):
super(TestAccountBankStatementImportAutoReconcile, self).setUp() super(TestAccountBankStatementImportAutoReconcile, self).setUp()
# we don't really have something to import, so we patch the # we don't really have something to import, so we patch the
# import routine to return what we want for our tests # import routine to return what we want for our tests
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
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({ 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): def tearDown(self):
super(TestAccountBankStatementImportAutoReconcile, self).tearDown() super(TestAccountBankStatementImportAutoReconcile, self).tearDown()
@ -40,34 +48,58 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase):
def _parse_file(self, data): def _parse_file(self, data):
date = self.invoice.date_invoice 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', 'name': 'Auto reconcile test',
'date': fields.Date.to_string( 'date': fields.Date.to_string(
fields.Date.from_string(date) + timedelta(days=5) 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 # first, we do an import with auto reconciliation turned off
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,
'auto_reconcile': False, 'auto_reconcile': False,
}).import_file() }).import_file()
# nothing should have happened # nothing should have happened
@ -77,10 +109,9 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase):
).unlink() ).unlink()
# now we do matching, but manipulate the matching to work on the # now we do matching, but manipulate the matching to work on the
# ref field only which is empty in our example # 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({ 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,
'auto_reconcile': True, 'auto_reconcile': True,
}).import_file() }).import_file()
# nothing should have happened # nothing should have happened
@ -91,24 +122,45 @@ class TestAccountBankStatementImportAutoReconcile(TransactionCase):
# 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 # 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({ 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,
'auto_reconcile': True, 'auto_reconcile': True,
}).import_file() }).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') self.assertEqual(self.invoice.state, 'paid')
def test_rule_options(self): def test_rule_options(self):
self.rule.unlink()
rule = self.env[ rule = self.env[
'account.bank.statement.import.auto.reconcile.rule' 'account.bank.statement.import.auto.reconcile.rule'
].create({ ].create({
'journal_id': self.env.ref('account.bank_journal').id,
'journal_id': self.journal.id,
'rule_type': 'rule_type':
'account.bank.statement.import.auto.reconcile.exact.amount', 'account.bank.statement.import.auto.reconcile.exact.amount',
'match_st_name': False, '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() rules = rule.get_rules()
# explicitly written # explicitly written
self.assertFalse(rules.match_st_name) self.assertFalse(rules.match_st_name)

6
account_bank_statement_import_auto_reconcile/views/account_bank_statement_import.xml

@ -5,8 +5,10 @@
<field name="inherit_id" ref="account_bank_statement_import.account_bank_statement_import_view" /> <field name="inherit_id" ref="account_bank_statement_import.account_bank_statement_import_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="data_file" position="after"> <field name="data_file" position="after">
<field name="auto_reconcile" class="oe_inline" />
<label for="auto_reconcile" />
<div>
<field name="auto_reconcile" class="oe_inline" />
<label for="auto_reconcile" />
</div>
</field> </field>
</field> </field>
</record> </record>

23
account_bank_statement_import_auto_reconcile/views/account_journal.xml

@ -4,9 +4,26 @@
<field name="model">account.journal</field> <field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_journal_form" /> <field name="inherit_id" ref="account.view_account_journal_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="default_credit_account_id" position="after">
<field name="statement_import_auto_reconcile_rule_ids"/>
</field>
<notebook position="inside">
<page
name="account_bank_statement_auto_reconcile"
string="Automatic reconciliation rules"
attrs="{'invisible': [('type', '!=', 'bank')]}"
>
<field name="statement_import_auto_reconcile_rule_ids" />
</page>
</notebook>
</field>
</record>
<record id="view_account_bank_journal_form" model="ir.ui.view">
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_bank_journal_form" />
<field name="arch" type="xml">
<xpath expr="./sheet/group" position="after">
<group name="account_bank_statement_auto_reconcile">
<field name="statement_import_auto_reconcile_rule_ids" />
</group>
</xpath>
</field> </field>
</record> </record>
</odoo> </odoo>
Loading…
Cancel
Save