Commit 75afbb15 authored by Kevin Deldycke's avatar Kevin Deldycke

better handling of bank account numbers (IBAN & BBAN)


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@2680 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent bcdd6881
...@@ -31,16 +31,16 @@ from AccessControl import ClassSecurityInfo ...@@ -31,16 +31,16 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.ERP5Type.Document.Folder import Folder from Products.ERP5Type.Document.Folder import Folder
from Products.ERP5.Document.Coordinate import Coordinate from Products.ERP5.Document.Coordinate import Coordinate
import string import string
class BankAccount(Folder, Coordinate): class BankAccount(Folder, Coordinate):
""" """
A bank account number holds a collection of numbers and codes (ex. SWIFT, RIB, etc.) which may be used to identify a bank account. A bank account number holds a collection of numbers and codes (ex. SWIFT, RIB, etc.) which may be used to identify a bank account.
A Bank Account is owned by a Person or an Organisation. A Bank Account contain Agents with Agent Privileges used by the owner to delegate the management of the bank account to trusted third-party Persons. A Bank Account is owned by a Person or an Organisation. A Bank Account contain Agents with Agent Privileges used by the owner to delegate the management of the bank account to trusted third-party Persons.
BankAccount inherits from Base and from the mix-in Coordinate. BankAccount inherits from Base and from the mix-in Coordinate.
""" """
...@@ -60,70 +60,119 @@ class BankAccount(Folder, Coordinate): ...@@ -60,70 +60,119 @@ class BankAccount(Folder, Coordinate):
, PropertySheet.SimpleItem , PropertySheet.SimpleItem
, PropertySheet.Task , PropertySheet.Task
, PropertySheet.Resource , PropertySheet.Resource
, PropertySheet.BankAccount , PropertySheet.BankAccount
) )
# Declarative interfaces # Declarative interfaces
__implements__ = ( Interface.Coordinate ) __implements__ = ( Interface.Coordinate )
security.declareProtected(Permissions.View, 'asText')
def asText(self): security.declareProtected(Permissions.View, 'getIbanTextFormat')
def getIbanTextFormat(self):
"""
Returns the standard IBAN text format
"""
iban = self.getIban()
l = 4
s = "IBAN"
for i in range((len(iban) / l) + 1):
s += ' ' + iban[i*l : (i+1)*l]
return s
security.declareProtected(Permissions.View, 'getIbanTextFormat')
def getIban(self):
""" """
Returns a string which identifies this bank account. The International Bank Account Number of this bank account.
Use IBAN if available, then an id code (ex. RIB; SWIFT) IBAN is an international standard for identifying bank accounts worldwide.
and finally a Bank / Branch / Number approach
""" """
if self.iban != '': key = self.getIbanKey()
return 'IBAN:%s' % self.iban country_code = self.getBankCountryCode()
if self.bank_account_id != '': bban = self.getBban()
return '%s:%s' % (self.bank_account_id_type, self.bank_account_id) if key == None: key = ''
if self.bank_name != '': if country_code == None: country_code = ''
return '%s / %s / %s' % (self.bank_name, self.bank_branch_name, if bban == None: bban = ''
self.bank_account_number) return (country_code + key + bban).upper()
return self.bank_account_number
security.declareProtected(Permissions.ModifyPortalContent, 'fromText') security.declareProtected(Permissions.View, 'getIbanKey')
def fromText(self, coordinate_text): def getIbanKey(self):
""" """
Tries to recognize the coordinate_text to update The IBAN key ensure the integry of the IBAN code.
this bank account It's calculated with the ISO 7064 method (known as "97-10 modulo").
""" """
self.iban = '' # Construct the alpha to number translation table
self.bank_name = '' table = {}
self.bank_branch_name = '' for i in range(26):
self.bank_account_number = '' table[chr(65+i)] = str(10+i)
self.bank_account_id_type = '' # Calcul the key
self.bank_account_id = '' country_code = self.getBankCountryCode() + '00'
if coordinate_text[0:4] == 'IBAN:': s = self.getBban() + country_code
self.iban = coordinate_text[5:] n = ''
self.reindexObject() for c in s:
return if c.isalpha():
coordinate_parts = string.split(coordinate_text, ':') n += table[c.upper()]
if len(coordinate_parts) > 1: if c.isdigit():
self.bank_account_id_type = coordinate_parts[0] n += c
self.bank_account_id = coordinate_parts[1] return str(98 - (int(n) % 97))
self.reindexObject()
return
coordinate_parts = string.split(coordinate_text, '/') security.declareProtected(Permissions.View, 'getBban')
if len(coordinate_parts) == 3: def getBban(self):
self.bank_name = coordinate_parts[0]
self.bank_branch_name = coordinate_parts[1]
self.bank_account_number = coordinate_parts[2]
self.reindexObject()
return
self.bank_account_number = coordinate_text
self.reindexObject()
security.declareProtected(Permissions.View, 'standardTextFormat')
def standardTextFormat(self):
""" """
Returns the standard text formats for bank accounts The Basic Bank Account Number (BBAN) is the last part of the IBAN.
Usualy it correspond to the national bank account number.
""" """
return ("""\ bank = self.getBankCode()
IBAN: FR76 3002 7175 3900 0410 2760 135 branch = self.getBranch()
""", """\ ban = self.getBankAccountNumber()
CIC / Calais / 3900 0410 2760 key = self.getBbanKey()
""", """\ if bank == None: bank = ''
RIB: FR76 3002 7175 3900 0410 2760 135 if branch == None: branch = ''
""", if ban == None: account_id = ''
) if key == None: key = ''
return (bank + branch + ban + key).upper()
security.declareProtected(Permissions.View, 'getBbanTextFormat')
def getBbanTextFormat(self, sep=' '):
"""
Returns a BBAN text format
"""
bank = self.getBankCode()
branch = self.getBranch()
ban = self.getBankAccountNumber()
key = self.getBbanKey()
if bank == None: bank = ''
if branch == None: branch = ''
if ban == None: account_id = ''
if key == None: key = ''
return sep.join([bank, branch, ban, key]).upper()
security.declareProtected(Permissions.View, 'getBbanKey')
def getBbanKey(self):
"""
The BBAN key ensure the integry of the BBAN code.
This is the french BBAN key algorithm.
"""
def transcode(string):
letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
digit = '12345678912345678923456789'
for i in range(len(letter)):
string = string.replace(letter[i], digit[i])
return int(string)
bank = self.getBankCode()
branch = self.getBranch()
ban = self.getBankAccountNumber()
if bank == None: bank = ''
if branch == None: branch = ''
if ban == None: ban = ''
bank += ('0' * (5 - len(bank)))
branch += ('0' * (5 - len(branch)))
s = (bank + branch + ban).upper()
return str(97 - ((transcode(s) * 100) % 97))
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment