[IMP] account_bank_statement_import: ask for confirmation before creating a journal
In previous versions the system would simply refuse to import a bank statement if the corresponding journal/account did not exist. As of 9.0 the system can create them automatically, but should not do that without asking for confirmation first, to avoid user mistakes with dangerous consequences. Closes #6023
This commit is contained in:
committed by
Olivier Dony
parent
8c65573885
commit
bc33b8dd04
@@ -1,3 +1,5 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
import account_bank_statement_import
|
||||
|
||||
import wizard
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
'description' : """Generic Wizard to Import Bank Statements. Includes the import of files in .OFX format""",
|
||||
'data' : [
|
||||
'account_bank_statement_import_view.xml',
|
||||
'account_import_tip_data.xml'
|
||||
'account_import_tip_data.xml',
|
||||
'wizard/journal_creation.xml',
|
||||
],
|
||||
'demo': [
|
||||
'demo/fiscalyear_period.xml',
|
||||
|
||||
@@ -37,21 +37,47 @@ class account_bank_statement_import(osv.TransientModel):
|
||||
context = {}
|
||||
#set the active_id in the context, so that any extension module could
|
||||
#reuse the fields chosen in the wizard if needed (see .QIF for example)
|
||||
context.update({'active_id': ids[0]})
|
||||
ctx = dict(context)
|
||||
ctx['active_id'] = ids[0]
|
||||
|
||||
data_file = self.browse(cr, uid, ids[0], context=context).data_file
|
||||
data_file = self.browse(cr, uid, ids[0], context=ctx).data_file
|
||||
|
||||
# The appropriate implementation module returns the required data
|
||||
currency_code, account_number, stmts_vals = self._parse_file(cr, uid, base64.b64decode(data_file), context=context)
|
||||
currency_code, account_number, stmts_vals = self._parse_file(cr, uid, base64.b64decode(data_file), context=ctx)
|
||||
# Check raw data
|
||||
self._check_parsed_data(cr, uid, stmts_vals, context=context)
|
||||
self._check_parsed_data(cr, uid, stmts_vals, context=ctx)
|
||||
# Try to find the bank account and currency in odoo
|
||||
currency_id, bank_account_id = self._find_additional_data(cr, uid, currency_code, account_number, context=context)
|
||||
# Find or create the bank journal
|
||||
journal_id = self._get_journal(cr, uid, currency_id, bank_account_id, account_number, context=context)
|
||||
# Create the bank account if not already existing
|
||||
if not bank_account_id and account_number:
|
||||
self._create_bank_account(cr, uid, account_number, journal_id=journal_id, partner_id=uid, context=context)
|
||||
currency_id, bank_account_id = self._find_additional_data(cr, uid, currency_code, account_number, context=ctx)
|
||||
# Try to find the journal
|
||||
journal_id = self._get_journal(cr, uid, currency_id, bank_account_id, account_number, context=ctx)
|
||||
# If no journal found, ask the user about creating one
|
||||
if not journal_id:
|
||||
return self._journal_creation_wizard(cr, uid, currency_id, account_number, bank_account_id, context=ctx)
|
||||
# Or directly finish the import
|
||||
return self._finalize_import(cr, uid, bank_account_id, account_number, journal_id, stmts_vals, context=ctx)
|
||||
|
||||
def _journal_creation_wizard(self, cr, uid, currency_id, account_number, bank_account_id, context=None):
|
||||
""" Calls a wizard that allows the user to accept/refuse journal creation """
|
||||
return {
|
||||
'name': _('Journal Creation'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'account.bank.statement.import.journal.creation',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'statement_import_transient_id': context['active_id'],
|
||||
'default_currency_id': currency_id,
|
||||
'default_account_number': account_number,
|
||||
'bank_account_id': bank_account_id,
|
||||
'default_name': _('Bank') + ' ' + account_number,
|
||||
}
|
||||
}
|
||||
|
||||
def _finalize_import(self, cr, uid, bank_account_id, account_number, journal_id, stmts_vals, context=None):
|
||||
""" This part is separated from import_file so it can be called via the joutnal creation wizard
|
||||
No CUD can happen before this method is called, so not calling it is like aborting the import.
|
||||
"""
|
||||
# Prepare statement data to be used for bank statements creation
|
||||
stmts_vals = self._complete_stmts_vals(cr, uid, stmts_vals, journal_id, account_number, context=context)
|
||||
# Create the bank statements
|
||||
@@ -153,31 +179,12 @@ class account_bank_statement_import(osv.TransientModel):
|
||||
if currency_id and currency_id != journal_currency_id:
|
||||
raise UserError(_('The currency of the bank statement is not the same as the currency of the journal !'))
|
||||
|
||||
# If there is no journal, create one (and its account)
|
||||
if not journal_id and account_number:
|
||||
journal_id = self._create_journal(cr, uid, currency_id, account_number, context=context)
|
||||
if bank_account_id:
|
||||
bank_pool.write(cr, uid, [bank_account_id], {'journal_id': journal_id}, context=context)
|
||||
|
||||
# If we couldn't find/create a journal, everything is lost
|
||||
if not journal_id:
|
||||
# If we couldn't find a journal and can't create one, everything is lost
|
||||
if not journal_id and not account_number:
|
||||
raise UserError(_('Cannot find in which journal import this statement. Please manually select a journal.'))
|
||||
|
||||
return journal_id
|
||||
|
||||
def _create_journal(self, cr, uid, currency_id, account_number, context=None):
|
||||
""" Create a journal and its account """
|
||||
wmca_pool = self.pool.get('wizard.multi.charts.accounts')
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
|
||||
|
||||
vals_account = {'currency_id': currency_id, 'acc_name': account_number, 'account_type': 'bank', 'currency_id': currency_id}
|
||||
vals_account = wmca_pool._prepare_bank_account(cr, uid, company, vals_account, context=context)
|
||||
account_id = self.pool.get('account.account').create(cr, uid, vals_account, context=context)
|
||||
|
||||
vals_journal = {'currency_id': currency_id, 'acc_name': _('Bank') + ' ' + account_number, 'account_type': 'bank'}
|
||||
vals_journal = wmca_pool._prepare_bank_journal(cr, uid, company, vals_journal, account_id, context=context)
|
||||
return self.pool.get('account.journal').create(cr, uid, vals_journal, context=context)
|
||||
|
||||
def _create_bank_account(self, cr, uid, account_number, journal_id=False, partner_id=False, context=None):
|
||||
try:
|
||||
type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal')
|
||||
@@ -245,7 +252,7 @@ class account_bank_statement_import(osv.TransientModel):
|
||||
else:
|
||||
ignored_statement_lines_import_ids.append(line_vals['unique_import_id'])
|
||||
if len(filtered_st_lines) > 0:
|
||||
# Remove values that won't be used to create records
|
||||
# Remove values that won't be used to create records
|
||||
st_vals.pop('transactions', None)
|
||||
for line_vals in filtered_st_lines:
|
||||
line_vals.pop('account_number', None)
|
||||
@@ -270,4 +277,3 @@ class account_bank_statement_import(osv.TransientModel):
|
||||
}]
|
||||
|
||||
return statement_ids, notifications
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import journal_creation
|
||||
@@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
class account_bank_statement_import_journal_creation(osv.TransientModel):
|
||||
_name = 'account.bank.statement.import.journal.creation'
|
||||
_description = 'Import Bank Statement Journal Creation Wizard'
|
||||
_columns = {
|
||||
'name': fields.char('Journal Name', required=True),
|
||||
'currency_id': fields.many2one('res.currency', 'Currency', readonly=True),
|
||||
'account_number': fields.char('Account Number', readonly=True),
|
||||
}
|
||||
|
||||
def create_journal(self, cr, uid, ids, context=None):
|
||||
bank_account_id = context['bank_account_id']
|
||||
|
||||
wmca_pool = self.pool.get('wizard.multi.charts.accounts')
|
||||
import_wiz_obj = self.pool['account.bank.statement.import']
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
|
||||
wiz = self.browse(cr, uid, ids, context=context)[0]
|
||||
currency_id = wiz.currency_id.id
|
||||
account_number = wiz.account_number
|
||||
|
||||
# Create the account.account
|
||||
vals_account = {'currency_id': currency_id, 'acc_name': account_number, 'account_type': 'bank', 'currency_id': currency_id}
|
||||
vals_account = wmca_pool._prepare_bank_account(cr, uid, company, vals_account, context=context)
|
||||
account_id = self.pool.get('account.account').create(cr, uid, vals_account, context=context)
|
||||
|
||||
# Create the account.journal
|
||||
name = wiz.name
|
||||
vals_journal = {'currency_id': currency_id, 'acc_name': name, 'account_type': 'bank'}
|
||||
vals_journal = wmca_pool._prepare_bank_journal(cr, uid, company, vals_journal, account_id, context=context)
|
||||
journal_id = self.pool.get('account.journal').create(cr, uid, vals_journal, context=context)
|
||||
if bank_account_id:
|
||||
self.pool.get('res.partner.bank').write(cr, uid, [bank_account_id], {'journal_id': journal_id}, context=context)
|
||||
# Create the bank account if not already existing
|
||||
elif not bank_account_id and account_number:
|
||||
import_wiz_obj._create_bank_account(cr, uid, account_number, journal_id=journal_id, partner_id=uid, context=context)
|
||||
# Finish the statement import
|
||||
statement_import_transient = import_wiz_obj.browse(cr, uid, context['statement_import_transient_id'], context=context)
|
||||
return statement_import_transient.import_file()
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" ?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="account_bank_statement_import_journal_creation_view" model="ir.ui.view">
|
||||
<field name="name">Journal Creation</field>
|
||||
<field name="model">account.bank.statement.import.journal.creation</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Journal Creation">
|
||||
<p>The account of the statement you are importing is not yet recorded in Odoo. In order to proceed with the import, you need to create a bank account and journal using this form.</p>
|
||||
<p>Just click OK to create the account/journal and finish the import. If this was a mistake, hit cancel to abort the import.</p>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="currency_id"/>
|
||||
<field name="account_number"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="create_journal" string="OK" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -17,13 +17,20 @@ class TestOfxFile(TransactionCase):
|
||||
#the Python library isn't installed on the server, the OFX import is unavailable and the test cannot be run
|
||||
return True
|
||||
cr, uid = self.cr, self.uid
|
||||
creation_wiz_obj = self.registry('account.bank.statement.import.journal.creation')
|
||||
ofx_file_path = get_module_resource('account_bank_statement_import_ofx', 'test_ofx_file', 'test_ofx.ofx')
|
||||
ofx_file = open(ofx_file_path, 'rb').read().encode('base64')
|
||||
bank_statement_id = self.statement_import_model.create(cr, uid, dict(
|
||||
data_file=ofx_file,
|
||||
))
|
||||
self.statement_import_model.import_file(cr, uid, [bank_statement_id])
|
||||
statement_id = self.bank_statement_model.search(cr, uid, [('name', '=', '000000123')])[0]
|
||||
res = self.statement_import_model.import_file(cr, uid, [bank_statement_id])
|
||||
self.assertEquals(res['res_model'], 'account.bank.statement.import.journal.creation', 'boom')
|
||||
ctx = res.get('context', {}).copy()
|
||||
wiz_id = creation_wiz_obj.create(cr, uid, {}, context=ctx)
|
||||
wiz = creation_wiz_obj.browse(cr, uid, [wiz_id], context=ctx)
|
||||
wiz.create_journal()
|
||||
|
||||
statement_id = self.bank_statement_model.search(cr, uid, [('name', '=', '000000123')])
|
||||
bank_st_record = self.bank_statement_model.browse(cr, uid, statement_id)
|
||||
self.assertEquals(bank_st_record.balance_start, 2516.56)
|
||||
self.assertEquals(bank_st_record.balance_end_real, 2156.56)
|
||||
|
||||
Reference in New Issue
Block a user