You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

98 lines
4.6 KiB

# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
import dateutil.parser
import StringIO
from openerp.tools.translate import _
from openerp.osv import osv, fields
from openerp.exceptions import Warning
class account_bank_statement_import(osv.TransientModel):
_inherit = "account.bank.statement.import"
_columns = {
'journal_id': fields.many2one('account.journal', string='Journal', help='Accounting journal related to the bank statement you\'re importing. It has be be manually chosen for statement formats which doesn\'t allow automatic journal detection (QIF for example).'),
'hide_journal_field': fields.boolean('Hide the journal field in the view'),
}
def _get_hide_journal_field(self, cr, uid, context=None):
return context and 'journal_id' in context or False
_defaults = {
'hide_journal_field': _get_hide_journal_field,
}
def _get_journal(self, cr, uid, currency_id, bank_account_id, account_number, context=None):
""" As .QIF format does not allow us to detect the journal, we need to let the user choose it.
We set it in context before to call super so it's the same as calling the widget from a journal """
if context is None:
context = {}
if context.get('active_id'):
record = self.browse(cr, uid, context.get('active_id'), context=context)
if record.journal_id:
context['journal_id'] = record.journal_id.id
return super(account_bank_statement_import, self)._get_journal(cr, uid, currency_id, bank_account_id, account_number, context=context)
def _check_qif(self, cr, uid, data_file, context=None):
return data_file.strip().startswith('!Type:')
def _parse_file(self, cr, uid, data_file, context=None):
if not self._check_qif(cr, uid, data_file, context=context):
return super(account_bank_statement_import, self)._parse_file(cr, uid, data_file, context=context)
try:
file_data = ""
for line in StringIO.StringIO(data_file).readlines():
file_data += line
if '\r' in file_data:
data_list = file_data.split('\r')
else:
data_list = file_data.split('\n')
header = data_list[0].strip()
header = header.split(":")[1]
except:
raise Warning(_('Could not decipher the QIF file.'))
transactions = []
vals_line = {}
total = 0
if header == "Bank":
vals_bank_statement = {}
for line in data_list:
line = line.strip()
if not line:
continue
if line[0] == 'D': # date of transaction
vals_line['date'] = dateutil.parser.parse(line[1:], fuzzy=True).date()
elif line[0] == 'T': # Total amount
total += float(line[1:].replace(',', ''))
vals_line['amount'] = float(line[1:].replace(',', ''))
elif line[0] == 'N': # Check number
vals_line['ref'] = line[1:]
elif line[0] == 'P': # Payee
vals_line['name'] = 'name' in vals_line and line[1:] + ': ' + vals_line['name'] or line[1:]
# Since QIF doesn't provide account numbers, we'll have to find res.partner and res.partner.bank here
# (normal behavious is to provide 'account_number', which the generic module uses to find partner/bank)
ids = self.pool.get('res.partner.bank').search(cr, uid, [('owner_name', '=', line[1:])], context=context)
if ids:
vals_line['bank_account_id'] = bank_account_id = ids[0]
vals_line['partner_id'] = self.pool.get('res.partner.bank').browse(cr, uid, bank_account_id, context=context).partner_id.id
elif line[0] == 'M': # Memo
vals_line['name'] = 'name' in vals_line and vals_line['name'] + ': ' + line[1:] or line[1:]
elif line[0] == '^': # end of item
transactions.append(vals_line)
vals_line = {}
elif line[0] == '\n':
transactions = []
else:
pass
else:
raise Warning(_('This file is either not a bank statement or is not correctly formed.'))
vals_bank_statement.update({
'balance_end_real': total,
'transactions': transactions
})
return None, None, [vals_bank_statement]