Diana Rodríguez Martínez has proposed merging lp:~dr.clearcorp/openerp-costa-rica/l10n_cr_account_banking_cr_bcr into lp:openerp-costa-rica.
Requested reviews: CLEARCORP drivers (clearcorp-drivers) For more details, see: https://code.launchpad.net/~dr.clearcorp/openerp-costa-rica/l10n_cr_account_banking_cr_bcr/+merge/113688 [ADD] New module l10n_cr_account_banking_cr_bcr - Import statement and transactions -- https://code.launchpad.net/~dr.clearcorp/openerp-costa-rica/l10n_cr_account_banking_cr_bcr/+merge/113688 Your team CLEARCORP development team is subscribed to branch lp:openerp-costa-rica.
=== added directory 'l10n_cr_account_banking_cr_bcr' === added file 'l10n_cr_account_banking_cr_bcr/__init__.py' --- l10n_cr_account_banking_cr_bcr/__init__.py 1970-01-01 00:00:00 +0000 +++ l10n_cr_account_banking_cr_bcr/__init__.py 2012-07-06 05:13:21 +0000 @@ -0,0 +1,24 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2011 credativ Ltd (<http://www.credativ.co.uk>). +# All Rights Reserved +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +import bcr_mt940 + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: === added file 'l10n_cr_account_banking_cr_bcr/__openerp__.py' --- l10n_cr_account_banking_cr_bcr/__openerp__.py 1970-01-01 00:00:00 +0000 +++ l10n_cr_account_banking_cr_bcr/__openerp__.py 2012-07-06 05:13:21 +0000 @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Addons modules by CLEARCORP S.A. +# Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +{ + 'name': 'BCR Account Banking', + 'version': '0.5', + 'license': 'AGPL-3', + 'author': 'CLEARCORP S.A.', + 'website': 'http://www.clearcorp.co.cr', + 'category': 'Account Banking', + 'depends': ['account_banking'], + 'init_xml': [], + 'update_xml': [], + 'demo_xml': [], + 'description': '', + 'active': False, + 'installable': True, +} === added file 'l10n_cr_account_banking_cr_bcr/bcr_mt940.py' --- l10n_cr_account_banking_cr_bcr/bcr_mt940.py 1970-01-01 00:00:00 +0000 +++ l10n_cr_account_banking_cr_bcr/bcr_mt940.py 2012-07-06 05:13:21 +0000 @@ -0,0 +1,164 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2011 credativ Ltd (<http://www.credativ.co.uk>). +# All Rights Reserved +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## +# Import of BAC data in Swift MT940 format +# + +from account_banking.parsers import models +from tools.translate import _ +from mt940_parser import BCRParser +import re +import osv +import logging +import pprint +from datetime import datetime + +bt = models.mem_bank_transaction +logger = logging.getLogger( 'bcr_mt940' ) + +def record2float(record, value): + if record == 'C': + return float (value) + else: + return -float(value) + +class transaction(models.mem_bank_transaction): + + mapping = { + 'execution_date' : '', + 'effective_date' : '', + 'local_currency' : '', + 'transfer_type' : '', + 'reference' : '', + 'message' : '', + 'name' : '', + 'amount': '', + 'creditmarker': '', + } + + def __init__(self, record, *args, **kwargs): + + ''' + Transaction creation + ''' + super(transaction, self).__init__(*args, **kwargs) + #for r in record: + for key, value in record.iteritems(): + if record.has_key(key): + setattr(self, key, record[key]) + + if not self.is_valid(): + logger.info("Invalid: %s", r) + + def is_valid(self): + ''' + We don't have remote_account so override base + ''' + return (self.execution_date + and self.transferred_amount and True) or False + +class statement(models.mem_bank_statement): + ''' + Bank statement imported data ''' + + def _transmission_number(self, record): + self.id = record['transref'] + + def _account_number(self, record): + self.local_account = record['account_number'] + + def _statement_number(self, record): + self.id = self.local_account + + def _opening_balance(self, record): + self.start_balance = float(record['startingbalance']) + self.local_currency = record['currencycode'] + + def _closing_balance(self, record): + self.end_balance = float(record['endingbalance']) + self.date = record['bookingdate'] + + def _transaction_new(self, record): + parser = BCRParser() + sub_record = parser.statement_lines(record) #dictionary + for sub in sub_record: + self.transactions.append(transaction(sub)) + + #def _transaction_info(): + #self.transaction_info(record) + + def _not_used(): + logger.info("Didn't use record: %s", record) + + def _forward_available(self, record): + self.end_balance = float(record['endingbalance']) + self.date = record['bookingdate'] + + def _execution_date_transferred_amount (self, record): + self.execution_date = record['bookingdate'] + self.transferred_amount = float(record['ammount']) + + def transaction_info(self, record): + ''' + Add extra information to transaction + ''' + # Additional information for previous transaction + if len(self.transactions) < 1: + logger.info("Received additional information for non existent transaction:") + logger.info(record) + else: + transaction = self.transactions[-1] + transaction.id = ','.join([record[k] for k in ['infoline{0}'.format(i) for i in range(2,5)] if record.has_key(k)]) + +def raise_error(message, line): + raise osv.osv.except_osv(_('Import error'), + 'Error in import:%s\n\n%s' % (message, line)) + +class parser_bcr_mt940( models.parser ): + code = 'BCR-MT940' + name = _( 'BCR statement import' ) + country_code = 'CR' + doc = _('''\ + This format is available through + the BCR web interface. + ''') + + def parse(self, cr, data): + result = [] + parser = BCRParser() + stmnt = statement() + + records = parser.parse_stamenent_record(data) + + stmnt._transmission_number(records) + stmnt._account_number(records) + stmnt._statement_number(records) + stmnt._opening_balance(records) + stmnt._closing_balance(records) + stmnt._forward_available(records) + stmnt._execution_date_transferred_amount (records) + stmnt._transaction_new(data) + + if stmnt.is_valid(): + result.append(stmnt) + + return result + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: === added file 'l10n_cr_account_banking_cr_bcr/mt940_parser.py' --- l10n_cr_account_banking_cr_bcr/mt940_parser.py 1970-01-01 00:00:00 +0000 +++ l10n_cr_account_banking_cr_bcr/mt940_parser.py 2012-07-06 05:13:21 +0000 @@ -0,0 +1,248 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2011 credativ Ltd (<http://www.credativ.co.uk>). +# All Rights Reserved +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +""" +Parser for BAC CR MT940 format files +Based on fi_patu's parser +""" +import re +from datetime import datetime +from dateutil import parser +import pprint +from copy import copy + +class BCRParser( object ): + + def statement_record ( self, rec ): + lines = [] + line_dict = {} + + line_dict = { + 'transref': 0.0, # _transmission_number + 'account_number': '', #_account_number + 'statementnr':'', # statement_number + 'startingbalance': 0.0, #_opening_balance + 'currencycode': 'CRC', #currencycode + 'endingbalance': 0.0, #_closing_balance + 'bookingdate': '', #moving_date + 'ammount': 0.0, + } + + #file = open( filename, 'r' ) + #line = file.readline() + + list_split = rec.split('\r\n') + + for l in list_split: + # _transmission_number + if l.find('Movimiento realizado el periodo', 0, len('Movimiento realizado el periodo')) > -1: + line_dict['statementnr'] = self.extract_number(l) + #_account_number + if l.find('Movimiento de Cuenta Corriente', 0, len('Movimiento de Cuenta Corriente')) > -1: + line_dict['account_number'] = self.extract_number(l) + # _transmission_number + if l.find('Solicitado el', 0, len('Solicitado el')) > -1 : + line_dict['transref'] = self.extract_number(l) + line_dict['bookingdate'] = self.extract_number(l) + #_opening_balance + if l.find('Saldo Inicial', 0, len('Saldo Inicial')) > -1: + line_dict['startingbalance'] = self.extract_float(l) + #_closing_balance + if l.find('Saldo Final', 0, len('Saldo Final')) > -1: + line_dict['endingbalance'] = self.extract_float(l) + + amount_statement = float( line_dict['startingbalance'] ) + float( line_dict['endingbalance'] ) + line_dict['ammount'] = amount_statement + + self.line_dict = line_dict + + return line_dict + + def statement_lines ( self, rec ): + parser = BCRParser() + mapping = { + 'execution_date' : '', + 'effective_date' : '', + 'local_currency' : '', + 'transfer_type' : '', + 'reference' : '', + 'message' : '', + 'name' : '', + 'transferred_amount': '', + 'creditmarker': '', + } + + lines = [] + line_dict = {} + + list_split = rec.split('\r\n') + entrada = False + start = 0 + end = 0 + + for l in list_split: + if l.find('TOTALES DEL MOVIMIENTO CONTABILIZADO', 0, len('TOTALES DEL MOVIMIENTO CONTABILIZADO')) <= -1: + end += 1 + else: + break + end = end - 1 + + for l in list_split: + if l.find('-CONTABLE-', 0, len('-CONTABLE-')) <= -1: + start += 1 + else: + break + start += 1 + + sub_list = list_split [start:end] + for sub in sub_list: + #03-05-12 + day = sub[0:2] + month = sub[3:5] + date_n = datetime.now() + try: + date = datetime(int(date_n.year), int(month), int (day)) + except Exception: + day = sub[1] + month = sub[4] + date_n = datetime.now() + date = datetime(int(date_n.year), int(month), int (day)) + + mapping['execution_date'] = date + mapping['effective_date'] = date + mapping['local_currency'] = 'CRC' + mapping['transfer_type'] = 'NTRF' + mapping['reference'] = parser.extract_number(sub[25:40]) + mapping['message'] = sub[26:92] + mapping['name'] = sub[26:92] + + amount = sub[106:] + amount.replace('\t',' ') + debit = amount[0:16] + credit = amount[16:] + + if (parser.extract_float(debit) is not ''): #debit + cad = parser.extract_float(debit) + mapping['transferred_amount'] = -float(cad) + mapping['creditmarker'] = 'C' + + else: #credit + cad = parser.extract_float (credit) + mapping['transferred_amount'] = float(cad) + + lines.append(copy(mapping)) + + return lines + + def parse_stamenent_record( self, rec ): + + matchdict = dict() + + matchdict = self.statement_record( rec ); + + # Remove members set to None + matchdict = dict( [( k, v ) for k, v in matchdict.iteritems() if v] ) + + matchkeys = set( matchdict.keys() ) + needstrip = set( [ 'transref', 'account_number', 'statementnr', 'currencycode', 'endingbalance', 'bookingdate'] ) + + for field in matchkeys & needstrip: + matchdict[field] = matchdict[field].strip() + + # Convert to float. Comma is decimal separator + needsfloat = set( ["startingbalance", "endingbalance", "amount"] ) + for field in matchkeys & needsfloat: + matchdict[field] = float( matchdict[field].replace( ',', '.' ) ) + + # Convert date fields + needdate = set( ["bookingdate"] ) + + for field in matchkeys & needdate: + datestring = matchdict[field] + try: + day = datestring[0:2] + month = datestring[2:4] + year = datestring[4:8] + hour = datestring[8:10] + minute = datestring[10:12] + second = datestring[12:14] + except Exception: + day = datestring[2] + month = datestring[4] + year = datestring[4:8] + hour = datestring[8:10] + minute = datestring[10:12] + second = datestring[12:14] + + date = datetime(int(year),int(month),int(day),int(hour),int(minute),int(second)) + matchdict[field] = date + + return matchdict + + def extract_number( self, account_number ): + cad = '' + result = re.findall(r'[0-9]+', account_number) + + for character in result: + cad = cad + character + return cad + + def extract_float ( self, ammount ): + cad = '' + result = re.findall(r"[-+]?\d*\.\d+|\d+",ammount) + + for character in result: + cad = cad + character + return cad + + def parse( self, cr, data ): + records = [] + # Some records are multiline + for line in data: + if len(line) <= 1: + continue + if line[0] == ':' and len(line) > 1: + records.append(line) + else: + records[-1] = '\n'.join([records[-1], line]) + + output = [] + + for rec in records: + output.append( self.parse_stamenent_record( rec ) ) + + return output + +def parse_file( filename ): + bacfile = open( filename, "r" ) + p = BCRParser().parse( bacfile.readlines() ) + +def main(): + """The main function, currently just calls a dummy filename + + :returns: description + """ + parse_file("testfile") + +if __name__ == '__main__': + main() +
_______________________________________________ Mailing list: https://launchpad.net/~clearcorp Post to : [email protected] Unsubscribe : https://launchpad.net/~clearcorp More help : https://help.launchpad.net/ListHelp

