[MERGE] l10n_fr_rib: improve check of RIB and IBAN (contrib from Akretion)

bzr revid: rco@openerp.com-20120201110507-ztz2ss626svv2jl6
This commit is contained in:
Raphael Collet 2012-02-01 12:05:07 +01:00
commit c0534b0100
7 changed files with 207 additions and 133 deletions

View File

@ -94,27 +94,34 @@ class res_partner_bank(osv.osv):
vals['acc_number'] = _pretty_iban(vals['acc_number'])
return super(res_partner_bank, self).write(cr, uid, ids, vals, context)
def is_iban_valid(self, cr, uid, iban, context=None):
""" Check if IBAN is valid or not
@param iban: IBAN as string
@return: True if IBAN is valid, False otherwise
"""
iban = _format_iban(iban).lower()
if iban[:2] in _ref_iban and len(iban) != len(_format_iban(_ref_iban[iban[:2]])):
return False
#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
return int(iban2) % 97 == 1
def check_iban(self, cr, uid, ids, context=None):
'''
Check the IBAN number
'''
for bank_acc in self.browse(cr, uid, ids, context=context):
if bank_acc.state<>'iban':
if bank_acc.state != 'iban':
continue
iban = _format_iban(bank_acc.acc_number).lower()
if iban[:2] in _ref_iban and len(iban) != len(_format_iban(_ref_iban[iban[:2]])):
return False
#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:
if not self.is_iban_valid(cr, uid, bank_acc.acc_number, context=context):
return False
return True

View File

