66
77
88HEAD_RE = re.compile(
9- r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s$'
9+ r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s\n $'
1010 % {
1111 'a': '(01)', # record code
1212 'b': parser.G_N % 5, # bank code
5959 ]
6060
6161
62- def parse_head(line):
63- # init row
64- row = parser.Row()
65- # set row data
66- row.parse(HEAD_RE, HEAD_KEYS, line)
67- # return initialized row
68- return row
69-
70-
7162CONTENT_4_RE = re.compile(
72- r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s%(n)s%(o)s%(p)s%(q)s%(r)s%(s)s$'
63+ r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s%(n)s%(o)s%(p)s%(q)s%(r)s%(s)s\n $'
7364 % {
7465 'a': '(04)', # record code
7566 'b': parser.G_N % 5, # bank code
@@ -83,9 +74,10 @@ def parse_head(line):
8374 'j': parser.G_N % 6, # operation date
8475 'k': parser.G_N_ % 2, # reject code
8576 'l': parser.G_N % 6, # value date
86- 'm': parser.G_AN_ % 31, # label
77+ 'm': parser.G_ALL % 31, # label
8778 'n': parser.G_AN_ % 2, # _
88- 'o': parser.G_N % 7, # reference
79+ 'o': parser.G_AN % 7, # reference in CFONB norme it's G_N
80+ # but in the real world it's an G_AN
8981 'p': parser.G_AN_ % 1, # exempt code
9082 'q': parser.G_AN_ % 1, # _
9183 'r': parser.G_AMT, # amount
@@ -140,31 +132,23 @@ def parse_head(line):
140132 ]
141133
142134
143- def parse_content_4(line):
144- # init row
145- row = parser.Row()
146- # set row data
147- row.parse(CONTENT_4_RE, CONTENT_4_KEYS, line)
148- # return initialized row
149- return row
150-
151135
152136CONTENT_5_RE = re.compile(
153- r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s%(n)s$'
137+ r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s%(n)s\n $'
154138 % {
155139 'a': '(05)', # record code
156140 'b': parser.G_N % 5, # bank code
157141 'c': parser.G_AN % 4, # internal code
158142 'd': parser.G_N % 5, # desk code
159143 'e': parser.G_A_ % 3, # currency code
160144 'f': parser.G_N_ % 1, # nb of decimal
161- 'g': parser.G__ % 1, # _
145+ 'g': parser.G_AN_ % 1, # _
162146 'h': parser.G_AN % 11, # account nb
163147 'i': parser.G_AN % 2, # operation code
164148 'j': parser.G_N % 6, # operation date
165149 'k': parser.G__ % 5, # _
166150 'l': parser.G_AN % 3, # qualifier
167- 'm': parser.G_AN % 70, # additional info
151+ 'm': parser.G_ALL % 70, # additional info
168152 'n': parser.G__ % 2, # _
169153 }
170154 )
@@ -206,20 +190,10 @@ def parse_content_4(line):
206190 ]
207191
208192
209- def parse_content_5(line):
210- """NOT TESTED
211- """
212- # init row
213- row = parser.Row()
214- # set row data
215- row.parse(CONTENT_5_RE, CONTENT_5_KEYS, line)
216- # return initialized row
217- return row
218-
219193
220194
221195FOOT_RE = re.compile(
222- r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s$'
196+ r'^%(a)s%(b)s%(c)s%(d)s%(e)s%(f)s%(g)s%(h)s%(i)s%(j)s%(k)s%(l)s%(m)s\n $'
223197 % {
224198 'a': '(07)', # record code
225199 'b': parser.G_N % 5, # bank code
@@ -272,14 +246,6 @@ def parse_content_5(line):
272246 ]
273247
274248
275- def parse_footer(line):
276- # init row
277- row = parser.Row()
278- # set row data
279- row.parse(FOOT_RE, FOOT_KEYS, line)
280- # return initialized row
281- return row
282-
283249
284250class Statement(object):
285251 """Satement file parser and container. Parse file object to corresponding
@@ -292,25 +258,44 @@ def __init__(self):
292258 self.footer = None
293259 self.lines = list()
294260
261+ def parse_header(self, line):
262+ self.header = parser.Row(HEAD_RE, HEAD_KEYS, line)
263+
264+ def parse_footer(self, line):
265+ self.footer = parser.Row(FOOT_RE, FOOT_KEYS, line)
266+
267+ def parse_content_4(self, line):
268+ # init row
269+ row = parser.Row(CONTENT_4_RE, CONTENT_4_KEYS, line)
270+ # return initialized row
271+ return row
272+
273+ def parse_content_5(self, line):
274+ """NOT TESTED
275+ """
276+ # init row
277+ row = parser.Row(CONTENT_5_RE, CONTENT_5_KEYS, line)
278+ # return initialized row
279+ return row
280+
281+
295282 def parse(self, file_obj):
296283 file_lines = file_obj.readlines()
297284 # header and footer
298- self.header = parser.Row()
299- self.header.parse(HEAD_RE, HEAD_KEYS, file_lines[0])
300- self.footer = parser.Row()
301- self.footer.parse(FOOT_RE, FOOT_KEYS, file_lines[-1])
285+ self.parse_header(file_lines.pop(0))
286+ self.parse_footer(file_lines.pop())
287+
302288 # content
303- for i, l in enumerate(file_lines[1:-1] ):
289+ for index, line in enumerate(file_lines):
304290 # parse line
305- row = parser.Row()
306- if CONTENT_4_RE.match(l):
307- row.parse(CONTENT_4_RE, CONTENT_4_KEYS, l, line_nb=i)
308- elif CONTENT_5_RE.match(l):
309- row.parse(CONTENT_5_RE, CONTENT_5_KEYS, l, line_nb=i)
291+ if CONTENT_4_RE.match(line):
292+ row = self.parse_content_4(line)
293+ elif CONTENT_5_RE.match(line):
294+ row = self.parse_content_5(line)
310295 else:
311- raise parser.ParsingError('line %s is invalid: "%s"' % (i, l))
296+ if line[0:2] in ['01', '07']:#we don't take care of subtotal
297+ continue
298+ else:
299+ raise parser.ParsingError('line %s is invalid: "%s"' % (index, line))
312300 # update content
313301 self.lines.append(row)
314-
315-
316-
0 commit comments