Correct tests

This commit is contained in:
Matthieu Dietrich
2016-04-13 15:31:54 +02:00
parent 6af891da27
commit 6b0c30e191
9 changed files with 122 additions and 380 deletions

View File

@@ -8,15 +8,15 @@ Mass Reconcile
This is a shared work between Akretion and Camptocamp
in order to provide:
- reconciliation facilities for big volume of transactions
- setup different profiles of reconciliation by account
- each profile can use many methods of reconciliation
- this module is also a base to create others
reconciliation methods which can plug in the profiles
- a profile a reconciliation can be run manually
or by a cron
- monitoring of reconciliation runs with an history
which keep track of the reconciled Journal items
- reconciliation facilities for big volume of transactions
- setup different profiles of reconciliation by account
- each profile can use many methods of reconciliation
- this module is also a base to create others
reconciliation methods which can plug in the profiles
- a profile a reconciliation can be run manually
or by a cron
- monitoring of reconciliation runs with an history
which keep track of the reconciled Journal items
2 simple reconciliation methods are integrated
in this module, the simple reconciliations works

View File

@@ -16,8 +16,6 @@
"security/ir.model.access.csv",
"views/res_config_view.xml",
],
"test": ['test/mass_reconcile.yml',
],
'license': 'AGPL-3',
"auto_install": False,
'installable': True,

View File

@@ -2,7 +2,7 @@
# © 2014-2016 Camptocamp SA (Leonardo Pistone, Damien Crier, Matthieu Dietrich)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import models, api, fields
from openerp import models, fields
class AccountConfigSettings(models.TransientModel):
@@ -15,20 +15,6 @@ class AccountConfigSettings(models.TransientModel):
help="Leave zero to commit only at the end of the process."
)
@api.multi
def onchange_company_id(self, company_id):
result = super(AccountConfigSettings, self).onchange_company_id(
company_id
)
if company_id:
company = self.env['res.company'].browse(company_id)
result['value']['reconciliation_commit_every'] = (
company.reconciliation_commit_every
)
return result
class Company(models.Model):
_inherit = "res.company"

View File

@@ -1,116 +0,0 @@
-
In order to test Confirm Draft Invoice wizard I create an invoice and confirm it with this wizard
-
!record {model: account.invoice, id: account_invoice_state2}:
account_id: account.a_recv
company_id: base.main_company
currency_id: base.EUR
invoice_line:
- account_id: account.a_sale
name: '[PCSC234] PC Assemble SC234'
price_unit: 1000.0
quantity: 1.0
product_id: product.product_product_3
uos_id: product.product_uom_unit
journal_id: account.bank_journal
partner_id: base.res_partner_12
reference_type: none
-
I called the "Confirm Draft Invoices" wizard
-
!record {model: account.invoice.confirm, id: account_invoice_confirm_0}:
{}
-
I clicked on Confirm Invoices Button
-
!python {model: account.invoice.confirm}: |
self.invoice_confirm(cr, uid, [ref("account_invoice_confirm_0")], {"lang": 'en_US',
"tz": False, "active_model": "account.invoice", "active_ids": [ref("account_invoice_state2")],
"type": "out_invoice", "active_id": ref("account_invoice_state2"), })
-
I check that customer invoice state is "Open"
-
!assert {model: account.invoice, id: account_invoice_state2}:
- state == 'open'
-
In order to test Bank Statement feature of account I create a bank statement line and confirm it and check it's move created
-
I select the period and journal for the bank statement
-
!python {model: account.bank.statement}: |
import time
journal = self._default_journal_id(cr, uid, {'lang': u'en_US', 'tz': False, 'active_model': 'ir.ui.menu',
'journal_type': 'bank', 'period_id': time.strftime('%m'), 'active_ids': [ref('account.menu_bank_statement_tree')], 'active_id': ref('account.menu_bank_statement_tree')})
assert journal, 'Journal has not been selected'
-
I create a bank statement with Opening and Closing balance 0.
-
!record {model: account.bank.statement, id: account_bank_statement_0}:
balance_end_real: 0.0
balance_start: 0.0
date: !eval time.strftime('%Y-%m-%d')
journal_id: account.bank_journal
-
I create bank statement line
-
!python {model: account.bank.statement.line}: |
vals = {
'amount': 1000.0,
'partner_id': ref('base.res_partner_12'),
'statement_id': ref('account_bank_statement_0'),
'name': 'EXT001'
}
line_id = self.create(cr, uid, vals)
assert line_id, "Account bank statement line has not been created"
-
We process the reconciliation of the invoice line
-
!python {model: account.bank.statement}: |
line_id = None
invoice = self.pool.get('account.invoice').browse(cr, uid, ref("account_invoice_state2"))
for l in invoice.move_id.line_id:
if l.account_id.id == ref('account.a_recv'):
line_id = l
break
statement = self.browse(cr, uid, ref("account_bank_statement_0"))
for statement_line in statement.line_ids:
self.pool.get('account.bank.statement.line').process_reconciliation(
cr, uid, statement_line.id,
[
{
'counterpart_move_line_id': line_id.id,
'credit': 1000.0,
'debit': 0.0,
'name': line_id.name
}
]
)
-
We unreconcile previous reconciliation so we can create an mass reconcile record to reconcile invoice
-
!python {model: account.move.line}: |
lines_to_unreconcile = self.search(cr, uid, [('reconcile_ref', '!=', False), ('statement_id', '=', ref("account_bank_statement_0"))])
self._remove_move_reconcile(cr, uid, lines_to_unreconcile)
-
We create the mass reconcile record
-
!record {model: account.mass.reconcile, id: account_mass_reconcile_0}:
name: 'mass reconcile 1'
account: account.a_recv
reconcile_method:
- name: 'mass.reconcile.simple.partner'
-
We call the automatic reconcilation method
-
!python {model: account.mass.reconcile}: |
self.run_reconcile(cr, uid, [ref('account_mass_reconcile_0')])
-
I check that customer invoice state is "Paid"
-
!assert {model: account.invoice, id: account_invoice_state2}:
- state == 'paid'

View File

@@ -3,44 +3,42 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.tests import common
from openerp import tools
from openerp.modules import get_module_resource
class TestOnChange(common.TransactionCase):
def setUp(self):
super(TestOnChange, self).setUp()
self.acc_setting_obj = self.registry('account.config.settings')
self.company_obj = self.registry('res.company')
tools.convert_file(self.cr, 'account',
get_module_resource('account', 'test',
'account_minimal_test.xml'),
{}, 'init', False, 'test')
acc_setting = self.env['account.config.settings']
self.acc_setting_obj = acc_setting.create({})
self.company_obj = self.env['res.company']
# analytic defaults account creation
self.main_company = self.ref('base.main_company')
self.main_company = self.env.ref('base.main_company')
self.sec_company = self.company_obj.create(
self.cr,
self.uid,
{
'name': 'Second company',
'reconciliation_commit_every': 80,
'reconciliation_commit_every': 80
}
)
)
def test_retrieve_analytic_account(self):
sec_company_commit = self.company_obj.browse(
self.cr,
self.uid,
self.sec_company).reconciliation_commit_every
main_company_commit = self.company_obj.browse(
self.cr,
self.uid,
self.main_company).reconciliation_commit_every
sec_company_commit = self.sec_company.reconciliation_commit_every
main_company_commit = self.main_company.reconciliation_commit_every
res1 = self.acc_setting_obj.onchange_company_id(
self.cr, self.uid, [], self.sec_company)
self.acc_setting_obj.company_id = self.sec_company
self.assertEqual(sec_company_commit, res1.get(
'value', {}).get('reconciliation_commit_every', False))
self.assertEqual(sec_company_commit,
self.acc_setting_obj.reconciliation_commit_every,
False)
res2 = self.acc_setting_obj.onchange_company_id(
self.cr, self.uid, [], self.main_company)
self.assertEqual(main_company_commit, res2.get(
'value', {}).get('reconciliation_commit_every', False))
# self.assertEqual(self.ref('account.analytic_agrolait'), res2.get(
# 'value', {}).get('reconciliation_commit_every', False))
self.acc_setting_obj.company_id = self.main_company
self.assertEqual(main_company_commit,
self.acc_setting_obj.reconciliation_commit_every,
False)

View File

@@ -3,38 +3,37 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.tests import common
from openerp import fields, exceptions
from openerp import fields, exceptions, tools
from openerp.modules import get_module_resource
class TestReconcile(common.TransactionCase):
def setUp(self):
super(TestReconcile, self).setUp()
self.rec_history_obj = self.registry('mass.reconcile.history')
self.mass_rec_obj = self.registry('account.mass.reconcile')
tools.convert_file(self.cr, 'account',
get_module_resource('account', 'test',
'account_minimal_test.xml'),
{}, 'init', False, 'test')
self.rec_history_obj = self.env['mass.reconcile.history']
self.mass_rec_obj = self.env['account.mass.reconcile']
self.mass_rec_method_obj = (
self.registry('account.mass.reconcile.method')
self.env['account.mass.reconcile.method']
)
self.mass_rec = self.mass_rec_obj.create(
self.cr,
self.uid,
{
'name': 'AER2',
'account': self.ref('account.a_salary_expense'),
}
)
self.mass_rec_method = self.mass_rec_method_obj.create(
self.cr,
self.uid,
{
'name': 'mass.reconcile.simple.name',
'sequence': '10',
'task_id': self.mass_rec,
'task_id': self.mass_rec.id,
}
)
self.mass_rec_no_history = self.mass_rec_obj.create(
self.cr,
self.uid,
{
'name': 'AER3',
'account': self.ref('account.a_salary_expense'),
@@ -42,65 +41,29 @@ class TestReconcile(common.TransactionCase):
}
)
self.rec_history = self.rec_history_obj.create(
self.cr,
self.uid,
{
'mass_reconcile_id': self.mass_rec,
'mass_reconcile_id': self.mass_rec.id,
'date': fields.Datetime.now(),
}
)
def test_last_history(self):
mass_rec_last_hist = self.mass_rec_obj.browse(
self.cr,
self.uid,
self.mass_rec
).last_history.id
mass_rec_last_hist = self.mass_rec.last_history
self.assertEqual(self.rec_history, mass_rec_last_hist)
def test_last_history_empty(self):
mass_rec_last_hist = self.mass_rec_obj.browse(
self.cr,
self.uid,
self.mass_rec_no_history
).last_history.id
mass_rec_last_hist = self.mass_rec_no_history.last_history.id
self.assertEqual(False, mass_rec_last_hist)
def test_last_history_full_no_history(self):
with self.assertRaises(exceptions.Warning):
self.mass_rec_obj.last_history_reconcile(
self.cr, self.uid, [self.mass_rec_no_history])
self.mass_rec_no_history.last_history_reconcile()
def test_open_unreconcile(self):
res = self.mass_rec_obj.open_unreconcile(
self.cr,
self.uid,
[self.mass_rec]
)
res = self.mass_rec.open_unreconcile()
self.assertEqual(unicode([('id', 'in', [])]), res.get('domain', []))
def test_prepare_run_transient(self):
res = self.mass_rec_obj._prepare_run_transient(
self.cr,
self.uid,
self.mass_rec_method_obj.browse(
self.cr,
self.uid,
self.mass_rec_method
)
)
res = self.mass_rec._prepare_run_transient(self.mass_rec_method)
self.assertEqual(self.ref('account.a_salary_expense'),
res.get('account_id', 0))
class TestReconcileNoMassReconcileAvailable(common.TransactionCase):
def setUp(self):
super(TestReconcileNoMassReconcileAvailable, self).setUp()
self.rec_history_obj = self.registry('mass.reconcile.history')
self.mass_rec_obj = self.registry('account.mass.reconcile')
# def test_run_scheduler(self):
# with self.assertRaises(AssertionError):
# self.mass_rec_obj.run_scheduler(
# self.cr, self.uid)

View File