@ -38,7 +38,7 @@ The module base_iban can be a useful addition to this module, because French ban
The RIB and IBAN codes for a single account can be entered by recording two Bank Accounts in OpenERP: the first with the type "RIB", the second with the type "IBAN".
''',
'author' : u'Numérigraphe SARL',
'depends': ['base', 'account'],
'depends': ['account', 'base_iban'],
'init_xml': ['bank_data.xml', ],
'update_xml': ['bank_view.xml', ],
'installable': True,

View File

@ -31,18 +31,17 @@ class res_partner_bank(osv.osv):
"""Check the RIB key"""
for bank_acc in self.browse(cr, uid, ids):
# Ignore the accounts of type other than rib
if bank_acc.state !='rib':
if bank_acc.state != 'rib':
continue
# Fail if the needed values are empty of too short
if (not bank_acc.bank_code
or len(bank_acc.bank_code) != 5
or not bank_acc.office or len(bank_acc.office) != 5
or not bank_acc.acc_number or len(bank_acc.acc_number) != 11
or not bank_acc.rib_acc_number or len(bank_acc.rib_acc_number) != 11
or not bank_acc.key or len(bank_acc.key) != 2):
return False
# Get the rib data (without the key)
rib = "%s%s%s" % (bank_acc.bank_code, bank_acc.office,
bank_acc.acc_number)
rib = "%s%s%s" % (bank_acc.bank_code, bank_acc.office, bank_acc.rib_acc_number)
# Translate letters into numbers according to a specific table
# (notice how s -> 2)
table = dict((ord(a), b) for a, b in zip(
@ -51,7 +50,12 @@ class res_partner_bank(osv.osv):
# compute the key
key = 97 - (100 * int(rib)) % 97
if int(bank_acc.key) != key:
return False
raise osv.except_osv(_('Error'),
_("The RIB key %s does not correspond to the other codes: %s %s %s.") % \
(bank_acc.key, bank_acc.bank_code, bank_acc.office, bank_acc.rib_acc_number) )
if bank_acc.acc_number:
if not self.is_iban_valid(cr, uid, bank_acc.acc_number):
raise osv.except_osv(_('Error'), _("The IBAN %s is not valid.") % bank_acc.acc_number)
return True
def onchange_bank_id(self, cr, uid, ids, bank_id, context=None):
@ -66,31 +70,17 @@ class res_partner_bank(osv.osv):
return result
_columns = {
'acc_number': fields.char('Account Number', size=64, required=False),
'rib_acc_number': fields.char('RIB account number', size=11, readonly=True,),
'bank_code': fields.char('Bank Code', size=64, readonly=True,),
'office': fields.char('Office Code', size=5, readonly=True,),
'key': fields.char('Key', size=2, readonly=True,
help="The key is a number allowing to check the "
"correctness of the other codes."),
}
def _construct_constraint_msg(self, cr, uid, ids, context=None):
"""Quote the data in the warning message"""
# Only process the first id
if type(ids) not in (int, long):
id = ids[0]
rib = self.browse(cr, uid, id, context=context)
if rib:
return (_("\nThe RIB key %s does not correspond to the other "
"codes: %s %s %s.") %
(rib.key,
rib.bank_code,
rib.office,
rib.acc_number) )
_constraints = [(_check_key,
_construct_constraint_msg,
["key"])]
_constraints = [(_check_key, 'The RIB and/or IBAN is not valid', ['rib_acc_number', 'bank_code', 'office', 'key'])]
res_partner_bank()
class res_bank(osv.osv):

View File

@ -6,24 +6,27 @@
RIB bank details
-->
<record id="bank_rib" model="res.partner.bank.type">
<field name="name">RIB Bank Details</field>
<field name="name">RIB and optional IBAN</field>
<field name="code">rib</field>
<field name="format_layout">%(bank_name)s: %(bank_code)s %(office)s %(rib_acc_number)s %(key)s</field>
</record>
<record id="rib_bank_code_field" model="res.partner.bank.type.field">
<field name="name">bank_code</field>
<field name="bank_type_id" ref="bank_rib"/>
<field eval="True" name="required"/>
<field eval="False" name="readonly"/>
<field name="size">5</field>
</record>
<record id="rib_office_field" model="res.partner.bank.type.field">
<field name="name">office</field>
<field name="bank_type_id" ref="bank_rib"/>
<field eval="True" name="required"/>
<field eval="False" name="readonly"/>
<field name="size">5</field>
</record>
<record id="bank_acc_number_field" model="res.partner.bank.type.field">
<field name="name">acc_number</field>
<record id="rib_rib_acc_number_field" model="res.partner.bank.type.field">
<field name="name">rib_acc_number</field>
<field name="bank_type_id" ref="bank_rib"/>
<field eval="True" name="required"/>
<field eval="False" name="readonly"/>
@ -34,11 +37,19 @@
<field name="bank_type_id" ref="bank_rib"/>
<field eval="True" name="required"/>
<field eval="False" name="readonly"/>
<field name="size">2</field>
</record>
<record id="rib_acc_number_field" model="res.partner.bank.type.field">
<field name="name">acc_number</field>
<field name="bank_type_id" ref="bank_rib"/>
<field eval="False" name="required"/>
<field eval="False" name="readonly"/>
</record>
<record id="rib_bic_field" model="res.partner.bank.type.field">
<field name="name">bank_bic</field>
<field name="bank_type_id" ref="bank_rib"/>
<field name="required" eval="0"/>
<field name="required" eval="False"/>
</record>
</data>
</openerp>

View File

@ -1,44 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- add the fields for French RIB to the partner form (subform)-->
<record id="view_partner_rib1_form" model="ir.ui.view">
<field name="name">res.partner.form.rib1.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="type">form</field>
<field name="arch" type="xml">
<field name="acc_number" position="before">
<newline />
<field name="bank_code" />
<field name="office" />
<newline />
</field>
</field>
</record>
<record id="view_partner_rib2_form" model="ir.ui.view">
<field name="name">res.partner.form.rib2.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="type">form</field>
<field name="arch" type="xml">
<field name="acc_number" position="after">
<field name="key" />
</field>
</field>
</record>
<!-- add the bank code-->
<record id="view_res_bank_form" model="ir.ui.view">
<field name="name">res.bank.form.rib.inherit</field>
<field name="model">res.bank</field>
<field name="inherit_id" ref="base.view_res_bank_form" />
<field name="type">form</field>
<field name="arch" type="xml">
<field name="bic" position="before">
<field name="rib_code" />
</field>
</field>
</record>
</data>
<data>
<!-- add the fields for French RIB to the partner form (subform)-->
<record id="view_partner_rib1_form" model="ir.ui.view">
<field name="name">res.partner.form.rib1.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.view_partner_property_form" />
<field name="type">form</field>
<field name="arch" type="xml">
<data>
<xpath expr="/form/notebook/page[@string='Accounting']/field[@name='bank_ids']/form/field[@name='acc_number']" position="before">
<newline />
<field name="bank_code" />
<field name="office" />
<field name="rib_acc_number" />
<field name="key" />
<newline />
</xpath>
<xpath expr="/form/notebook/page[@string='Accounting']/field[@name='bank_ids']/tree/field[@name='acc_number']" position="after">
<field name="rib_acc_number"/>
</xpath>
</data>
</field>
</record>
<!-- add RIB fields to the form view of res.partner.bank -->
<record id="view_partner_bank_rib_form" model="ir.ui.view">
<field name="name">res.partner.bank.form.rib.inherit</field>
<field name="model">res.partner.bank</field>
<field name="inherit_id" ref="base.view_partner_bank_form" />
<field name="type">form</field>
<field name="arch" type="xml">
<field name="acc_number" position="before">
<field name="bank_code" />
<field name="office" />
<newline />
<field name="rib_acc_number" />
<field name="key" />
<newline />
</field>
</field>
</record>
<!-- add rib_acc_number to the tree view of res.partner.bank -->
<record id="view_partner_bank_rib_tree" model="ir.ui.view">
<field name="name">res.partner.bank.tree.rib.inherit</field>
<field name="model">res.partner.bank</field>
<field name="inherit_id" ref="base.view_partner_bank_tree" />
<field name="type">tree</field>
<field name="arch" type="xml">
<field name="acc_number" position="after">
<field name="rib_acc_number" />
</field>
</field>
</record>
<!-- add the bank code-->
<record id="view_res_bank_form" model="ir.ui.view">
<field name="name">res.bank.form.rib.inherit</field>
<field name="model">res.bank</field>
<field name="inherit_id" ref="base.view_res_bank_form" />
<field name="type">form</field>
<field name="arch" type="xml">
<field name="bic" position="before">
<field name="rib_code" />
</field>
</field>
</record>
</data>
</openerp>

View File

@ -4,10 +4,10 @@
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1beta\n"
"Project-Id-Version: OpenERP Server 6.1rc1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-11-21 12:37+0000\n"
"PO-Revision-Date: 2011-11-21 12:37+0000\n"
"POT-Creation-Date: 2012-01-27 18:47+0000\n"
"PO-Revision-Date: 2012-01-27 18:47+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -23,9 +23,14 @@ msgstr "\n"
"Please define BIC/Swift code on bank for bank type IBAN Account to make valid payments"
#. module: l10n_fr_rib
#: model:ir.model,name:l10n_fr_rib.model_res_partner_bank
msgid "Bank Accounts"
msgstr "Comptes bancaires"
#: model:res.partner.bank.type,name:l10n_fr_rib.bank_rib
msgid "RIB and optional IBAN"
msgstr "RIB et IBAN optionnel"
#. module: l10n_fr_rib
#: field:res.partner.bank,rib_acc_number:0
msgid "RIB account number"
msgstr "Numéro de compte RIB"
#. module: l10n_fr_rib
#: field:res.partner.bank,bank_code:0
@ -33,9 +38,10 @@ msgid "Bank Code"
msgstr "Code banque"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bic_field
msgid "bank_bic"
msgstr "bank_bic"
#: code:addons/l10n_fr_rib/bank.py:55
#, python-format
msgid "The RIB key %s does not correspond to the other codes: %s %s %s."
msgstr "La clé RIB %s ne correspond pas aux autres codes : %s %s %s."
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_office_field
@ -48,13 +54,15 @@ msgid "RIB Bank Code"
msgstr "Code banque RIB"
#. module: l10n_fr_rib
#: model:ir.module.module,description:l10n_fr_rib.module_meta_information
msgid "\n"
"This module installs the base for RIB bank accounts (French standard for bank accounts). \n"
"To make it easier to enter RIB data, it will also allow to search for banks by code."
msgstr "\n"
"Ce module installe la base pour les comptes bancaires RIB (norme française pour les n° de compte). \n"
"Pour faciliter la saisie des RIBs, il permet aussi de chercher les banques par code."
#: code:addons/l10n_fr_rib/bank.py:62
#, python-format
msgid "The IBAN %s is not valid."
msgstr "L'IBAN %s n'est pas valide."
#. module: l10n_fr_rib
#: model:ir.model,name:l10n_fr_rib.model_res_partner_bank
msgid "Bank Accounts"
msgstr "Comptes bancaires"
#. module: l10n_fr_rib
#: field:res.partner.bank,office:0
@ -62,43 +70,47 @@ msgid "Office Code"
msgstr "Code agence"
#. module: l10n_fr_rib
#: model:res.partner.bank.type,name:l10n_fr_rib.bank_rib
msgid "RIB Bank Details"
msgstr "Relevé d'identité bancaire (RIB)"
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_rib_acc_number_field
msgid "rib_acc_number"
msgstr "rib_acc_number"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bank_code_field
msgid "bank_code"
msgstr "bank_code"
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:109
#, python-format
msgid "\n"
"The RIB key %s does not correspond to the other codes: %s %s %s."
msgstr "\n"
"La clé RIB %s ne correspond pas aux autres codes : %s %s %s."
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_key_field
msgid "key"
msgstr "key"
#. module: l10n_fr_rib
#: model:ir.module.module,shortdesc:l10n_fr_rib.module_meta_information
msgid "French RIB Bank Details"
msgstr "Relevés d'identité bancaire français (RIB)"
#. module: l10n_fr_rib
#: help:res.partner.bank,key:0
msgid "The key is a number allowing to check the correctness of the other codes."
msgstr "La clé est un nombre permettant de vérifier que les autres codes sont corrects."
#. module: l10n_fr_rib
#: constraint:res.partner.bank:0
msgid "Error message in raise"
msgstr "Error message in raise"
#. module: l10n_fr_rib
#: field:res.partner.bank,key:0
msgid "Key"
msgstr "Clé"
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:54
#: code:addons/l10n_fr_rib/bank.py:61
#, python-format
msgid "Error"
msgstr "Error"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bic_field
msgid "bank_bic"
msgstr "bank_bic"
#. module: l10n_fr_rib
#: model:res.partner.bank.type,format_layout:l10n_fr_rib.bank_rib
msgid "%(bank_name)s: %(acc_number)s"
@ -110,7 +122,7 @@ msgid "Bank"
msgstr "Banque"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.bank_acc_number_field
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_acc_number_field
msgid "acc_number"
msgstr "acc_number"

View File

@ -4,10 +4,10 @@
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1beta\n"
"Project-Id-Version: OpenERP Server 6.1rc1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-12-22 18:45+0000\n"
"PO-Revision-Date: 2011-12-22 18:45+0000\n"
"POT-Creation-Date: 2012-01-27 18:47+0000\n"
"PO-Revision-Date: 2012-01-27 18:47+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -21,14 +21,25 @@ msgid "\n"
"Please define BIC/Swift code on bank for bank type IBAN Account to make valid payments"
msgstr ""
#. module: l10n_fr_rib
#: model:res.partner.bank.type,name:l10n_fr_rib.bank_rib
msgid "RIB and optional IBAN"
msgstr ""
#. module: l10n_fr_rib
#: field:res.partner.bank,rib_acc_number:0
msgid "RIB account number"
msgstr ""
#. module: l10n_fr_rib
#: field:res.partner.bank,bank_code:0
msgid "Bank Code"
msgstr ""
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bic_field
msgid "bank_bic"
#: code:addons/l10n_fr_rib/bank.py:55
#, python-format
msgid "The RIB key %s does not correspond to the other codes: %s %s %s."
msgstr ""
#. module: l10n_fr_rib
@ -41,6 +52,12 @@ msgstr ""
msgid "RIB Bank Code"
msgstr ""
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:62
#, python-format
msgid "The IBAN %s is not valid."
msgstr ""
#. module: l10n_fr_rib
#: model:ir.model,name:l10n_fr_rib.model_res_partner_bank
msgid "Bank Accounts"
@ -52,8 +69,8 @@ msgid "Office Code"
msgstr ""
#. module: l10n_fr_rib
#: model:res.partner.bank.type,name:l10n_fr_rib.bank_rib
msgid "RIB Bank Details"
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_rib_acc_number_field
msgid "rib_acc_number"
msgstr ""
#. module: l10n_fr_rib
@ -61,13 +78,6 @@ msgstr ""
msgid "bank_code"
msgstr ""
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:83
#, python-format
msgid "\n"
"The RIB key %s does not correspond to the other codes: %s %s %s."
msgstr ""
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_key_field
msgid "key"
@ -78,11 +88,28 @@ msgstr ""
msgid "The key is a number allowing to check the correctness of the other codes."
msgstr ""
#. module: l10n_fr_rib
#: constraint:res.partner.bank:0
msgid "Error message in raise"
msgstr ""
#. module: l10n_fr_rib
#: field:res.partner.bank,key:0
msgid "Key"
msgstr ""
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:54
#: code:addons/l10n_fr_rib/bank.py:61
#, python-format
msgid "Error"
msgstr ""
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bic_field
msgid "bank_bic"
msgstr ""
#. module: l10n_fr_rib
#: model:res.partner.bank.type,format_layout:l10n_fr_rib.bank_rib
msgid "%(bank_name)s: %(acc_number)s"
@ -94,7 +121,7 @@ msgid "Bank"
msgstr ""
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.bank_acc_number_field
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_acc_number_field
msgid "acc_number"
msgstr ""