Merge lp:~gs.clearcorp/openerp-costa-rica/7.0_l10n_cr_account_banking into lp:openerp-costa-rica

Proposed by Glen Sojo
Status: Merged
Merged at revision: 252
Proposed branch: lp:~gs.clearcorp/openerp-costa-rica/7.0_l10n_cr_account_banking
Merge into: lp:openerp-costa-rica
Diff against target: 823 lines (+803/-0)
4 files modified
l10n_cr_account_banking_cr_bcr/__init__.py (+24/-0)
l10n_cr_account_banking_cr_bcr/__openerp__.py (+39/-0)
l10n_cr_account_banking_cr_bcr/bcr_format.py (+181/-0)
l10n_cr_account_banking_cr_bcr/bcr_parser.py (+559/-0)
To merge this branch: bzr merge lp:~gs.clearcorp/openerp-costa-rica/7.0_l10n_cr_account_banking
Reviewer Review Type Date Requested Status
ClearCorp drivers Pending
Review via email: mp+197215@code.launchpad.net

Description of the change

[ADD] New module l10n_cr_account_banking_cr_bcr intended to read and parse bank statements files for a the module account_banking_ccorp from openerp-ccorp-addons

To post a comment you must log in.
252. By Ronald Rubi

[MRG] New module l10n_cr_account_banking_cr_bcr intended to read and parse bank statements files for a the module account_banking_ccorp from openerp-ccorp-addons

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'l10n_cr_account_banking_cr_bcr'
2=== added file 'l10n_cr_account_banking_cr_bcr/__init__.py'
3--- l10n_cr_account_banking_cr_bcr/__init__.py 1970-01-01 00:00:00 +0000
4+++ l10n_cr_account_banking_cr_bcr/__init__.py 2013-11-29 14:49:44 +0000
5@@ -0,0 +1,24 @@
6+# -*- encoding: utf-8 -*-
7+##############################################################################
8+#
9+# Copyright (C) 2011 credativ Ltd (<http://www.credativ.co.uk>).
10+# All Rights Reserved
11+#
12+# This program is free software: you can redistribute it and/or modify
13+# it under the terms of the GNU Affero General Public License as
14+# published by the Free Software Foundation, either version 3 of the
15+# License, or (at your option) any later version.
16+#
17+# This program is distributed in the hope that it will be useful,
18+# but WITHOUT ANY WARRANTY; without even the implied warranty of
19+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+# GNU Affero General Public License for more details.
21+#
22+# You should have received a copy of the GNU Affero General Public License
23+# along with this program. If not, see <http://www.gnu.org/licenses/>.
24+#
25+##############################################################################
26+
27+import bcr_format
28+
29+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
30
31=== added file 'l10n_cr_account_banking_cr_bcr/__openerp__.py'
32--- l10n_cr_account_banking_cr_bcr/__openerp__.py 1970-01-01 00:00:00 +0000
33+++ l10n_cr_account_banking_cr_bcr/__openerp__.py 2013-11-29 14:49:44 +0000
34@@ -0,0 +1,39 @@
35+# -*- coding: utf-8 -*-
36+##############################################################################
37+#
38+# OpenERP, Open Source Management Solution
39+# Addons modules by CLEARCORP S.A.
40+# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
41+#
42+# This program is free software: you can redistribute it and/or modify
43+# it under the terms of the GNU Affero General Public License as
44+# published by the Free Software Foundation, either version 3 of the
45+# License, or (at your option) any later version.
46+#
47+# This program is distributed in the hope that it will be useful,
48+# but WITHOUT ANY WARRANTY; without even the implied warranty of
49+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+# GNU Affero General Public License for more details.
51+#
52+# You should have received a copy of the GNU Affero General Public License
53+# along with this program. If not, see <http://www.gnu.org/licenses/>.
54+#
55+##############################################################################
56+
57+{
58+ 'name': 'BCR Account Banking',
59+ 'version': '0.1',
60+ 'license': 'AGPL-3',
61+ 'author': 'CLEARCORP S.A.',
62+ 'website': 'http://www.clearcorp.co.cr',
63+ 'category': 'Accounting & Finance',
64+ 'depends': [
65+ 'account_banking_ccorp',
66+ ],
67+ 'init_xml': [],
68+ 'update_xml': [],
69+ 'demo_xml': [],
70+ 'description': '',
71+ 'active': False,
72+ 'installable': True,
73+}
74
75=== added file 'l10n_cr_account_banking_cr_bcr/bcr_format.py'
76--- l10n_cr_account_banking_cr_bcr/bcr_format.py 1970-01-01 00:00:00 +0000
77+++ l10n_cr_account_banking_cr_bcr/bcr_format.py 2013-11-29 14:49:44 +0000
78@@ -0,0 +1,181 @@
79+# -*- coding: utf-8 -*-
80+##############################################################################
81+#
82+# OpenERP, Open Source Management Solution
83+# Addons modules by CLEARCORP S.A.
84+# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
85+#
86+# This program is free software: you can redistribute it and/or modify
87+# it under the terms of the GNU Affero General Public License as
88+# published by the Free Software Foundation, either version 3 of the
89+# License, or (at your option) any later version.
90+#
91+# This program is distributed in the hope that it will be useful,
92+# but WITHOUT ANY WARRANTY; without even the implied warranty of
93+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
94+# GNU Affero General Public License for more details.
95+#
96+# You should have received a copy of the GNU Affero General Public License
97+# along with this program. If not, see <http://www.gnu.org/licenses/>.
98+#
99+##############################################################################
100+
101+from account_banking_ccorp.parsers import models
102+from openerp.tools.translate import _
103+from bcr_parser import BCRParser
104+import re
105+from openerp.osv import osv, fields
106+import logging
107+import pprint
108+from datetime import datetime
109+import base64
110+
111+bt = models.mem_bank_transaction
112+logger = logging.getLogger( 'bcr_mt940' )
113+
114+def record2float(record, value):
115+ if record == 'C':
116+ return float (value)
117+ else:
118+ return -float(value)
119+
120+class transaction(models.mem_bank_transaction):
121+
122+ mapping = {
123+ 'execution_date' : '',
124+ 'effective_date' : '',
125+ 'local_currency' : '',
126+ 'transfer_type' : '',
127+ 'reference' : '',
128+ 'message' : '',
129+ 'name' : '',
130+ 'amount': '',
131+ 'creditmarker': '',
132+ }
133+
134+ def __init__(self, record, *args, **kwargs):
135+
136+ '''
137+ Transaction creation
138+ '''
139+ super(transaction, self).__init__(*args, **kwargs)
140+ #for r in record:
141+ for key, value in record.iteritems():
142+ if record.has_key(key):
143+ setattr(self, key, record[key])
144+
145+ if not self.is_valid():
146+ logger.info("Invalid: %s", record)
147+
148+ def is_valid(self):
149+ '''
150+ We don't have remote_account so override base
151+ '''
152+ return (self.execution_date
153+ and self.transferred_amount and True) or False
154+
155+class statement(models.mem_bank_statement):
156+ '''
157+ Bank statement imported data '''
158+
159+ def _transmission_number(self, record):
160+ self.id = record['transref']
161+
162+ def _account_number(self, record):
163+ self.local_account = record['account_number']
164+
165+ def _statement_number(self, record):
166+ self.id = record['id']
167+
168+ def _opening_balance(self, record):
169+ self.start_balance = float(record['startingbalance'])
170+ self.local_currency = record['currencycode']
171+
172+ def _closing_balance(self, record):
173+ self.end_balance = float(record['endingbalance'])
174+ self.date = record['bookingdate']
175+
176+ def _transaction_new(self, record):
177+ parser = BCRParser()
178+ sub_record = parser.statement_lines(record) #dictionary
179+ for sub in sub_record:
180+ self.transactions.append(transaction(sub))
181+
182+ def _not_used():
183+ logger.info("Didn't use record: %s", record)
184+
185+ def _forward_available(self, record):
186+ self.end_balance = float(record['endingbalance'])
187+ self.date = record['bookingdate']
188+
189+ def _execution_date_transferred_amount (self, record):
190+ self.execution_date = record['bookingdate']
191+ self.transferred_amount = float(record['ammount'])
192+
193+ def transaction_info(self, record):
194+ '''
195+ Add extra information to transaction
196+ '''
197+ # Additional information for previous transaction
198+ if len(self.transactions) < 1:
199+ logger.info("Received additional information for non existent transaction:")
200+ logger.info(record)
201+ else:
202+ transaction = self.transactions[-1]
203+ transaction.id = ','.join([record[k] for k in ['infoline{0}'.format(i) for i in range(2,5)] if record.has_key(k)])
204+
205+def raise_error(message, line):
206+ raise osv.osv.except_osv(_('Import error'),
207+ 'Error in import:%s\n\n%s' % (message, line))
208+
209+class parser_bcr_mt940( models.parser ):
210+ code = 'BCR-MT940'
211+ name = _( 'BCR statement import' )
212+ country_code = 'CR'
213+ doc = _('''\
214+ This format is available through
215+ the BCR web interface.
216+ ''')
217+
218+ def parse(self, cr, statements_file, **kwargs):
219+
220+ '''
221+ ** Kwargs parameter is used for a dynamic list of parameters.
222+ The wizard imported extracts used in all parsers and not all parsers have all the necessary information in your file,
223+ so get information from the wizard and passed by the ** kwargs.
224+ Then in the parses that are needed, are extracted from the ** kwargs and if needed,
225+ the parser still works the same way without this parameter.
226+
227+ The rest of the methods must receive this parameter. (As the method that parse the header and the lines).
228+ '''
229+
230+ result = []
231+ parser = BCRParser()
232+ stmnt = statement()
233+
234+ """
235+ **kwargs have all the parameters that have the wizard and
236+ has all the parameters passed from the wizard before calling
237+ the method that parses the file.
238+ """
239+
240+ #pass to encoding with the correct type of file.
241+ data = base64.decodestring(statements_file)
242+
243+ records = parser.parse_stamenent_record(data,**kwargs)
244+
245+ stmnt._transmission_number(records)
246+ stmnt._account_number(records)
247+ stmnt._statement_number(records)
248+ stmnt._opening_balance(records)
249+ stmnt._closing_balance(records)
250+ stmnt._forward_available(records)
251+ stmnt._execution_date_transferred_amount (records)
252+ stmnt._transaction_new(data)
253+
254+ if stmnt.is_valid():
255+ result.append(stmnt)
256+
257+ return result
258+
259+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
260
261=== added file 'l10n_cr_account_banking_cr_bcr/bcr_parser.py'
262--- l10n_cr_account_banking_cr_bcr/bcr_parser.py 1970-01-01 00:00:00 +0000
263+++ l10n_cr_account_banking_cr_bcr/bcr_parser.py 2013-11-29 14:49:44 +0000
264@@ -0,0 +1,559 @@
265+# -*- coding: utf-8 -*-
266+##############################################################################
267+#
268+# OpenERP, Open Source Management Solution
269+# Addons modules by CLEARCORP S.A.
270+# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
271+#
272+# This program is free software: you can redistribute it and/or modify
273+# it under the terms of the GNU Affero General Public License as
274+# published by the Free Software Foundation, either version 3 of the
275+# License, or (at your option) any later version.
276+#
277+# This program is distributed in the hope that it will be useful,
278+# but WITHOUT ANY WARRANTY; without even the implied warranty of
279+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
280+# GNU Affero General Public License for more details.
281+#
282+# You should have received a copy of the GNU Affero General Public License
283+# along with this program. If not, see <http://www.gnu.org/licenses/>.
284+#
285+##############################################################################
286+"""
287+Parser for BCR format files
288+"""
289+import re
290+from datetime import datetime
291+from dateutil import parser
292+from pprint import PrettyPrinter
293+from copy import copy
294+from openerp.tools.translate import _
295+from openerp.osv import osv, fields
296+
297+class BCRParser( object ):
298+ """
299+ Para noviembre de 2012 se cambia el formato del archivo del BCR. Se cambia el encabezado del archivo
300+ así como el final del mismo. Además en la parte de abajo cambia el formato y visualización de los
301+ saldos finales.
302+
303+ El cambio más evidente es el formato de la cuenta de banco, pasa de 1-246447-0 a 001-0246447-0
304+ Revisión # 1 Revisión#2
305+ Encabezado anterior: Encabezado nuevo
306+ BANCO DE COSTA RICA BANCO DE COSTA RICA
307+ Movimiento de Cuenta Corriente 1-246447-0 Colones (puede ser Dólares o Dolares) MOVIMIENTO DE LA CUENTA CORRIENTE No. 001-0246447-0 COLONES (DOLARES)
308+ Dueño: COMPA IA INMOBILIARIA CENTROA DUENO: COMPA IA INMOBILIARIA CENTROAMERICANA CICCR S
309+ Movimiento realizado el periodo del 01-10-2012 al 31-10-2012 MOVIMIENTO REALIZADO DEL 01-11-2012 AL 30-11-2012
310+
311+ Final de archivo
312+ Revisión # 1 Revisión #2
313+ TOTALES DEL MOVIMIENTO CONTABILIZADO TOTALES DEL MOVIMIENTO CONTABILIZADO
314+ Cantidad -------Monto-------- CANTIDAD -------MONTO--------
315+ Débitos 239 81,876,681.22 DEBITOS 209 67,553,414.30
316+ Créditos 27 92,636,599.01 CREDITOS 8 66,086,326.53
317+
318+ Saldo Inicial 21,682,799.04 -------- SALDOS --------
319+ Saldo Final 33,992,829.43 INICIAL 33,992,829.43
320+ FINAL 32,525,741.66
321+ Solicitado el 01/11/2012 20:03:34 SOLICITADO EL 01-12-2012 A LAS 15:36:15:17
322+ """
323+ def statement_record ( self, rec, **kwargs):
324+ lines = []
325+ line_dict = {}
326+
327+ line_dict = {
328+ 'transref': 0.0, # _transmission_number
329+ 'account_number': '', #_account_number
330+ 'statementnr':'', # statement_number
331+ 'startingbalance': 0.0, #_opening_balance
332+ 'currencycode': 'CRC', #currencycode
333+ 'endingbalance': 0.0, #_closing_balance
334+ 'bookingdate': '', #moving_date
335+ 'ammount': 0.0,
336+ 'id': '',
337+ }
338+
339+ cad = ''
340+ list_split = rec.split('\r\n')
341+ account_number_wizard = kwargs['account_number']
342+
343+ #If return True, the account are the same.
344+ if self.match_account(list_split, account_number_wizard):
345+ for l in list_split:
346+ #_account_number -> FIRST REVISION
347+ if l.find('Movimiento de Cuenta Corriente', 0, len('Movimiento de Cuenta Corriente')) > -1:
348+ line_dict['account_number'] = self.extract_number(l)
349+
350+ if (l.find('D',0,len(l)) > -1):
351+ line_dict['currencycode'] = 'USD'
352+ else:
353+ line_dict['currencycode'] = 'CRC'
354+
355+ #_account_number -> SECOND REVISION
356+ elif (l.find('MOVIMIENTO DE LA CUENTA CORRIENTE No.', 0, len('MOVIMIENTO DE LA CUENTA CORRIENTE No.')) > -1):
357+ account_str = self.extract_number(l)
358+ #001-0246447-0
359+ account_1 = account_str[2:3] #1
360+ account_2 = account_str[4:] #246447-0
361+ account_complete = account_1+self.extract_number(account_2)#12464470
362+ line_dict['account_number'] = self.extract_number(account_complete)
363+ if (l.find('DOLARES',0,len(l)) > -1):
364+ line_dict['currencycode'] = 'USD'
365+ else:
366+ line_dict['currencycode'] = 'CRC'
367+
368+ # _transmission_number -> FIRST REVISION
369+ if (l.find('Movimiento realizado el periodo', 0, len('Movimiento realizado el periodo')) > -1):
370+ line_dict['statementnr'] = self.extract_number(l)
371+ date_1 = self.extract_date_regular_expresion_line_format_2(l,0)
372+ date_2 = self.extract_date_regular_expresion_line_format_2(l,1)
373+
374+ # _transmission_number -> SECOND REVISION
375+ elif (l.find('MOVIMIENTO REALIZADO', 0, len('MOVIMIENTO REALIZADO')) > -1):
376+ line_dict['statementnr'] = self.extract_number(l)
377+ date_1 = self.extract_date_regular_expresion_line_format_2(l,0)
378+ date_2 = self.extract_date_regular_expresion_line_format_2(l,1)
379+
380+ #date and hour -> FIRST REVISION
381+ if (l.find('Solicitado el', 0, len('Solicitado el')) > -1):
382+ date = hour = cad = ''
383+ date = self.extract_date_regular_expresion(l)
384+ if len(date) > 0:
385+ hour = self.extract_hour_regular_expresion(l)
386+ cad = date + ' ' + hour
387+ line_dict['transref'] = cad
388+ line_dict['bookingdate'] = cad
389+
390+ #date and hour -> SECOND REVISION
391+ elif (l.find('SOLICITADO EL', 0, len('SOLICITADO EL')) > -1):
392+ date = hour = cad = ''
393+ date = self.extract_date_regular_expresion(l)
394+ if len(date) > 0:
395+ hour = self.extract_hour_regular_expresion(l)
396+ cad = date + ' ' + hour
397+ line_dict['transref'] = cad
398+ line_dict['bookingdate'] = cad
399+
400+ #_opening_balance -> FIRST REVISION
401+ if l.find('Saldo Inicial', 0, len('Saldo Inicial')) > -1:
402+ line_dict['startingbalance'] = self.extract_float(l)
403+ #_opening_balance -> SECOND REVISION
404+ elif l.find('INICIAL', 0, len('INICIAL')) > -1:
405+ line_dict['startingbalance'] = self.extract_float(l)
406+
407+ #_closing_balance -> FIRST REVISION
408+ if l.find('FINAL', 0, len('FINAL')) > -1:
409+ line_dict['endingbalance'] = self.extract_float(l)
410+
411+ #_closing_balance -> SECOND REVISION
412+ elif l.find('Saldo Final', 0, len('Saldo Final')) > -1:
413+ line_dict['endingbalance'] = self.extract_float(l)
414+
415+ line_dict['ammount'] = float( line_dict['startingbalance'] ) + float( line_dict['endingbalance'] )
416+ line_dict['id'] = date_1 + ' - ' + date_2 + ' Extracto BCR ' + line_dict['account_number']
417+ self.line_dict = line_dict
418+
419+ return line_dict
420+
421+ else:
422+ raise osv.except_osv(_('Error'),
423+ _('Error en la importación! La cuenta especificada en el archivo no coincide con la seleccionada en el asistente de importacion'))
424+
425+ def statement_lines ( self, rec):
426+ parser = BCRParser()
427+ mapping = {
428+ 'execution_date' : '',
429+ 'effective_date' : '',
430+ 'local_currency' : '',
431+ 'transfer_type' : '',
432+ 'reference' : '',
433+ 'message' : '',
434+ 'name' : '',
435+ 'transferred_amount': '',
436+ 'creditmarker': '',
437+ }
438+ line_dict = {}
439+ currencycode = ''
440+
441+ list_split = rec.split('\r\n')
442+ entrada = False
443+ start = 0
444+ end = 0
445+ version = 'none'
446+
447+ #========= Start and end of lines ======#
448+ for l in list_split:
449+ if l.find('TOTALES DEL MOVIMIENTO CONTABILIZADO', 0, len('TOTALES DEL MOVIMIENTO CONTABILIZADO')) <= -1:
450+ end += 1
451+ else:
452+ break
453+ end = end - 1
454+
455+ for l in list_split:
456+ if l.find('-CONTABLE-', 0, len('-CONTABLE-')) <= -1:
457+ start += 1
458+ else:
459+ break
460+ start += 1
461+
462+ for l in list_split:
463+ if l.find('Movimiento de Cuenta Corriente', 0, len('Movimiento de Cuenta Corriente')) > -1:
464+ if (l.find('D',0,len(l)) > -1):
465+ currencycode = 'USD'
466+ else:
467+ currencycode = 'CRC'
468+ break
469+
470+ elif l.find('MOVIMIENTO DE LA CUENTA CORRIENTE No.', 0, len('MOVIMIENTO DE LA CUENTA CORRIENTE No.')) > -1:
471+ if (l.find('DOLARES',0,len(l)) > -1):
472+ currencycode = 'USD'
473+ else:
474+ currencycode = 'CRC'
475+ break
476+
477+ #========= VERSION OF THREE COLUMNS FOR DEBIT AND CREDIT =============#
478+ sub_list = list_split [start:end]
479+
480+ if len(sub_list) > 0:
481+ sub_first = sub_list[0] #Based in first line, decide which version it is
482+
483+ #1. Try separate by tab ('\t') (last version) (fields must have, at least, more than 1 of length)
484+ fields = sub_first.split('\t')
485+
486+ if len(fields) > 1:
487+ version = 'third_version'
488+
489+ #2. Find where start debit and credit columns
490+ else:
491+ amount = sub_first[106:]
492+ debit = amount[0:16]
493+
494+ debit = debit.replace(',','')
495+ debit = debit.replace('.','')
496+ debit = re.sub(r'\s', '', debit)
497+
498+ if re.match('^[0-9,.]*$', debit):
499+ version = 'first_version'
500+
501+ else:
502+ amount = sub_first[120:]
503+ debit = amount[0:40]
504+
505+ debit = debit.replace(',','')
506+ debit = debit.replace('.','')
507+ debit = re.sub(r'\s', '', debit)
508+
509+ if re.match('^[0-9,.]*$', debit):
510+ version = 'second_version'
511+
512+ #=====================================================================#
513+
514+ if version != 'none':
515+ if version =='first_version':
516+ return self.first_version_file(sub_list,mapping,currencycode,parser)
517+
518+ elif version == 'second_version':
519+ return self.second_version(sub_list,mapping,currencycode,parser)
520+
521+ elif version == 'third_version':
522+ return self.third_version(sub_list,mapping,currencycode,parser)
523+
524+ else:
525+ raise osv.except_osv(_('Error'),
526+ _('There is not format implementend for this file.'))
527+
528+ else:
529+ return []
530+
531+ def parse_stamenent_record( self, rec, **kwargs):
532+
533+ matchdict = dict()
534+
535+ matchdict = self.statement_record( rec, **kwargs );
536+
537+ # Remove members set to None
538+ matchdict = dict( [( k, v ) for k, v in matchdict.iteritems() if v] )
539+
540+ matchkeys = set( matchdict.keys() )
541+ needstrip = set( [ 'transref', 'account_number', 'statementnr', 'currencycode', 'endingbalance', 'bookingdate'] )
542+
543+ for field in matchkeys & needstrip:
544+ matchdict[field] = matchdict[field].strip()
545+
546+ # Convert to float. Comma is decimal separator
547+ needsfloat = set( ["startingbalance", "endingbalance", "amount"] )
548+ for field in matchkeys & needsfloat:
549+ matchdict[field] = float( matchdict[field].replace( ',', '.' ) )
550+
551+ # Convert date fields
552+ needdate = set( ["bookingdate"] )
553+
554+ for field in matchkeys & needdate:
555+ datestring = matchdict[field]
556+ date = self.extract_date_regular_expresion(datestring)
557+ hour = self.extract_hour_regular_expresion(datestring)
558+
559+ date_complete = date + ' ' + hour
560+ try:
561+ #FORMAT DATE REVISION # 1
562+ date_obj= datetime.strptime(date_complete, "%d/%m/%Y %H:%M:%S")
563+ except:
564+ #FORMAT DATE REVISION # 2
565+ date_obj= datetime.strptime(date_complete, "%d-%m-%Y %H:%M:%S")
566+ matchdict[field] = date_obj
567+
568+ return matchdict
569+
570+ #=============================Auxiliary methods =============================#
571+
572+ #=====================Versions of file
573+
574+ def first_version_file(self, sub_list,mapping,currencycode,parser):
575+ lines = []
576+ for sub in sub_list:
577+ #effective_date
578+ date_str = ''
579+ date_str = self.extract_date_regular_expresion_line(sub,0)
580+ date= datetime.strptime(date_str, "%d-%m-%y")
581+ mapping['effective_date'] = date #fecha_contable.
582+
583+ #execution_date
584+ date_str = self.extract_date_regular_expresion_line(sub,1)
585+ date = datetime.strptime(date_str, "%d-%m-%y")
586+ mapping['execution_date'] = date #fecha_movimiento
587+
588+ mapping['local_currency'] = currencycode
589+ mapping['transfer_type'] = 'NTRF'
590+ mapping['reference'] = parser.extract_number(sub[18:26])
591+ mapping['message'] = sub[27:80]
592+ mapping['name'] = sub[27:80]
593+ mapping['id'] = sub[27:80]
594+
595+ amount = sub[106:]
596+ amount.replace('\t',' ')
597+ debit = amount[0:16]
598+ credit = amount[16:]
599+
600+ if (parser.extract_float(debit) is not ''): #debit
601+ cad = parser.extract_float(debit)
602+ mapping['transferred_amount'] = -float(cad)
603+ mapping['creditmarker'] = 'C'
604+
605+ else: #credit
606+ cad = parser.extract_float (credit)
607+ mapping['transferred_amount'] = float(cad)
608+
609+ lines.append(copy(mapping))
610+
611+ return lines
612+
613+ def second_version (self, sub_list,mapping,currencycode,parser):
614+ lines = []
615+ for sub in sub_list:
616+ #effective_date
617+ date_str = ''
618+ date_str = self.extract_date_regular_expresion_line(sub,0)
619+ date= datetime.strptime(date_str, "%d-%m-%y")
620+ mapping['effective_date'] = date #fecha_contable.
621+
622+ #execution_date
623+ date_str = self.extract_date_regular_expresion_line(sub,1)
624+ date = datetime.strptime(date_str, "%d-%m-%y")
625+ mapping['execution_date'] = date #fecha_movimiento
626+
627+ mapping['local_currency'] = currencycode
628+ mapping['transfer_type'] = 'NTRF'
629+ mapping['reference'] = parser.extract_number(sub[18:26])
630+ mapping['message'] = sub[27:80]
631+ mapping['name'] = sub[27:80]
632+ mapping['id'] = sub[27:80]
633+
634+ amount = sub[120:]
635+ amount.replace('\t',' ')
636+ debit = amount[0:40]
637+ credit = amount[40:]
638+
639+ if (parser.extract_float(debit) is not ''): #debit
640+ cad = parser.extract_float(debit)
641+ mapping['transferred_amount'] = -float(cad)
642+ mapping['creditmarker'] = 'C'
643+
644+ else: #credit
645+ cad = parser.extract_float (credit)
646+ mapping['transferred_amount'] = float(cad)
647+
648+ lines.append(copy(mapping))
649+
650+ return lines
651+
652+ def third_version(self, sub_list,mapping,currencycode,parser):
653+ lines = []
654+ for l in sub_list:
655+ fields = l.split('\t')
656+
657+ #effective_date
658+ date_str = fields[0]
659+ date= datetime.strptime(date_str, "%d-%m-%y")
660+ mapping['effective_date'] = date #fecha_contable.
661+
662+ #execution_date
663+ date_str = fields[1]
664+ date = datetime.strptime(date_str, "%d-%m-%y")
665+ mapping['execution_date'] = date #fecha_movimiento
666+
667+ mapping['local_currency'] = currencycode
668+ mapping['transfer_type'] = 'NTRF'
669+ mapping['reference'] = parser.extract_number(fields[2])
670+ mapping['message'] = fields[3]
671+ mapping['name'] = fields[3]
672+ mapping['id'] = fields[3]
673+
674+ #Extract debit and credit
675+ debit = fields[5]
676+ if (parser.extract_float(debit) is not ''): #debit
677+ cad = parser.extract_float(debit)
678+ mapping['transferred_amount'] = -float(cad)
679+ mapping['creditmarker'] = 'C'
680+
681+ else: #credit
682+ credit = fields[6]
683+ cad = parser.extract_float(credit)
684+ mapping['transferred_amount'] = float(cad)
685+
686+ lines.append(copy(mapping))
687+
688+ return lines
689+
690+ #===============================================================
691+ def extract_number( self, account_number ):
692+ cad = ''
693+ result = re.findall(r'[0-9]+', account_number)
694+
695+ for character in result:
696+ cad = cad + character
697+ return cad
698+
699+ def extract_float ( self, amount ):
700+ cad = ''
701+ result = re.findall(r"[-+]?\d*\.\d+|\d+",amount)
702+
703+ for character in result:
704+ cad = cad + character
705+ return cad
706+
707+ def extract_date_regular_expresion(self, date):
708+ cad = ''
709+ result = []
710+ date_string = ''
711+ #re.findall('[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}',str)[0]+' '+re.findall('[0-9]{2}:[0-9]{2}:[0-9]{2}',str)[0]
712+ #FORMAT DATE FIRST REVISION
713+ result = re.findall('[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}', date)
714+
715+ if len(result) == 0:
716+ #FORMAT DATE SECOND REVISION
717+ result = re.findall('[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}',date)
718+
719+ for character in result:
720+ cad = cad + character
721+ return cad
722+
723+ #with the pos parameter is said which of the two dates must be brought
724+ #result brings a list of two elements, the post tells us to choose
725+ def extract_date_regular_expresion_line(self, date, pos):
726+ cad = ''
727+ result = []
728+ date_string = ''
729+ result = re.findall('([0-9]{2}-[0-9]{2}-[0-9]{2})[\s]*',date)
730+ date_str = result[pos]
731+
732+ for character in date_str:
733+ cad = cad + character
734+ return cad
735+
736+ #with the pos parameter is said which of the two dates must be brought
737+ #result brings a list of two elements, the post tells us to choose
738+ def extract_date_regular_expresion_line_format_2(self, date, pos):
739+ cad = ''
740+ result = []
741+ date_string = ''
742+ result = re.findall('([0-9]{2}-[0-9]{2}-[0-9]{4})[\s]*',date)
743+ date_str = result[pos]
744+
745+ for character in date_str:
746+ cad = cad + character
747+ return cad
748+
749+ def extract_hour_regular_expresion(self, date):
750+ cad = ''
751+ result = []
752+
753+ result = re.findall('[0-9]{2}:[0-9]{2}:[0-9]{2}',date)
754+
755+ for character in result:
756+ cad = cad + character
757+ return cad
758+
759+ def extract_currency_code_USD(self, currency):
760+ cad = ''
761+ result = re.findall('[D.lares]',currency)
762+ for character in result:
763+ cad = cad + character
764+ return cad
765+
766+ def parse( self, cr, data ):
767+ records = []
768+ # Some records are multiline
769+ for line in data:
770+ if len(line) <= 1:
771+ continue
772+ if line[0] == ':' and len(line) > 1:
773+ records.append(line)
774+ else:
775+ records[-1] = '\n'.join([records[-1], line])
776+
777+ output = []
778+
779+ for rec in records:
780+ output.append( self.parse_stamenent_record( rec ) )
781+
782+ return output
783+
784+ #check if the account_number in the file match with the selected in the wizard.
785+ def match_account(self, list_split, account_number_wizard):
786+ accnumber = ''
787+ for l in list_split:
788+ #_account_number -> FIRST REVISION
789+ if l.find('Movimiento de Cuenta Corriente', 0, len('Movimiento de Cuenta Corriente')) > -1:
790+ accnumber = self.extract_number(l)
791+ break
792+
793+ #_account_number -> SECOND REVISION
794+ elif (l.find('MOVIMIENTO DE LA CUENTA CORRIENTE No.', 0, len('MOVIMIENTO DE LA CUENTA CORRIENTE No.')) > -1):
795+ account_str = self.extract_number(l)
796+ #001-0246447-0
797+ account_1 = account_str[2:3] #1
798+ account_2 = account_str[4:] #246447-0
799+ account_complete = account_1+self.extract_number(account_2)#12464470
800+ accnumber = self.extract_number(account_complete)
801+ break
802+
803+ #If return True, the account_number in the wizard and the account in the file are the same.
804+ if accnumber.find(account_number_wizard) > -1:
805+ return True
806+ else:
807+ return False
808+
809+
810+def parse_file( filename ):
811+ bacfile = open( filename, "r" )
812+ p = BCRParser().parse(bacfile.readlines())
813+
814+def main():
815+ """The main function, currently just calls a dummy filename
816+
817+ :returns: description
818+ """
819+ parse_file("testfile")
820+
821+if __name__ == '__main__':
822+ main()
823+

Subscribers

People subscribed via source and target branches

to all changes: