From 4bbe2cfc1fc20bd0590ac35c6f4591a191d7b95d Mon Sep 17 00:00:00 2001 From: qdp Date: Wed, 1 Oct 2008 16:00:03 +0200 Subject: [PATCH] *added an integrity check of the iban account number *added an automatic formatting of the iban account number in order to comply with schema *added a function the compute the account bank number from the iban account number accordingly to the country rule *added comments *overall improvements bzr revid: qdp@tinyerp.com-20081001140003-pgvbxcr52jpwxnj6 --- addons/base_iban/base_iban.py | 87 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/addons/base_iban/base_iban.py b/addons/base_iban/base_iban.py index 870d7cb..d7ccef6 100644 --- a/addons/base_iban/base_iban.py +++ b/addons/base_iban/base_iban.py @@ -31,11 +31,52 @@ import netsvc from osv import fields, osv +def _format_iban(string): + ''' + This function removes all characters from given 'string' that isn't a alpha numeric and converts it to lower case. + ''' + res = "" + for char in string: + if char.isalnum(): + res += char.lower() + return res + class res_partner_bank(osv.osv): _inherit = "res.partner.bank" - _columns = { - 'iban': fields.char('IBAN', size=34, readonly=True, help="International Bank Account Number"), - } + + def create(self, cr, uid, vals, context={}): + #overwrite to format the iban number correctly + if vals.has_key('iban'): + vals['iban'] = _format_iban(vals['iban']) + return super(res_partner_bank, self).create(cr, uid, vals, context) + + def write(self, cr, uid, ids, vals, context={}): + #overwrite to format the iban number correctly + if vals.has_key('iban'): + vals['iban'] = _format_iban(vals['iban']) + return super(res_partner_bank, self).write(cr, uid, ids, vals, context) + + def check_iban(self, cr, uid, ids): + ''' + Check the IBAN number + ''' + for bank_acc in self.browse(cr, uid, ids): + if not bank_acc.iban: + continue + iban =_format_iban(bank_acc.iban) + #the four first digits have to be shifted to the end + iban = iban[4:] + iban[:4] + #letters have to be transformed into numbers (a = 10, b = 11, ...) + iban2 = "" + for char in iban: + if char.isalpha(): + iban2 += str(ord(char)-87) + else: + iban2 += char + #iban is correct if modulo 97 == 1 + if not int(iban2) % 97 == 1: + return False + return True def name_get(self, cr, uid, ids, context=None): res = [] @@ -48,18 +89,50 @@ class res_partner_bank(osv.osv): res += super(res_partner_bank, self).name_get(cr, uid, to_check_ids, context) return res - def search(self, cr, uid, args, offset=0, limit=None, order=None, - context=None, count=False): - res = super(res_partner_bank,self).search(cr, uid, args, offset, limit, - order, context=context, count=count) + def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): + #overwrite the search method in order to search not only on bank type == basic account number but also on type == iban + res = super(res_partner_bank,self).search(cr, uid, args, offset, limit, order, context=context, count=count) if filter(lambda x:x[0]=='acc_number' ,args): + #get the value of the search iban_value = filter(lambda x:x[0]=='acc_number' ,args)[0][2] + #get the other arguments of the search args1 = filter(lambda x:x[0]!='acc_number' ,args) + #add the new criterion args1 += [('iban','ilike',iban_value)] + #append the results to the older search res += super(res_partner_bank,self).search(cr, uid, args1, offset, limit, order, context=context, count=count) return res + def get_bban_from_iban(self, cr, uid, ids, context=None): + ''' + This function returns the bank account number computed from the iban account number, thanks to the mapping_list dictionary that contains the rules associated to its country. + ''' + res = {} + mapping_list = { + #TODO add rules for others countries + 'be': lambda x: x[4:], + 'fr': lambda x: x[14:], + 'ch': lambda x: x[9:], + 'gb': lambda x: x[14:], + } + for record in self.browse(cr, uid, ids, context): + if not record.iban: + res[record.id] = False + continue + res[record.id] = False + for code, function in mapping_list.items(): + if record.iban.lower().startswith(code): + res[record.id] = function(record.iban) + break + return res + + _columns = { + 'iban': fields.char('IBAN', size=34, readonly=True, help="International Bank Account Number"), + } + + _constraints = [(check_iban, "The IBAN number doesn't seem to be correct.", ["iban"])] + res_partner_bank() -- 1.7.10.4