@@ -3,18 +3,21 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.tests import common
from openerp import fields
from openerp import fields, tools
from openerp.modules import get_module_resource
class TestReconcileHistory(common.TransactionCase):
def setUp(self):
super(TestReconcileHistory, self).setUp()
self.rec_history_obj = self.registry('mass.reconcile.history')
self.mass_rec_obj = self.registry('account.mass.reconcile')
tools.convert_file(self.cr, 'account',
get_module_resource('account', 'test',
'account_minimal_test.xml'),
{}, 'init', False, 'test')
self.rec_history_obj = self.env['mass.reconcile.history']
self.mass_rec_obj = self.env['account.mass.reconcile']
self.mass_rec = self.mass_rec_obj.create(
self.cr,
self.uid,
{
'name': 'AER1',
'account': self.ref('account.a_expense'),
@@ -22,22 +25,18 @@ class TestReconcileHistory(common.TransactionCase):
}
)
self.rec_history = self.rec_history_obj.create(
self.cr,
self.uid,
{
'mass_reconcile_id': self.mass_rec,
'mass_reconcile_id': self.mass_rec.id,
'date': fields.Datetime.now(),
}
)
def test_open_full_empty(self):
res = self.rec_history_obj._open_move_lines(
self.cr, self.uid, [self.rec_history])
res = self.rec_history._open_move_lines()
self.assertEqual(unicode([('id', 'in', [])]), res.get(
'domain', []))
def test_open_full_empty_from_method(self):
res = self.rec_history_obj.open_reconcile(
self.cr, self.uid, [self.rec_history])
res = self.rec_history.open_reconcile()
self.assertEqual(unicode([('id', 'in', [])]), res.get(
'domain', []))

View File

@@ -1,115 +1,85 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Damien Crier
# Copyright 2015 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# © 2014-2016 Camptocamp SA (Damien Crier)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.tests import common
import time
from openerp import fields, tools
from openerp.modules import get_module_resource
class TestScenarioReconcile(common.TransactionCase):
def setUp(self):
super(TestScenarioReconcile, self).setUp()
self.rec_history_obj = self.registry('mass.reconcile.history')
self.mass_rec_obj = self.registry('account.mass.reconcile')
self.invoice_obj = self.registry('account.invoice')
self.bk_stmt_obj = self.registry('account.bank.statement')
self.bk_stmt_line_obj = self.registry('account.bank.statement.line')
self.acc_move_line_obj = self.registry('account.move.line')
tools.convert_file(self.cr, 'account',
get_module_resource('account', 'test',
'account_minimal_test.xml'),
{}, 'init', False, 'test')
self.rec_history_obj = self.env['mass.reconcile.history']
self.mass_rec_obj = self.env['account.mass.reconcile']
self.invoice_obj = self.env['account.invoice']
self.bk_stmt_obj = self.env['account.bank.statement']
self.bk_stmt_line_obj = self.env['account.bank.statement.line']
self.acc_move_line_obj = self.env['account.move.line']
self.mass_rec_method_obj = (
self.registry('account.mass.reconcile.method')
self.env['account.mass.reconcile.method']
)
self.account_fx_income_id = self.ref("account.income_fx_income")
self.account_fx_expense_id = self.ref("account.income_fx_expense")
self.acs_model = self.registry('account.config.settings')
self.acs_model = self.env['account.config.settings']
acs_ids = self.acs_model.search(
self.cr, self.uid,
[('company_id', '=', self.ref("base.main_company"))]
)
values = {'group_multi_currency': True,
'income_currency_exchange_account_id':
self.account_fx_income_id,
'expense_currency_exchange_account_id':
self.account_fx_expense_id}
'currency_id': self.ref('base.EUR')}
if acs_ids:
self.acs_model.write(self.cr, self.uid, acs_ids, values)
acs_ids.write(values)
else:
default_vals = self.acs_model.default_get(self.cr, self.uid, [])
default_vals = self.acs_model.default_get([])
default_vals.update(values)
default_vals['date_stop'] = time.strftime('%Y-12-31')
default_vals['date_start'] = time.strftime('%Y-%m-%d')
default_vals['period'] = 'month'
self.acs_model.create(self.cr, self.uid, default_vals)
acs_ids = self.acs_model.create(default_vals)
def test_scenario_reconcile(self):
# create invoice
inv_id = self.invoice_obj.create(
self.cr,
self.uid,
invoice = self.invoice_obj.create(
{
'type': 'out_invoice',
'account_id': self.ref('account.a_recv'),
'company_id': self.ref('base.main_company'),
'currency_id': self.ref('base.EUR'),
'journal_id': self.ref('account.sales_journal'),
'partner_id': self.ref('base.res_partner_12'),
'invoice_line': [
'invoice_line_ids': [
(0, 0, {
'name': '[PCSC234] PC Assemble SC234',
'account_id': self.ref('account.a_sale'),
'price_unit': 1000.0,
'quantity': 1.0,
'product_id': self.ref('product.product_product_3'),
'uos_id': self.ref('product.product_uom_unit'),
}
)
]
}
)
# validate invoice
self.invoice_obj.signal_workflow(
self.cr,
self.uid,
[inv_id],
'invoice_open'
)
invoice_record = self.invoice_obj.browse(self.cr, self.uid, [inv_id])
self.assertEqual('open', invoice_record.state)
invoice.signal_workflow('invoice_open')
self.assertEqual('open', invoice.state)
# create bank_statement
bk_stmt_id = self.bk_stmt_obj.create(
self.cr,
self.uid,
statement = self.bk_stmt_obj.create(
{
'balance_end_real': 0.0,
'balance_start': 0.0,
'date': time.strftime('%Y-%m-%d'),
'date': fields.Datetime.now(),
'journal_id': self.ref('account.bank_journal'),
'line_ids': [
(0, 0, {
'amount': 1000.0,
'partner_id': self.ref('base.res_partner_12'),
'name': invoice_record.number,
'ref': invoice_record.number,
'name': invoice.number,
'ref': invoice.number,
}
)
]
@@ -118,41 +88,32 @@ class TestScenarioReconcile(common.TransactionCase):
# reconcile
line_id = None
for l in invoice_record.move_id.line_id:
for l in invoice.move_id.line_ids:
if l.account_id.id == self.ref('account.a_recv'):
line_id = l
break
statement = self.bk_stmt_obj.browse(self.cr, self.uid, bk_stmt_id)
for statement_line in statement.line_ids:
self.bk_stmt_line_obj.process_reconciliation(
self.cr, self.uid, statement_line.id,
statement_line.process_reconciliation(
[
{
'counterpart_move_line_id': line_id.id,
'move_line': line_id,
'credit': 1000.0,
'debit': 0.0,
'name': invoice_record.number,
'name': invoice.number,
}
]
)
# unreconcile journal item created by previous reconciliation
lines_to_unreconcile = self.acc_move_line_obj.search(
self.cr,
self.uid,
[('reconcile_ref', '!=', False),
('statement_id', '=', bk_stmt_id)]
)
self.acc_move_line_obj._remove_move_reconcile(
self.cr,
self.uid,
lines_to_unreconcile
[('reconciled', '=', True),
('statement_id', '=', statement.id)]
)
lines_to_unreconcile.remove_move_reconcile()
# create the mass reconcile record
mass_rec_id = self.mass_rec_obj.create(
self.cr,
self.uid,
mass_rec = self.mass_rec_obj.create(
{
'name': 'mass_reconcile_1',
'account': self.ref('account.a_recv'),
@@ -165,27 +126,21 @@ class TestScenarioReconcile(common.TransactionCase):
}
)
# call the automatic reconcilation method
self.mass_rec_obj.run_reconcile(
self.cr,
self.uid,
[mass_rec_id]
)
mass_rec.run_reconcile()
self.assertEqual(
'paid',
self.invoice_obj.browse(self.cr, self.uid, inv_id).state
invoice.state
)
def test_scenario_reconcile_currency(self):
# create currency rate
self.registry('res.currency.rate').create(self.cr, self.uid, {
'name': time.strftime('%Y-%m-%d') + ' 00:00:00',
self.env['res.currency.rate'].create({
'name': fields.Date.today() + ' 00:00:00',
'currency_id': self.ref('base.USD'),
'rate': 1.5,
})
# create invoice
inv_id = self.invoice_obj.create(
self.cr,
self.uid,
invoice = self.invoice_obj.create(
{
'type': 'out_invoice',
'account_id': self.ref('account.a_recv'),
@@ -193,45 +148,37 @@ class TestScenarioReconcile(common.TransactionCase):
'currency_id': self.ref('base.USD'),
'journal_id': self.ref('account.bank_journal_usd'),
'partner_id': self.ref('base.res_partner_12'),
'invoice_line': [
'invoice_line_ids': [
(0, 0, {
'name': '[PCSC234] PC Assemble SC234',
'account_id': self.ref('account.a_sale'),
'price_unit': 1000.0,
'quantity': 1.0,
'product_id': self.ref('product.product_product_3'),
'uos_id': self.ref('product.product_uom_unit'),
}
)
]
}
)
# validate invoice
self.invoice_obj.signal_workflow(
self.cr,
self.uid,
[inv_id],
'invoice_open'
)
invoice_record = self.invoice_obj.browse(self.cr, self.uid, [inv_id])
self.assertEqual('open', invoice_record.state)
invoice.signal_workflow('invoice_open')
self.assertEqual('open', invoice.state)
# create bank_statement
bk_stmt_id = self.bk_stmt_obj.create(
self.cr,
self.uid,
statement = self.bk_stmt_obj.create(
{
'balance_end_real': 0.0,
'balance_start': 0.0,
'date': time.strftime('%Y-%m-%d'),
'date': fields.Datetime.now(),
'journal_id': self.ref('account.bank_journal_usd'),
'currency_id': self.ref('base.USD'),
'line_ids': [
(0, 0, {
'amount': 1000.0,
'amount_currency': 1500.0,
'currency_id': self.ref('base.USD'),
'partner_id': self.ref('base.res_partner_12'),
'name': invoice_record.number,
'ref': invoice_record.number,
'name': invoice.number,
'ref': invoice.number,
}
)
]
@@ -240,41 +187,31 @@ class TestScenarioReconcile(common.TransactionCase):
# reconcile
line_id = None
for l in invoice_record.move_id.line_id:
for l in invoice.move_id.line_ids:
if l.account_id.id == self.ref('account.a_recv'):
line_id = l
break
statement = self.bk_stmt_obj.browse(self.cr, self.uid, bk_stmt_id)
for statement_line in statement.line_ids:
self.bk_stmt_line_obj.process_reconciliation(
self.cr, self.uid, statement_line.id,
statement_line.process_reconciliation(
[
{
'counterpart_move_line_id': line_id.id,
'move_line': line_id,
'credit': 1000.0,
'debit': 0.0,
'name': invoice_record.number,
'name': invoice.number,
}
]
)
# unreconcile journal item created by previous reconciliation
lines_to_unreconcile = self.acc_move_line_obj.search(
self.cr,
self.uid,
[('reconcile_ref', '!=', False),
('statement_id', '=', bk_stmt_id)]
)
self.acc_move_line_obj._remove_move_reconcile(
self.cr,
self.uid,
lines_to_unreconcile
[('reconciled', '=', True),
('statement_id', '=', statement.id)]
)
lines_to_unreconcile.remove_move_reconcile()
# create the mass reconcile record
mass_rec_id = self.mass_rec_obj.create(
self.cr,
self.uid,
mass_rec = self.mass_rec_obj.create(
{
'name': 'mass_reconcile_1',
'account': self.ref('account.a_recv'),
@@ -287,12 +224,8 @@ class TestScenarioReconcile(common.TransactionCase):
}
)
# call the automatic reconcilation method
self.mass_rec_obj.run_reconcile(
self.cr,
self.uid,
[mass_rec_id]
)
mass_rec.run_reconcile()
self.assertEqual(
'paid',
self.invoice_obj.browse(self.cr, self.uid, inv_id).state
invoice.state
)

View File

@@ -116,25 +116,6 @@ The lines should have the partner, the credit entry ref. is matched vs the debit
<!-- account.mass.reconcile.method view -->
<record id="account_mass_reconcile_method_form" model="ir.ui.view">
<field name="name">account.mass.reconcile.method.form</field>
<field name="priority">20</field>
<field name="model">account.mass.reconcile.method</field>
<field name="arch" type="xml">
<form string="Automatic Mass Reconcile Method">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="write_off"/>
<field name="account_lost_id" attrs="{'required':[('write_off','>',0)]}"/>
<field name="account_profit_id" attrs="{'required':[('write_off','>',0)]}"/>
<field name="income_exchange_account_id" groups="base.group_multi_currency"/>
<field name="expense_exchange_account_id" groups="base.group_multi_currency"/>
<field name="journal_id" attrs="{'required':[('write_off','>',0)]}"/>
<field name="date_base_on"/>
</form>
</field>
</record>
<record id="account_mass_reconcile_method_tree" model="ir.ui.view">
<field name="name">account.mass.reconcile.method.tree</field>
<field name="priority">20</field>