11# python import
22import re
3-
3+ from collections import OrderedDict
44# cfonb import
55from cfonb import parser
66
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+
134206FOOT_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