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: 259
Proposed branch: lp:~gs.clearcorp/openerp-costa-rica/7.0_l10n_cr_account_banking
Merge into: lp:openerp-costa-rica
Diff against target: 1138 lines (+2/-1081)
9 files modified
TODO-7.0/l10n_cr_account_banking_cr_bac/__init__.py (+0/-23)
TODO-7.0/l10n_cr_account_banking_cr_bac/__openerp__.py (+0/-40)
TODO-7.0/l10n_cr_account_banking_cr_bac/bac_mt940.py (+0/-261)
TODO-7.0/l10n_cr_account_banking_cr_bac/mt940_parser.py (+0/-153)
TODO-7.0/l10n_cr_account_banking_cr_bcr/__init__.py (+0/-24)
TODO-7.0/l10n_cr_account_banking_cr_bcr/__openerp__.py (+0/-37)
TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_format.py (+0/-174)
TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_parser.py (+0/-366)
l10n_cr_account_banking_cr_davivienda/davivienda_parser.py (+2/-3)
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+197967@code.launchpad.net

Description of the change

[FIX] l10n_cr_account_banking_cr_davivienda: Fixed missing line importing DaVivienda's bank statements file

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

[MRG] l10n_cr_account_banking_cr_davivienda: Fixed missing line importing DaVivienda's bank statements file

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed directory 'TODO-7.0/l10n_cr_account_banking_cr_bac'
2=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bac/__init__.py'
3--- TODO-7.0/l10n_cr_account_banking_cr_bac/__init__.py 2012-07-12 00:37:04 +0000
4+++ TODO-7.0/l10n_cr_account_banking_cr_bac/__init__.py 1970-01-01 00:00:00 +0000
5@@ -1,23 +0,0 @@
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 bac_mt940
28-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
29
30=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bac/__openerp__.py'
31--- TODO-7.0/l10n_cr_account_banking_cr_bac/__openerp__.py 2012-07-12 00:37:04 +0000
32+++ TODO-7.0/l10n_cr_account_banking_cr_bac/__openerp__.py 1970-01-01 00:00:00 +0000
33@@ -1,40 +0,0 @@
34-# -*- coding: utf-8 -*-
35-##############################################################################
36-#
37-# OpenERP, Open Source Management Solution
38-# Addons modules by CLEARCORP S.A.
39-# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
40-#
41-# This program is free software: you can redistribute it and/or modify
42-# it under the terms of the GNU Affero General Public License as
43-# published by the Free Software Foundation, either version 3 of the
44-# License, or (at your option) any later version.
45-#
46-# This program is distributed in the hope that it will be useful,
47-# but WITHOUT ANY WARRANTY; without even the implied warranty of
48-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49-# GNU Affero General Public License for more details.
50-#
51-# You should have received a copy of the GNU Affero General Public License
52-# along with this program. If not, see <http://www.gnu.org/licenses/>.
53-#
54-##############################################################################
55-
56-{
57- 'name': 'BAC Account Banking',
58- 'version': '0.5',
59- 'license': 'AGPL-3',
60- 'author': 'CLEARCORP S.A.',
61- 'website': 'http://www.clearcorp.co.cr',
62- 'category': 'Account Banking',
63- 'depends': ['account_banking'],
64- 'init_xml': [],
65- 'update_xml': [
66- ],
67- 'demo_xml': [],
68- 'description': '''
69- Module to import BAC CR format transation files (S.W.I.F.T MT940).
70- ''',
71- 'active': False,
72- 'installable': True,
73-}
74
75=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bac/bac_mt940.py'
76--- TODO-7.0/l10n_cr_account_banking_cr_bac/bac_mt940.py 2013-02-22 22:35:48 +0000
77+++ TODO-7.0/l10n_cr_account_banking_cr_bac/bac_mt940.py 1970-01-01 00:00:00 +0000
78@@ -1,261 +0,0 @@
79-# -*- encoding: utf-8 -*-
80-##############################################################################
81-#
82-# Copyright (C) 2011 credativ Ltd (<http://www.credativ.co.uk>).
83-# All Rights Reserved
84-#
85-# This program is free software: you can redistribute it and/or modify
86-# it under the terms of the GNU Affero General Public License as
87-# published by the Free Software Foundation, either version 3 of the
88-# License, or (at your option) any later version.
89-#
90-# This program is distributed in the hope that it will be useful,
91-# but WITHOUT ANY WARRANTY; without even the implied warranty of
92-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
93-# GNU Affero General Public License for more details.
94-#
95-# You should have received a copy of the GNU Affero General Public License
96-# along with this program. If not, see <http://www.gnu.org/licenses/>.
97-#
98-##############################################################################
99-# Import of BAC data in Swift MT940 format
100-#
101-
102-from account_banking.parsers import models
103-from tools.translate import _
104-from mt940_parser import BACParser
105-import re
106-import osv
107-import logging
108-import datetime
109-
110-bt = models.mem_bank_transaction
111-logger = logging.getLogger('bac_mt940')
112-
113-def record2float(record, value):
114- if record['creditmarker'][-1] == 'C':
115- return float(record[value])
116- return -float(record[value])
117-
118-class transaction(models.mem_bank_transaction):
119-
120- mapping = {
121- 'execution_date' : 'valuedate',
122- 'effective_date' : 'valuedate',
123- 'local_currency' : 'currency',
124- 'transfer_type' : 'bookingcode',
125- 'reference' : 'custrefno',
126- 'message' : 'furtherinfo',
127- 'name' : 'infoline1'
128- }
129-
130- type_map = {
131- 'NTRF': bt.ORDER,
132- 'NMSC': bt.ORDER,
133- 'NPAY': bt.PAYMENT_BATCH,
134- 'NCHK': bt.CHECK,
135- 'NCLR': bt.ORDER,
136- }
137-
138- def __init__(self, record, *args, **kwargs):
139- '''
140- Transaction creation
141- '''
142- super(transaction, self).__init__(*args, **kwargs)
143- for key, value in self.mapping.iteritems():
144- if record.has_key(value):
145- setattr(self, key, record[value])
146-
147- self.transferred_amount = record2float(record, 'amount')
148-
149- # Set the transfer type based on the bookingcode
150- if record.get('bookingcode','ignore') in self.type_map:
151- self.transfer_type = self.type_map[record['bookingcode']]
152- else:
153- # Default to the generic order, so it will be eligible for matching
154- self.transfer_type = bt.ORDER
155-
156- if not self.is_valid():
157- logger.info("Invalid: %s", record)
158- def is_valid(self):
159- '''
160- We don't have remote_account so override base
161- '''
162- return (self.execution_date
163- and self.transferred_amount and True) or False
164-
165-class statement(models.mem_bank_statement):
166- '''
167- Bank statement imported data
168- '''
169-
170- def import_record(self, record,**kwargs):
171- def _transmission_number():
172- self.id = record['transref']
173- def _account_number():
174- # The wizard doesn't check for sort code
175- self.local_account = record['sortcode'] + record['accnum']
176- def _statement_number():
177- self.id = self.local_account + '-' + record['statementnr']
178- def _opening_balance():
179- self.start_balance = record2float(record,'startingbalance')
180- self.local_currency = record['currencycode']
181- def _closing_balance():
182- self.end_balance = record2float(record, 'endingbalance')
183- today = datetime.datetime.today()
184- dateString = today.strftime("%Y-%m-%d %H:%M:%S")
185- self.id = dateString + '-' + self.id
186- def _transaction_new():
187- self.transactions.append(transaction(record))
188- def _transaction_info():
189- self.transaction_info(record)
190- def _not_used():
191- logger.info("Didn't use record: %s", record)
192- def _forward_available():
193- self.end_balance = record2float(record, 'endingbalance')
194- self.date = record['bookingdate']
195-
196- rectypes = {
197- '20' : _transmission_number,
198- '25' : _account_number,
199- '28' : _statement_number,
200- '28C': _statement_number,
201- '60F': _opening_balance,
202- '62F': _closing_balance,
203- '64' : _forward_available,
204- #'62M': _interim_balance,
205- '61' : _transaction_new,
206- '86' : _transaction_info,
207- }
208-
209- rectypes.get(record['recordid'], _not_used)()
210-
211- def transaction_info(self, record):
212- '''
213- Add extra information to transaction
214- '''
215- # Additional information for previous transaction
216- if len(self.transactions) < 1:
217- logger.info("Received additional information for non existent transaction:")
218- logger.info(record)
219- else:
220- transaction = self.transactions[-1]
221- #transaction.id = ','.join([record[k] for k in ['infoline{0}'.format(i) for i in range(2,5)] if record.has_key(k)])
222- transaction.id = record['infoline1']
223-
224-def raise_error(message, line):
225- raise osv.osv.except_osv(_('Import error'),
226- 'Error in import:%s\n\n%s' % (message, line))
227-
228-class parser_bac_mt940(models.parser):
229- code = 'BAC-MT940'
230- name = _('BAC Swift MT940 statement export')
231- country_code = 'CR'
232- doc = _('''\
233- This format is available through
234- the BAC web interface.
235- ''')
236-
237- def parse(self, cr, data,**kwargs):
238- '''
239- ** Kwargs parameter is used for a dynamic list of parameters.
240- The wizard imported extracts used in all parsers and not all parsers have all the necessary information in your file,
241- so get information from the wizard and passed by the ** kwargs.
242- Then in the parses that are needed, are extracted from the ** kwargs and if needed,
243- the parser still works the same way without this parameter.
244-
245- The rest of the methods must receive this parameter. (As the method that parse the header and the lines).
246- '''
247- result = []
248- parser = BACParser()
249- list_record = []
250- inversion_colocada = 0
251-
252- # Split into statements
253- statements = [st for st in re.split('[\r\n]*(?=:20:)', data)]
254- # Split by records
255- statement_list = [re.split('[\r\n ]*(?=:\d\d[\w]?:)', st) for st in statements]
256-
257- for statement_lines in statement_list:
258- stmnt = statement()
259-
260- """EXTRACCION DE DATOS """
261- for record in statement_lines:
262- records = parser.parse_record(record)
263-
264- if records is not None:
265- ############START PAGO CAPITAL INVERSION
266- if records['recordid'] == '60F':
267- start_balance = float(records['startingbalance'])
268- if records['recordid'] == '61':
269- amount = float(records['amount'])
270- if records['recordid'] == '86' and records['infoline1'] == 'PAGO CAPITAL INVERSION':
271- start_amount = amount
272- start_balance += amount #con la suma ya realizada.
273- ############END PAGO CAPITAL INVERSION
274-
275- ############START INVERSION COLOCADA
276- if records['recordid'] == '86':
277- cad = records['infoline1']
278- if cad.find('INVERSION COLOCADA') > 0:
279- inversion_colocada = amount
280-
281- if records['recordid'] == '62F':
282- ending_balance = (inversion_colocada + float(records['endingbalance']))
283-
284- if records is not None:
285- """ACTUALIZACION DE DATOS """
286- for record in statement_lines:
287- if record is not None:
288- records = parser.parse_record(record)
289-
290- if (records['recordid'] == '60F'):
291- dic = {'startingbalance':start_balance}
292- records.update(dic)
293-
294- if (records['recordid'] == '62F'):
295- dic = {'endingbalance': ending_balance}
296- records.update(dic)
297-
298- if (records['recordid'] == '64'):
299- dic = {'endingbalance': ending_balance}
300- records.update(dic)
301-
302- #SI LA LINEA NO ES INVERSION COLOCADA O PAGO CAPITAL INVERSION, SE AGREGA A LA LISTA
303- #PAGO_CAPITAL
304- if (records['recordid'] == '86'):
305- cad = records['infoline1']
306-
307- if (cad != "PAGO CAPITAL INVERSION") and (cad.find("INVERSION COLOCADA") < 0):
308- list_record.append(records)
309-
310- if (records['recordid'] == '61'):
311- try:
312- if float(records['amount']) != start_amount and float(records['amount']) != inversion_colocada:
313- list_record.append(records)
314- except:
315- list_record.append(records)
316- #####################################################################
317-
318- if (records['recordid'] != '61' and records['recordid'] != '86' ):
319- list_record.append(records)
320-
321- [stmnt.import_record(r) for r in list_record if r is not None]
322-
323- if stmnt.is_valid():
324- result.append(stmnt)
325- list_record = []
326- inversion_colocada = 0
327- start_balance = 0
328- else:
329- logger.info("Invalid Statement:")
330- logger.info(records[0])
331- logger.info(records[1])
332- logger.info(records[2])
333- logger.info(records[3])
334- logger.info(records[4])
335- list_record = []
336-
337- return result
338-
339-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
340
341=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bac/mt940_parser.py'
342--- TODO-7.0/l10n_cr_account_banking_cr_bac/mt940_parser.py 2013-02-22 22:35:48 +0000
343+++ TODO-7.0/l10n_cr_account_banking_cr_bac/mt940_parser.py 1970-01-01 00:00:00 +0000
344@@ -1,153 +0,0 @@
345-#!/usr/bin/env python
346-# -*- encoding: utf-8 -*-
347-##############################################################################
348-#
349-# Copyright (C) 2011 credativ Ltd (<http://www.credativ.co.uk>).
350-# All Rights Reserved
351-#
352-# This program is free software: you can redistribute it and/or modify
353-# it under the terms of the GNU Affero General Public License as
354-# published by the Free Software Foundation, either version 3 of the
355-# License, or (at your option) any later version.
356-#
357-# This program is distributed in the hope that it will be useful,
358-# but WITHOUT ANY WARRANTY; without even the implied warranty of
359-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
360-# GNU Affero General Public License for more details.
361-#
362-# You should have received a copy of the GNU Affero General Public License
363-# along with this program. If not, see <http://www.gnu.org/licenses/>.
364-#
365-##############################################################################
366-
367-"""
368-Parser for BAC CR MT940 format files
369-Based on fi_patu's parser
370-"""
371-import re
372-from datetime import datetime
373-
374-class BACParser(object):
375-
376- def __init__( self ):
377- recparse = dict()
378- patterns = {'ebcdic': "\w/\?:\(\).,'+{} -"}
379-
380- # MT940 header
381- recparse["20"] = ":(?P<recordid>20):(?P<transref>.{1,16})"
382- recparse["25"] = ":(?P<recordid>25):(?P<sortcode>\d{6})(?P<accnum>\d{1,29})"
383- recparse["28"] = ":(?P<recordid>28C?):(?P<statementnr>.{1,8})"
384-
385- # Opening balance 60F
386- recparse["60F"] = ":(?P<recordid>60F):(?P<creditmarker>[CD])" \
387- + "(?P<prevstmtdate>\d{6})(?P<currencycode>.{3})" \
388- + "(?P<startingbalance>[\d,]{1,15})"
389-
390- # Transaction
391- recparse["61"] = ":(?P<recordid>61):" \
392- + "(?P<valuedate>\d{6})(?P<bookingdate>\d{4})?" \
393- + "(?P<creditmarker>R?[CD])" \
394- + "(?P<amount>[\d,]{1,15})" \
395- + "(?P<bookingcode>[A-Z]{4})" \
396- + "(?P<custrefno>[\d,]{1,16})" \
397- + "(?P<bankref>[%(ebcdic)s]{1,16})?" \
398- + "(?:\n(?P<furtherinfo>[%(ebcdic)s]))?" \
399- % (patterns)
400-
401- # Further info
402- recparse["86"] = ":(?P<recordid>86):" \
403- + "(?P<infoline1>.{1,80})?" \
404- + "(?:\n(?P<infoline2>.{1,80}))?" \
405- + "(?:\n(?P<infoline3>.{1,80}))?" \
406- + "(?:\n(?P<infoline4>.{1,80}))?" \
407- + "(?:\n(?P<infoline5>.{1,80}))?"
408-
409- # Forward available balance (64) / Closing balance (62F) / Interim balance (62M)
410- recparse["64"] = ":(?P<recordid>64|62[FM]):" \
411- + "(?P<creditmarker>[CD])" \
412- + "(?P<bookingdate>\d{6})(?P<currencycode>.{3})" \
413- + "(?P<endingbalance>[\d,]{1,15})"
414-
415- for record in recparse:
416- recparse[record] = re.compile(recparse[record])
417- self.recparse = recparse
418-
419-
420- def parse_record(self, line,**kwargs):
421- """
422- Parse record using regexps and apply post processing
423- """
424- for matcher in self.recparse:
425- matchobj = self.recparse[matcher].match(line)
426- if matchobj:
427- break
428- if not matchobj:
429- print " **** failed to match line '%s'" % (line)
430- return
431- # Strip strings
432- matchdict = matchobj.groupdict()
433-
434- # Remove members set to None
435- matchdict=dict([(k,v) for k,v in matchdict.iteritems() if v])
436-
437- matchkeys = set(matchdict.keys())
438- needstrip = set(["transref", "accnum", "statementnr", "custrefno",
439- "bankref", "furtherinfo", "infoline1", "infoline2", "infoline3",
440- "infoline4", "infoline5", "startingbalance", "endingbalance"])
441- for field in matchkeys & needstrip:
442- matchdict[field] = matchdict[field].strip()
443-
444- # Convert to float. Comma is decimal separator
445- needsfloat = set(["startingbalance", "endingbalance", "amount"])
446- for field in matchkeys & needsfloat:
447- matchdict[field] = float(matchdict[field].replace(',','.'))
448-
449- # Convert date fields
450- needdate = set(["prevstmtdate", "valuedate", "bookingdate"])
451- for field in matchkeys & needdate:
452- datestring = matchdict[field]
453-
454- post_check = False
455- if len(datestring) == 4 and field=="bookingdate" and matchdict.has_key("valuedate"):
456- # Get year from valuedate
457- datestring = matchdict['valuedate'].strftime('%y') + datestring
458- post_check = True
459- try:
460- matchdict[field] = datetime.strptime(datestring,'%y%m%d')
461- if post_check and matchdict[field] > matchdict["valuedate"]:
462- matchdict[field]=matchdict[field].replace(year=matchdict[field].year-1)
463- except ValueError:
464- matchdict[field] = None
465-
466- return matchdict
467-
468- def parse(self, cr, data):
469- records = []
470- # Some records are multiline
471- for line in data:
472- if len(line) <= 1:
473- continue
474- if line[0] == ':' and len(line) > 1:
475- records.append(line)
476- else:
477- records[-1] = '\n'.join([records[-1], line])
478-
479- output = []
480- for rec in records:
481- output.append(self.parse_record(rec))
482-
483- return output
484-
485-def parse_file(filename):
486- bacfile = open(filename, "r")
487- p = BACParser().parse(bacfile.readlines())
488-
489-def main():
490- """The main function, currently just calls a dummy filename
491-
492- :returns: description
493- """
494- parse_file("testfile")
495-
496-if __name__ == '__main__':
497- main()
498
499=== removed directory 'TODO-7.0/l10n_cr_account_banking_cr_bcr'
500=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bcr/__init__.py'
501--- TODO-7.0/l10n_cr_account_banking_cr_bcr/__init__.py 2012-07-18 03:20:08 +0000
502+++ TODO-7.0/l10n_cr_account_banking_cr_bcr/__init__.py 1970-01-01 00:00:00 +0000
503@@ -1,24 +0,0 @@
504-# -*- encoding: utf-8 -*-
505-##############################################################################
506-#
507-# Copyright (C) 2011 credativ Ltd (<http://www.credativ.co.uk>).
508-# All Rights Reserved
509-#
510-# This program is free software: you can redistribute it and/or modify
511-# it under the terms of the GNU Affero General Public License as
512-# published by the Free Software Foundation, either version 3 of the
513-# License, or (at your option) any later version.
514-#
515-# This program is distributed in the hope that it will be useful,
516-# but WITHOUT ANY WARRANTY; without even the implied warranty of
517-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
518-# GNU Affero General Public License for more details.
519-#
520-# You should have received a copy of the GNU Affero General Public License
521-# along with this program. If not, see <http://www.gnu.org/licenses/>.
522-#
523-##############################################################################
524-
525-import bcr_format
526-
527-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
528
529=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bcr/__openerp__.py'
530--- TODO-7.0/l10n_cr_account_banking_cr_bcr/__openerp__.py 2012-07-06 05:08:02 +0000
531+++ TODO-7.0/l10n_cr_account_banking_cr_bcr/__openerp__.py 1970-01-01 00:00:00 +0000
532@@ -1,37 +0,0 @@
533-# -*- coding: utf-8 -*-
534-##############################################################################
535-#
536-# OpenERP, Open Source Management Solution
537-# Addons modules by CLEARCORP S.A.
538-# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
539-#
540-# This program is free software: you can redistribute it and/or modify
541-# it under the terms of the GNU Affero General Public License as
542-# published by the Free Software Foundation, either version 3 of the
543-# License, or (at your option) any later version.
544-#
545-# This program is distributed in the hope that it will be useful,
546-# but WITHOUT ANY WARRANTY; without even the implied warranty of
547-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
548-# GNU Affero General Public License for more details.
549-#
550-# You should have received a copy of the GNU Affero General Public License
551-# along with this program. If not, see <http://www.gnu.org/licenses/>.
552-#
553-##############################################################################
554-
555-{
556- 'name': 'BCR Account Banking',
557- 'version': '0.5',
558- 'license': 'AGPL-3',
559- 'author': 'CLEARCORP S.A.',
560- 'website': 'http://www.clearcorp.co.cr',
561- 'category': 'Account Banking',
562- 'depends': ['account_banking'],
563- 'init_xml': [],
564- 'update_xml': [],
565- 'demo_xml': [],
566- 'description': '',
567- 'active': False,
568- 'installable': True,
569-}
570
571=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_format.py'
572--- TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_format.py 2013-02-22 22:35:48 +0000
573+++ TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_format.py 1970-01-01 00:00:00 +0000
574@@ -1,174 +0,0 @@
575-# -*- coding: utf-8 -*-
576-##############################################################################
577-#
578-# OpenERP, Open Source Management Solution
579-# Addons modules by CLEARCORP S.A.
580-# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
581-#
582-# This program is free software: you can redistribute it and/or modify
583-# it under the terms of the GNU Affero General Public License as
584-# published by the Free Software Foundation, either version 3 of the
585-# License, or (at your option) any later version.
586-#
587-# This program is distributed in the hope that it will be useful,
588-# but WITHOUT ANY WARRANTY; without even the implied warranty of
589-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
590-# GNU Affero General Public License for more details.
591-#
592-# You should have received a copy of the GNU Affero General Public License
593-# along with this program. If not, see <http://www.gnu.org/licenses/>.
594-#
595-##############################################################################
596-
597-from account_banking.parsers import models
598-from tools.translate import _
599-from bcr_parser import BCRParser
600-import re
601-import osv
602-import logging
603-import pprint
604-from datetime import datetime
605-
606-bt = models.mem_bank_transaction
607-logger = logging.getLogger( 'bcr_mt940' )
608-
609-def record2float(record, value):
610- if record == 'C':
611- return float (value)
612- else:
613- return -float(value)
614-
615-class transaction(models.mem_bank_transaction):
616-
617- mapping = {
618- 'execution_date' : '',
619- 'effective_date' : '',
620- 'local_currency' : '',
621- 'transfer_type' : '',
622- 'reference' : '',
623- 'message' : '',
624- 'name' : '',
625- 'amount': '',
626- 'creditmarker': '',
627- }
628-
629- def __init__(self, record, *args, **kwargs):
630-
631- '''
632- Transaction creation
633- '''
634- super(transaction, self).__init__(*args, **kwargs)
635- #for r in record:
636- for key, value in record.iteritems():
637- if record.has_key(key):
638- setattr(self, key, record[key])
639-
640- if not self.is_valid():
641- logger.info("Invalid: %s", record)
642-
643- def is_valid(self):
644- '''
645- We don't have remote_account so override base
646- '''
647- return (self.execution_date
648- and self.transferred_amount and True) or False
649-
650-class statement(models.mem_bank_statement):
651- '''
652- Bank statement imported data '''
653-
654- def _transmission_number(self, record):
655- self.id = record['transref']
656-
657- def _account_number(self, record):
658- self.local_account = record['account_number']
659-
660- def _statement_number(self, record):
661- self.id = record['id']
662-
663- def _opening_balance(self, record):
664- self.start_balance = float(record['startingbalance'])
665- self.local_currency = record['currencycode']
666-
667- def _closing_balance(self, record):
668- self.end_balance = float(record['endingbalance'])
669- self.date = record['bookingdate']
670-
671- def _transaction_new(self, record):
672- parser = BCRParser()
673- sub_record = parser.statement_lines(record) #dictionary
674- for sub in sub_record:
675- self.transactions.append(transaction(sub))
676-
677- #def _transaction_info():
678- #self.transaction_info(record)
679-
680- def _not_used():
681- logger.info("Didn't use record: %s", record)
682-
683- def _forward_available(self, record):
684- self.end_balance = float(record['endingbalance'])
685- self.date = record['bookingdate']
686-
687- def _execution_date_transferred_amount (self, record):
688- self.execution_date = record['bookingdate']
689- self.transferred_amount = float(record['ammount'])
690-
691- def transaction_info(self, record):
692- '''
693- Add extra information to transaction
694- '''
695- # Additional information for previous transaction
696- if len(self.transactions) < 1:
697- logger.info("Received additional information for non existent transaction:")
698- logger.info(record)
699- else:
700- transaction = self.transactions[-1]
701- transaction.id = ','.join([record[k] for k in ['infoline{0}'.format(i) for i in range(2,5)] if record.has_key(k)])
702-
703-def raise_error(message, line):
704- raise osv.osv.except_osv(_('Import error'),
705- 'Error in import:%s\n\n%s' % (message, line))
706-
707-class parser_bcr_mt940( models.parser ):
708- code = 'BCR-MT940'
709- name = _( 'BCR statement import' )
710- country_code = 'CR'
711- doc = _('''\
712- This format is available through
713- the BCR web interface.
714- ''')
715-
716- def parse(self, cr, data, **kwargs):
717-
718- '''
719- ** Kwargs parameter is used for a dynamic list of parameters.
720- The wizard imported extracts used in all parsers and not all parsers have all the necessary information in your file,
721- so get information from the wizard and passed by the ** kwargs.
722- Then in the parses that are needed, are extracted from the ** kwargs and if needed,
723- the parser still works the same way without this parameter.
724-
725- The rest of the methods must receive this parameter. (As the method that parse the header and the lines).
726- '''
727-
728- result = []
729- parser = BCRParser()
730- stmnt = statement()
731-
732- records = parser.parse_stamenent_record(data)
733-
734- stmnt._transmission_number(records)
735- stmnt._account_number(records)
736- stmnt._statement_number(records)
737- stmnt._opening_balance(records)
738- stmnt._closing_balance(records)
739- stmnt._forward_available(records)
740- stmnt._execution_date_transferred_amount (records)
741- stmnt._transaction_new(data)
742-
743- if stmnt.is_valid():
744- result.append(stmnt)
745-
746- return result
747-
748-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
749
750=== removed file 'TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_parser.py'
751--- TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_parser.py 2013-02-22 22:35:48 +0000
752+++ TODO-7.0/l10n_cr_account_banking_cr_bcr/bcr_parser.py 1970-01-01 00:00:00 +0000
753@@ -1,366 +0,0 @@
754-# -*- coding: utf-8 -*-
755-##############################################################################
756-#
757-# OpenERP, Open Source Management Solution
758-# Addons modules by CLEARCORP S.A.
759-# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
760-#
761-# This program is free software: you can redistribute it and/or modify
762-# it under the terms of the GNU Affero General Public License as
763-# published by the Free Software Foundation, either version 3 of the
764-# License, or (at your option) any later version.
765-#
766-# This program is distributed in the hope that it will be useful,
767-# but WITHOUT ANY WARRANTY; without even the implied warranty of
768-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
769-# GNU Affero General Public License for more details.
770-#
771-# You should have received a copy of the GNU Affero General Public License
772-# along with this program. If not, see <http://www.gnu.org/licenses/>.
773-#
774-##############################################################################
775-"""
776-Parser for BCR format files
777-"""
778-import re
779-from datetime import datetime
780-from dateutil import parser
781-from pprint import PrettyPrinter
782-from copy import copy
783-
784-class BCRParser( object ):
785- """
786- Para noviembre de 2012 se cambia el formato del archivo del BCR. Se cambia el encabezado del archivo
787- así como el final del mismo. Además en la parte de abajo cambia el formato y visualización de los
788- saldos finales.
789-
790- El cambio más evidente es el formato de la cuenta de banco, pasa de 1-246447-0 a 001-0246447-0
791- Revisión # 1 Revisión#2
792- Encabezado anterior: Encabezado nuevo
793- BANCO DE COSTA RICA BANCO DE COSTA RICA
794- 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)
795- Dueño: COMPA IA INMOBILIARIA CENTROA DUENO: COMPA IA INMOBILIARIA CENTROAMERICANA CICCR S
796- Movimiento realizado el periodo del 01-10-2012 al 31-10-2012 MOVIMIENTO REALIZADO DEL 01-11-2012 AL 30-11-2012
797-
798- Final de archivo
799- Revisión # 1 Revisión #2
800- TOTALES DEL MOVIMIENTO CONTABILIZADO TOTALES DEL MOVIMIENTO CONTABILIZADO
801- Cantidad -------Monto-------- CANTIDAD -------MONTO--------
802- Débitos 239 81,876,681.22 DEBITOS 209 67,553,414.30
803- Créditos 27 92,636,599.01 CREDITOS 8 66,086,326.53
804-
805- Saldo Inicial 21,682,799.04 -------- SALDOS --------
806- Saldo Final 33,992,829.43 INICIAL 33,992,829.43
807- FINAL 32,525,741.66
808- Solicitado el 01/11/2012 20:03:34 SOLICITADO EL 01-12-2012 A LAS 15:36:15:17
809- """
810- def statement_record ( self, rec, **kwargs):
811- lines = []
812- line_dict = {}
813-
814- line_dict = {
815- 'transref': 0.0, # _transmission_number
816- 'account_number': '', #_account_number
817- 'statementnr':'', # statement_number
818- 'startingbalance': 0.0, #_opening_balance
819- 'currencycode': 'CRC', #currencycode
820- 'endingbalance': 0.0, #_closing_balance
821- 'bookingdate': '', #moving_date
822- 'ammount': 0.0,
823- 'id': '',
824- }
825-
826- cad = ''
827- list_split = rec.split('\r\n')
828-
829- for l in list_split:
830-
831- # _transmission_number -> FIRST REVISION
832- if (l.find('Movimiento realizado el periodo', 0, len('Movimiento realizado el periodo')) > -1):
833- line_dict['statementnr'] = self.extract_number(l)
834- # _transmission_number -> SECOND REVISION
835- elif (l.find('MOVIMIENTO REALIZADO', 0, len('MOVIMIENTO REALIZADO')) > -1):
836- line_dict['statementnr'] = self.extract_number(l)
837-
838- #_account_number -> FIRST REVISION
839- if l.find('Movimiento de Cuenta Corriente', 0, len('Movimiento de Cuenta Corriente')) > -1:
840- line_dict['account_number'] = self.extract_number(l)
841- if (l.find('D',0,len(l)) > -1):
842- line_dict['currencycode'] = 'USD'
843- else:
844- line_dict['currencycode'] = 'CRC'
845- #_account_number -> SECOND REVISION
846- elif (l.find('MOVIMIENTO DE LA CUENTA CORRIENTE No.', 0, len('MOVIMIENTO DE LA CUENTA CORRIENTE No.')) > -1):
847- account_str = self.extract_number(l)
848- #001-0246447-0
849- account_1 = account_str[2:3] #1
850- account_2 = account_str[4:] #246447-0
851- account_complete = account_1+self.extract_number(account_2)#12464470
852- line_dict['account_number'] = self.extract_number(account_complete)
853- if (l.find('DOLARES',0,len(l)) > -1):
854- line_dict['currencycode'] = 'USD'
855- else:
856- line_dict['currencycode'] = 'CRC'
857-
858- #FECHA Y HORA -> FIRST REVISION
859- if (l.find('Solicitado el', 0, len('Solicitado el')) > -1):
860- date = hour = cad = ''
861- date = self.extract_date_regular_expresion(l)
862- if len(date) > 0:
863- hour = self.extract_hour_regular_expresion(l)
864- cad = date + ' ' + hour
865- line_dict['transref'] = cad
866- line_dict['bookingdate'] = cad
867- #FECHA Y HORA -> SECOND REVISION
868- elif (l.find('SOLICITADO EL', 0, len('SOLICITADO EL')) > -1):
869- date = hour = cad = ''
870- date = self.extract_date_regular_expresion(l)
871- if len(date) > 0:
872- hour = self.extract_hour_regular_expresion(l)
873- cad = date + ' ' + hour
874- line_dict['transref'] = cad
875- line_dict['bookingdate'] = cad
876-
877- #_opening_balance -> FIRST REVISION
878- if l.find('Saldo Inicial', 0, len('Saldo Inicial')) > -1:
879- line_dict['startingbalance'] = self.extract_float(l)
880- #_opening_balance -> SECOND REVISION
881- elif l.find('INICIAL', 0, len('INICIAL')) > -1:
882- line_dict['startingbalance'] = self.extract_float(l)
883-
884- #_closing_balance -> FIRST REVISION
885- if l.find('FINAL', 0, len('FINAL')) > -1:
886- line_dict['endingbalance'] = self.extract_float(l)
887- #_closing_balance -> SECOND REVISION
888- elif l.find('Saldo Final', 0, len('Saldo Final')) > -1:
889- line_dict['endingbalance'] = self.extract_float(l)
890-
891- line_dict['ammount'] = float( line_dict['startingbalance'] ) + float( line_dict['endingbalance'] )
892- line_dict['id'] = line_dict['bookingdate'] + ' - ' + line_dict['account_number']
893- self.line_dict = line_dict
894-
895- return line_dict
896-
897- def statement_lines ( self, rec ):
898- parser = BCRParser()
899- mapping = {
900- 'execution_date' : '',
901- 'effective_date' : '',
902- 'local_currency' : '',
903- 'transfer_type' : '',
904- 'reference' : '',
905- 'message' : '',
906- 'name' : '',
907- 'transferred_amount': '',
908- 'creditmarker': '',
909- }
910-
911- lines = []
912- line_dict = {}
913- currencycode = ''
914-
915- list_split = rec.split('\r\n')
916- entrada = False
917- start = 0
918- end = 0
919-
920- for l in list_split:
921- if l.find('TOTALES DEL MOVIMIENTO CONTABILIZADO', 0, len('TOTALES DEL MOVIMIENTO CONTABILIZADO')) <= -1:
922- end += 1
923- else:
924- break
925- end = end - 1
926-
927- for l in list_split:
928- if l.find('-CONTABLE-', 0, len('-CONTABLE-')) <= -1:
929- start += 1
930- else:
931- break
932- start += 1
933-
934- for l in list_split:
935- if l.find('Movimiento de Cuenta Corriente', 0, len('Movimiento de Cuenta Corriente')) > -1:
936- if (l.find('D',0,len(l)) > -1):
937- currencycode = 'USD'
938- else:
939- currencycode = 'CRC'
940- break
941-
942- elif l.find('MOVIMIENTO DE LA CUENTA CORRIENTE No.', 0, len('MOVIMIENTO DE LA CUENTA CORRIENTE No.')) > -1:
943- if (l.find('DOLARES',0,len(l)) > -1):
944- currencycode = 'USD'
945- else:
946- currencycode = 'CRC'
947- break
948-
949- sub_list = list_split [start:end]
950- for sub in sub_list:
951- #effective_date
952- date_str = ''
953- date_str = self.extract_date_regular_expresion_line(sub,0)
954- date= datetime.strptime(date_str, "%d-%m-%y")
955- mapping['effective_date'] = date #fecha_contable.
956-
957- #execution_date
958- date_str = self.extract_date_regular_expresion_line(sub,1)
959- date = datetime.strptime(date_str, "%d-%m-%y")
960- mapping['execution_date'] = date #fecha_movimiento
961-
962- mapping['local_currency'] = currencycode
963- mapping['transfer_type'] = 'NTRF'
964- mapping['reference'] = parser.extract_number(sub[18:26])
965- mapping['message'] = sub[27:80]
966- mapping['name'] = sub[27:80]
967- mapping['id'] = sub[27:80]
968-
969- amount = sub[106:]
970- amount.replace('\t',' ')
971- debit = amount[0:16]
972- credit = amount[16:]
973-
974- if (parser.extract_float(debit) is not ''): #debit
975- cad = parser.extract_float(debit)
976- mapping['transferred_amount'] = -float(cad)
977- mapping['creditmarker'] = 'C'
978-
979- else: #credit
980- cad = parser.extract_float (credit)
981- mapping['transferred_amount'] = float(cad)
982-
983- lines.append(copy(mapping))
984-
985- return lines
986-
987- def parse_stamenent_record( self, rec, **kwargs):
988-
989- matchdict = dict()
990-
991- matchdict = self.statement_record( rec, **kwargs );
992-
993- # Remove members set to None
994- matchdict = dict( [( k, v ) for k, v in matchdict.iteritems() if v] )
995-
996- matchkeys = set( matchdict.keys() )
997- needstrip = set( [ 'transref', 'account_number', 'statementnr', 'currencycode', 'endingbalance', 'bookingdate'] )
998-
999- for field in matchkeys & needstrip:
1000- matchdict[field] = matchdict[field].strip()
1001-
1002- # Convert to float. Comma is decimal separator
1003- needsfloat = set( ["startingbalance", "endingbalance", "amount"] )
1004- for field in matchkeys & needsfloat:
1005- matchdict[field] = float( matchdict[field].replace( ',', '.' ) )
1006-
1007- # Convert date fields
1008- needdate = set( ["bookingdate"] )
1009-
1010- for field in matchkeys & needdate:
1011- datestring = matchdict[field]
1012- date = self.extract_date_regular_expresion(datestring)
1013- hour = self.extract_hour_regular_expresion(datestring)
1014-
1015- date_complete = date + ' ' + hour
1016- try:
1017- #FORMAT DATE REVISION # 1
1018- date_obj= datetime.strptime(date_complete, "%d/%m/%Y %H:%M:%S")
1019- except:
1020- #FORMAT DATE REVISION # 2
1021- date_obj= datetime.strptime(date_complete, "%d-%m-%Y %H:%M:%S")
1022- matchdict[field] = date_obj
1023-
1024- return matchdict
1025-
1026- def extract_number( self, account_number ):
1027- cad = ''
1028- result = re.findall(r'[0-9]+', account_number)
1029-
1030- for character in result:
1031- cad = cad + character
1032- return cad
1033-
1034- def extract_float ( self, ammount ):
1035- cad = ''
1036- result = re.findall(r"[-+]?\d*\.\d+|\d+",ammount)
1037-
1038- for character in result:
1039- cad = cad + character
1040- return cad
1041-
1042- def extract_date_regular_expresion(self, date):
1043- cad = ''
1044- result = []
1045- date_string = ''
1046- #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]
1047- #FORMAT DATE FIRST REVISION
1048- result = re.findall('[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}', date)
1049-
1050- if len(result) == 0:
1051- #FORMAT DATE SECOND REVISION
1052- result = re.findall('[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}',date)
1053-
1054- for character in result:
1055- cad = cad + character
1056- return cad
1057-
1058- #with the pos parameter is said which of the two dates must be brought
1059- #result brings a list of two elements, the post tells us to choose
1060- def extract_date_regular_expresion_line(self, date, pos):
1061- cad = ''
1062- result = []
1063- date_string = ''
1064- result = re.findall('([0-9]{2}-[0-9]{2}-[0-9]{2})[\s]*',date)
1065- date_str = result[pos]
1066-
1067- for character in date_str:
1068- cad = cad + character
1069- return cad
1070-
1071- def extract_hour_regular_expresion(self, date):
1072- cad = ''
1073- result = []
1074-
1075- result = re.findall('[0-9]{2}:[0-9]{2}:[0-9]{2}',date)
1076-
1077- for character in result:
1078- cad = cad + character
1079- return cad
1080-
1081- def extract_currency_code_USD(self, currency):
1082- cad = ''
1083- result = re.findall('[D.lares]',currency)
1084- for character in result:
1085- cad = cad + character
1086- return cad
1087-
1088- def parse( self, cr, data ):
1089- records = []
1090- # Some records are multiline
1091- for line in data:
1092- if len(line) <= 1:
1093- continue
1094- if line[0] == ':' and len(line) > 1:
1095- records.append(line)
1096- else:
1097- records[-1] = '\n'.join([records[-1], line])
1098-
1099- output = []
1100-
1101- for rec in records:
1102- output.append( self.parse_stamenent_record( rec ) )
1103-
1104- return output
1105-
1106-def parse_file( filename ):
1107- bacfile = open( filename, "r" )
1108- p = BCRParser().parse( bacfile.readlines() )
1109-
1110-def main():
1111- """The main function, currently just calls a dummy filename
1112-
1113- :returns: description
1114- """
1115- parse_file("testfile")
1116-
1117-if __name__ == '__main__':
1118- main()
1119-
1120
1121=== modified file 'l10n_cr_account_banking_cr_davivienda/davivienda_parser.py'
1122--- l10n_cr_account_banking_cr_davivienda/davivienda_parser.py 2013-12-04 17:39:51 +0000
1123+++ l10n_cr_account_banking_cr_davivienda/davivienda_parser.py 2013-12-05 22:58:17 +0000
1124@@ -148,12 +148,11 @@
1125 #last line can be blanck, find the last line with data.
1126 if last_line == "":
1127 while True:
1128- end -= 1
1129 last_line = list_split[end]
1130 if last_line is not "":
1131 break
1132-
1133- sub_list = list_split [start:end]
1134+ end -= 1
1135+ sub_list = list_split [start:end+1]
1136 for sub in sub_list:
1137 line = sub.split(';')
1138 #effective_date

Subscribers

People subscribed via source and target branches

to all changes: