Skip to content

Commit 4f948cd

Browse files
committed
start to parse the subcontent of 05 line
1 parent 0934643 commit 4f948cd

File tree

2 files changed

+110
-14
lines changed

2 files changed

+110
-14
lines changed

cfonb/parser/common.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def __init__(self, **entries):
4444
self.__dict__.update(entries)
4545

4646

47-
class Row(object):
47+
class Row(dict):
4848
"""Generic row object to manage bank file parsing, compare and reading.
4949
"""
5050

@@ -61,14 +61,13 @@ def __init__(self, re, keys, line):
6161
if match is None:
6262
raise ParsingError('line is invalid: "%s"' % line)
6363
else:
64-
self.__dict__ = dict(zip(keys, list(match.groups())))
64+
self.update(dict(zip(keys, list(match.groups()))))
6565

66-
def __getitem__(self, attr):
67-
return getattr(self, attr)
68-
69-
def __setitem__(self, attr, value):
70-
return setattr(self, attr, value)
66+
def __getattr__(self, attr):
67+
return self[attr]
7168

69+
def __setattr__(self, attr, value):
70+
self[attr] = value
7271

7372
def parse_amount(amount_str, nb_of_dec):
7473
""" return a numerical amount from the cfonb amount string

cfonb/parser/statement.py

Lines changed: 104 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# python import
22
import re
3-
3+
from collections import OrderedDict
44
# cfonb import
55
from cfonb import parser
66

@@ -128,9 +128,81 @@
128128
'_3',
129129
]
130130

131+
# http://www.cfonb.org/Web/cfonb/cfonbmain.nsf/DocumentsByIDWeb/7JSHS5/$File/7-8%20Evolution%20Releve%20Comptes%20120%20caracteres%20operations%20virement%20et%20prelevement%20sepa%20V2_0_2010_03.pdf
132+
ADDITIONAL_INFO = {
133+
"NPY": OrderedDict([
134+
('debtor_name', parser.G_ALL %70),
135+
]),
136+
"IPY": OrderedDict([
137+
('debtor_id', parser.G_ALL %35),
138+
('debtor_id_type', parser.G_ALL %35),
139+
]),
140+
"NBE": OrderedDict([
141+
('creditor_name', parser.G_ALL %70),
142+
]),
143+
"IBE": OrderedDict([
144+
('creditor_id', parser.G_ALL %35),
145+
('creditor_id_type', parser.G_ALL %35),
146+
]),
147+
"NPO": OrderedDict([
148+
('ultimate_debtor_name', parser.G_ALL %70),
149+
]),
150+
"IPO": OrderedDict([
151+
('ultimate_debtor_id', parser.G_ALL %35),
152+
('ultimate_debtor_type', parser.G_ALL %35),
153+
]),
154+
"NBU": OrderedDict([
155+
('ultimate_creditor_name', parser.G_ALL %70),
156+
]),
157+
"IBU": OrderedDict([
158+
('ultimate_creditor_id', parser.G_ALL %35),
159+
('ultimate_creditor_type', parser.G_ALL %35),
160+
]),
161+
"LCC": OrderedDict([
162+
('remittance_information_1', parser.G_ALL %70),
163+
]),
164+
"LC2": OrderedDict([
165+
('remittance_information_2', parser.G_ALL %70),
166+
]),
167+
"LCS": OrderedDict([
168+
('creditor_ref_information', parser.G_ALL %70),
169+
]),
170+
"RCN": OrderedDict([
171+
('end2end_identification', parser.G_ALL %35),
172+
('purpose', parser.G_ALL %35),
173+
]),
174+
"RCN": OrderedDict([
175+
('payment_infor_id', parser.G_ALL %35),
176+
('instruction_id', parser.G_ALL %35),
177+
]),
178+
179+
#Specific to bank transfers
180+
"MMO": OrderedDict([
181+
('currency_code', parser.G_AN %3),
182+
('nb_of_dec_amount', parser.G_N %1),
183+
('equivalent_amount', parser.G_N_ %14),
184+
('nb_of_dec_exchange_rate', parser.G_N_ %2),
185+
('exchange_rate', parser.G_N_ %11),
186+
('_', parser.G_AN_ %39)
187+
]),
188+
"CBE": OrderedDict([
189+
('creditor_account', parser.G_ALL %70),
190+
]),
131191

132192

133-
193+
#specific to withdrawal
194+
# TODO FIXME it's look like there is something wrong in
195+
# confb norme indeed 35+4 != 70 and 35 != 70 :S outch!
196+
# "RUM": OrderedDict([
197+
# ('mandate_identification', parser.G_ALL %35),
198+
# ('sequence_type', parser.G_ALL %4),
199+
# ]),
200+
# "CPY": OrderedDict([
201+
# ('debtor_account', parser.G_ALL %35),
202+
# ]),
203+
#
204+
}
205+
134206
FOOT_RE = re.compile(
135207
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$'
136208
% {
@@ -191,14 +263,39 @@ def parse_content_4(self, line):
191263
# return initialized row
192264
return row
193265

194-
def parse_content_5(self, line):
266+
def parser_sub_content_5(self, row):
267+
regex = r''
268+
keys = []
269+
for key, value in ADDITIONAL_INFO[row.qualifier].iteritems():
270+
regex += value
271+
keys += [key]
272+
reg = re.compile(regex + r'$')
273+
match = reg.match(row.additional_info)
274+
# re check
275+
if match is None:
276+
import pdb; pdb.set_trace()
277+
raise parser.ParsingError('line is invalid: "%s"' % row.additional_info)
278+
else:
279+
res = dict(zip(keys, list(match.groups())))
280+
import pdb; pdb.set_trace()
281+
return res
282+
283+
def parse_content_5(self, previous_row, line):
195284
"""NOT TESTED
196285
"""
197286
# init row
198287
row = parser.Row(CONTENT_5_RE, CONTENT_5_KEYS, line)
199288
# return initialized row
200-
return row
201-
289+
if row.qualifier == 'LIB':
290+
index = 0
291+
while True:
292+
index += 1
293+
if not previous_row.get('LIB_%s'%index):
294+
previous_row['LIB_%s'%index] = row.additional_info.strip()
295+
break
296+
else:
297+
previous_row.update(self.parser_sub_content_5(row))
298+
#return sub_content
202299

203300
def parse(self, file_obj):
204301
file_lines = file_obj.readlines()
@@ -211,12 +308,12 @@ def parse(self, file_obj):
211308
# parse line
212309
if CONTENT_4_RE.match(line):
213310
row = self.parse_content_4(line)
311+
self.lines.append(row)
214312
elif CONTENT_5_RE.match(line):
215-
row = self.parse_content_5(line)
313+
self.parse_content_5(row, line)
216314
else:
217315
if line[0:2] in ['01', '07']:#we don't take care of subtotal
218316
continue
219317
else:
220318
raise parser.ParsingError('line %s is invalid: "%s"' % (index, line))
221319
# update content
222-
self.lines.append(row)

0 commit comments

Comments
 (0)