Skip to content

Commit 6b83706

Browse files
committed
[REF] refactor statement reader in order to support multi statement in one file
1 parent f448e50 commit 6b83706

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

README.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ You can read a statement like this::
2424

2525
>>> from os.path import join
2626
>>> statement_file = open(join('cfonb', 'tests', 'bank_statement.cfo'))
27-
>>> from cfonb.parser.statement import Statement
28-
>>> statement = Statement()
29-
>>> statement.parse(statement_file)
27+
>>> from cfonb import StatementReader
28+
>>> reader = StatementReader()
29+
>>> result = reader.parse(statement_file)
30+
>>> statement = result[0]
3031

3132
The statement has a header and a footer, which are both statement rows::
3233

cfonb/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
#
2+
from parser.statement import StatementReader

cfonb/parser/statement.py

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,39 @@
22
from cfonb.parser import Row, ParsingError
33

44

5-
class Statement(object):
6-
"""Satement file parser and container. Parse file object to corresponding
5+
6+
7+
class StatementReader(object):
8+
"""Statement file parser. Parse file object to corresponding
79
row objects for further use. Offers useful method for reading, writing and
810
comparing issues.
911
"""
1012

11-
def __init__(self):
12-
self.header = None
13-
self.footer = None
14-
self.lines = list()
15-
1613
def parse(self, file_obj):
17-
file_lines = file_obj.readlines()
18-
# header and footer
19-
self.header = Row(file_lines.pop(0))
20-
self.footer = Row(file_lines.pop())
14+
""" Parser a file object and return the list of bank statement
15+
extracted from the file"""
2116

22-
if file_lines[0][0:2] != '04':
23-
raise ParserError('the first line after the header must be a'
24-
'04 line. This line is invalid %s'%file_lines[0])
17+
file_lines = file_obj.readlines()
2518
# content
19+
result = {}
2620
for index, line in enumerate(file_lines):
27-
# parse line
28-
if line[0:2] == '04':
21+
22+
if line[0:2] == '01':
23+
row = Row(line)
24+
25+
#If a statement already exist for the same account
26+
#we updated it else we create a new own
27+
if result.get(row.account_nb):
28+
statement = result[row.account_nb]
29+
else:
30+
statement = Statement()
31+
result[row.account_nb] = statement
32+
statement.header = row
33+
34+
elif line[0:2] == '04':
2935
row = Row(line)
30-
self.lines.append(row)
36+
statement.lines.append(row)
37+
3138
elif line[0:2] == '05':
3239
new_row = Row(line)
3340
if new_row.get('label') and row.get('label'):
@@ -39,8 +46,21 @@ def parse(self, file_obj):
3946
break
4047
else:
4148
row.update(new_row)
49+
50+
elif line[0:2] == '07':
51+
statement.footer = Row(line)
4252
else:
43-
if line[0:2] in ['01', '07']:#we don't take care of subtotal
44-
continue
45-
else:
46-
raise ParsingError('line %s is invalid: "%s"' % (index, line))
53+
raise ParsingError('line %s is invalid: "%s"' % (index, line))
54+
55+
56+
57+
return [result[key] for key in result]
58+
59+
class Statement(object):
60+
61+
def __init__(self):
62+
self.header = None
63+
self.footer = None
64+
self.lines = list()
65+
66+

0 commit comments

Comments
 (0)