diff --git a/addons/account_bank_statement_import/__init__.py b/addons/account_bank_statement_import/__init__.py index 0882f8a9139..a72befb7117 100644 --- a/addons/account_bank_statement_import/__init__.py +++ b/addons/account_bank_statement_import/__init__.py @@ -1,3 +1,5 @@ # -*- encoding: utf-8 -*- import account_bank_statement_import + +import wizard diff --git a/addons/account_bank_statement_import/__openerp__.py b/addons/account_bank_statement_import/__openerp__.py index d074ea16901..e40afbdc484 100644 --- a/addons/account_bank_statement_import/__openerp__.py +++ b/addons/account_bank_statement_import/__openerp__.py @@ -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', diff --git a/addons/account_bank_statement_import/account_bank_statement_import.py b/addons/account_bank_statement_import/account_bank_statement_import.py index 6a39a6a2920..67818766e17 100644 --- a/addons/account_bank_statement_import/account_bank_statement_import.py +++ b/addons/account_bank_statement_import/account_bank_statement_import.py @@ -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 - diff --git a/addons/account_bank_statement_import/wizard/__init__.py b/addons/account_bank_statement_import/wizard/__init__.py new file mode 100644 index 00000000000..a92b373b470 --- /dev/null +++ b/addons/account_bank_statement_import/wizard/__init__.py @@ -0,0 +1 @@ +import journal_creation diff --git a/addons/account_bank_statement_import/wizard/journal_creation.py b/addons/account_bank_statement_import/wizard/journal_creation.py new file mode 100644 index 00000000000..547afda2395 --- /dev/null +++ b/addons/account_bank_statement_import/wizard/journal_creation.py @@ -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() diff --git a/addons/account_bank_statement_import/wizard/journal_creation.xml b/addons/account_bank_statement_import/wizard/journal_creation.xml new file mode 100644 index 00000000000..a834327e8ed --- /dev/null +++ b/addons/account_bank_statement_import/wizard/journal_creation.xml @@ -0,0 +1,27 @@ + + + + + + Journal Creation + account.bank.statement.import.journal.creation + +
+

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.

+

Just click OK to create the account/journal and finish the import. If this was a mistake, hit cancel to abort the import.

+ + + + + + +
+
+
+ +
+
diff --git a/addons/account_bank_statement_import_ofx/tests/test_import_bank_statement.py b/addons/account_bank_statement_import_ofx/tests/test_import_bank_statement.py index 6a6215fa6df..3a2c080a173 100644 --- a/addons/account_bank_statement_import_ofx/tests/test_import_bank_statement.py +++ b/addons/account_bank_statement_import_ofx/tests/test_import_bank_statement.py @@ -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)