banking-addons-team team mailing list archive
-
banking-addons-team team
-
Mailing list archive
-
Message #00436
lp:~camptocamp/banking-addons/bank-statement-reconcile-70-improve-import-usability into lp:banking-addons/bank-statement-reconcile-70
Nicolas Bessi - Camptocamp has proposed merging lp:~camptocamp/banking-addons/bank-statement-reconcile-70-improve-import-usability into lp:banking-addons/bank-statement-reconcile-70.
Requested reviews:
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c): code review, no test
For more details, see:
https://code.launchpad.net/~camptocamp/banking-addons/bank-statement-reconcile-70-improve-import-usability/+merge/148665
Improve statement import global usability by retuning usable error message while parsing files.
Allows empty value for float in parsed CSV.
Minor code improvements.
--
https://code.launchpad.net/~camptocamp/banking-addons/bank-statement-reconcile-70-improve-import-usability/+merge/148665
Your team Banking Addons Team is subscribed to branch lp:banking-addons/bank-statement-reconcile-70.
=== modified file 'account_statement_base_import/parser/file_parser.py'
--- account_statement_base_import/parser/file_parser.py 2012-12-20 13:37:01 +0000
+++ account_statement_base_import/parser/file_parser.py 2013-02-26 08:28:21 +0000
@@ -17,8 +17,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
-
from openerp.tools.translate import _
+from openerp.osv.osv import except_osv
import tempfile
import datetime
from parser import BankStatementImportParser
@@ -34,12 +34,13 @@
Generic abstract class for defining parser for .csv or .xls file format.
"""
- def __init__(self, parse_name, keys_to_validate=[], ftype='csv', convertion_dict=None, header=None, *args, **kwargs):
+ def __init__(self, parse_name, keys_to_validate=None, ftype='csv', conversion_dict=None,
+ header=None, *args, **kwargs):
"""
:param char: parse_name : The name of the parser
:param list: keys_to_validate : contain the key that need to be present in the file
:param char ftype: extension of the file (could be csv or xls)
- :param: convertion_dict : keys and type to convert of every column in the file like
+ :param: conversion_dict : keys and type to convert of every column in the file like
{
'ref': unicode,
'label': unicode,
@@ -54,9 +55,10 @@
if ftype in ('csv', 'xls'):
self.ftype = ftype
else:
- raise Exception(_('Invalide file type %s. please use csv or xls') % (ftype))
- self.keys_to_validate = keys_to_validate
- self.convertion_dict = convertion_dict
+ raise except_osv(_('User Error'),
+ _('Invalid file type %s. Please use csv or xls') % ftype)
+ self.keys_to_validate = keys_to_validate if keys_to_validate is not None else []
+ self.conversion_dict = conversion_dict
self.fieldnames = header
self._datemode = 0 # used only for xls documents,
# 0 means Windows mode (1900 based dates).
@@ -99,7 +101,8 @@
parsed_cols = self.result_row_list[0].keys()
for col in self.keys_to_validate:
if col not in parsed_cols:
- raise Exception(_('Column %s not present in file') % (col))
+ raise except_osv(_('Invalid data'),
+ _('Column %s not present in file') % col)
return True
def _post(self, *args, **kwargs):
@@ -128,17 +131,13 @@
wb_file.write(self.filebuffer)
# We ensure that cursor is at beginig of file
wb_file.seek(0)
- wb = xlrd.open_workbook(wb_file.name)
- self._datemode = wb.datemode
- sheet = wb.sheet_by_index(0)
- header = sheet.row_values(0)
- res = []
- for rownum in range(1, sheet.nrows):
- res.append(dict(zip(header, sheet.row_values(rownum))))
- try:
- wb_file.close()
- except Exception, e:
- pass # file is already closed
+ with xlrd.open_workbook(wb_file.name) as wb:
+ self._datemode = wb.datemode
+ sheet = wb.sheet_by_index(0)
+ header = sheet.row_values(0)
+ res = []
+ for rownum in range(1, sheet.nrows):
+ res.append(dict(zip(header, sheet.row_values(rownum))))
return res
def _from_csv(self, result_set, conversion_rules):
@@ -149,11 +148,30 @@
for line in result_set:
for rule in conversion_rules:
if conversion_rules[rule] == datetime.datetime:
- date_string = line[rule].split(' ')[0]
- line[rule] = datetime.datetime.strptime(date_string,
- '%Y-%m-%d')
+ try:
+ date_string = line[rule].split(' ')[0]
+ line[rule] = datetime.datetime.strptime(date_string,
+ '%Y-%m-%d')
+ except ValueError as err:
+ raise except_osv(_("Date format is not valid."),
+ _(" It should be YYYY-MM-DD for column: %s"
+ " value: %s \n \n"
+ " \n Please check the line with ref: %s"
+ " \n \n Detail: %s") % (rule,
+ line.get(rule, _('Missing')),
+ line.get('ref', line),
+ repr(err)))
else:
- line[rule] = conversion_rules[rule](line[rule])
+ try:
+ line[rule] = conversion_rules[rule](line[rule])
+ except Exception as err:
+ raise except_osv(_('Invalid data'),
+ _("Value %s of column %s is not valid."
+ "\n Please check the line with ref %s:"
+ "\n \n Detail: %s") % (line.get(rule, _('Missing')),
+ rule,
+ line.get('ref', line),
+ repr(err)))
return result_set
def _from_xls(self, result_set, conversion_rules):
@@ -164,17 +182,37 @@
for line in result_set:
for rule in conversion_rules:
if conversion_rules[rule] == datetime.datetime:
- t_tuple = xlrd.xldate_as_tuple(line[rule], self._datemode)
- line[rule] = datetime.datetime(*t_tuple)
+ try:
+ t_tuple = xlrd.xldate_as_tuple(line[rule], self._datemode)
+ line[rule] = datetime.datetime(*t_tuple)
+ except Exception as err:
+ raise except_osv(_("Date format is not valid"),
+ _("Please modify the cell formatting to date format"
+ " for column: %s"
+ " value: %s"
+ "\n Please check the line with ref: %s"
+ "\n \n Detail: %s") % (rule,
+ line.get(rule, _('Missing')),
+ line.get('ref', line),
+ repr(err)))
else:
- line[rule] = conversion_rules[rule](line[rule])
+ try:
+ line[rule] = conversion_rules[rule](line[rule])
+ except Exception as err:
+ raise except_osv(_('Invalid data'),
+ _("Value %s of column %s is not valid."
+ "\n Please check the line with ref %s:"
+ "\n \n Detail: %s") % (line.get(rule, _('Missing')),
+ rule,
+ line.get('ref', line),
+ repr(err)))
return result_set
def _cast_rows(self, *args, **kwargs):
"""
- Convert the self.result_row_list using the self.convertion_dict providen.
+ Convert the self.result_row_list using the self.conversion_dict providen.
We call here _from_xls or _from_csv depending on the self.ftype variable.
"""
func = getattr(self, '_from_%s' % self.ftype)
- res = func(self.result_row_list, self.convertion_dict)
+ res = func(self.result_row_list, self.conversion_dict)
return res
=== modified file 'account_statement_base_import/parser/generic_file_parser.py'
--- account_statement_base_import/parser/generic_file_parser.py 2012-12-20 13:37:01 +0000
+++ account_statement_base_import/parser/generic_file_parser.py 2013-02-26 08:28:21 +0000
@@ -29,6 +29,11 @@
except:
raise Exception(_('Please install python lib xlrd'))
+def float_or_zero(val):
+ """ Conversion function used to manage
+ empty string into float usecase"""
+ return float(val) if val else 0.0
+
class GenericFileParser(FileParser):
"""
@@ -38,16 +43,16 @@
"""
def __init__(self, parse_name, ftype='csv'):
- convertion_dict = {
+ conversion_dict = {
'ref': unicode,
'label': unicode,
'date': datetime.datetime,
- 'amount': float,
- 'commission_amount': float
+ 'amount': float_or_zero,
+ 'commission_amount': float_or_zero
}
# Order of cols does not matter but first row of the file has to be header
keys_to_validate = ['ref', 'label', 'date', 'amount', 'commission_amount']
- super(GenericFileParser, self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, convertion_dict=convertion_dict)
+ super(GenericFileParser, self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, conversion_dict=conversion_dict)
@classmethod
def parser_for(cls, parser_name):
=== modified file 'account_statement_transactionid_import/parser/transactionid_file_parser.py'
--- account_statement_transactionid_import/parser/transactionid_file_parser.py 2012-12-20 13:37:01 +0000
+++ account_statement_transactionid_import/parser/transactionid_file_parser.py 2013-02-26 08:28:21 +0000
@@ -30,7 +30,7 @@
"""
def __init__(self, parse_name, ftype='csv'):
- convertion_dict = {
+ conversion_dict = {
'transaction_id': unicode,
'label': unicode,
'date': datetime.datetime,
@@ -39,7 +39,8 @@
}
# Order of cols does not matter but first row of the file has to be header
keys_to_validate = ['transaction_id', 'label', 'date', 'amount', 'commission_amount']
- super(TransactionIDFileParser, self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, convertion_dict=convertion_dict)
+ super(TransactionIDFileParser, self).__init__(parse_name, keys_to_validate=keys_to_validate,
+ ftype=ftype, conversion_dict=conversion_dict)
@classmethod
def parser_for(cls, parser_name):
Follow ups