IDEMPIERE-3304
Use apache commons-validator instead of own code to validate IBANs
This commit is contained in:
parent
61dee84cb4
commit
1c166a17f0
|
@ -15,6 +15,7 @@
|
||||||
<classpathentry exported="true" kind="lib" path="jfreechart-1.0.19.jar"/>
|
<classpathentry exported="true" kind="lib" path="jfreechart-1.0.19.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="jnlp.jar"/>
|
<classpathentry exported="true" kind="lib" path="jnlp.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="barcode4j-2.1.jar"/>
|
<classpathentry exported="true" kind="lib" path="barcode4j-2.1.jar"/>
|
||||||
|
<classpathentry exported="true" kind="lib" path="commons-validator-1.6.jar"/>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -12,7 +12,8 @@ Bundle-ClassPath: base.jar,
|
||||||
jfreechart-1.0.19.jar,
|
jfreechart-1.0.19.jar,
|
||||||
jnlp.jar,
|
jnlp.jar,
|
||||||
barcode4j-2.1.jar,
|
barcode4j-2.1.jar,
|
||||||
bsh-2.0b6.jar
|
bsh-2.0b6.jar,
|
||||||
|
commons-validator-1.6.jar
|
||||||
Export-Package: bsh,
|
Export-Package: bsh,
|
||||||
bsh.classpath,
|
bsh.classpath,
|
||||||
bsh.collection,
|
bsh.collection,
|
||||||
|
|
|
@ -27,7 +27,8 @@ bin.includes = META-INF/,\
|
||||||
OSGI-INF/addressvalidationeventhandler.xml,\
|
OSGI-INF/addressvalidationeventhandler.xml,\
|
||||||
schema/,\
|
schema/,\
|
||||||
barcode4j-2.1.jar,\
|
barcode4j-2.1.jar,\
|
||||||
bsh-2.0b6.jar
|
bsh-2.0b6.jar,\
|
||||||
|
commons-validator-1.6.jar
|
||||||
output.base.jar = bin/
|
output.base.jar = bin/
|
||||||
src.includes = schema/
|
src.includes = schema/
|
||||||
source.base.jar = src/
|
source.base.jar = src/
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<get src="${url.maven2.lib}/maven2/net/sourceforge/barbecue/barbecue/1.5-beta1/barbecue-1.5-beta1.jar" dest="barbecue-1.5-beta1.jar" usetimestamp="true" verbose="true" retries="5" />
|
<get src="${url.maven2.lib}/maven2/net/sourceforge/barbecue/barbecue/1.5-beta1/barbecue-1.5-beta1.jar" dest="barbecue-1.5-beta1.jar" usetimestamp="true" verbose="true" retries="5" />
|
||||||
<get src="${url.maven2.lib}/maven2/org/jfree/jcommon/1.0.23/jcommon-1.0.23.jar" dest="jcommon-1.0.23.jar" usetimestamp="true" verbose="true" retries="5" />
|
<get src="${url.maven2.lib}/maven2/org/jfree/jcommon/1.0.23/jcommon-1.0.23.jar" dest="jcommon-1.0.23.jar" usetimestamp="true" verbose="true" retries="5" />
|
||||||
<get src="${url.maven2.lib}/maven2/org/jfree/jfreechart/1.0.19/jfreechart-1.0.19.jar" dest="jfreechart-1.0.19.jar" usetimestamp="true" verbose="true" retries="5" />
|
<get src="${url.maven2.lib}/maven2/org/jfree/jfreechart/1.0.19/jfreechart-1.0.19.jar" dest="jfreechart-1.0.19.jar" usetimestamp="true" verbose="true" retries="5" />
|
||||||
|
<get src="${url.maven2.lib}/maven2/commons-validator/commons-validator/1.6/commons-validator-1.6.jar" dest="commons-validator-1.6.jar" usetimestamp="true" verbose="true" retries="5" />
|
||||||
<!-- jnlp is not used in idempiere? -->
|
<!-- jnlp is not used in idempiere? -->
|
||||||
<get src="${url.maven2.lib}/maven2/net/sf/barcode4j/barcode4j/2.1/barcode4j-2.1.jar" dest="barcode4j-2.1.jar" usetimestamp="true" verbose="true" retries="5" />
|
<get src="${url.maven2.lib}/maven2/net/sf/barcode4j/barcode4j/2.1/barcode4j-2.1.jar" dest="barcode4j-2.1.jar" usetimestamp="true" verbose="true" retries="5" />
|
||||||
<get src="${url.file.srv}/jarfile/4.1/jnlp.jar" dest="jnlp.jar" usetimestamp="true" verbose="true" retries="5" />
|
<get src="${url.file.srv}/jarfile/4.1/jnlp.jar" dest="jnlp.jar" usetimestamp="true" verbose="true" retries="5" />
|
||||||
|
|
|
@ -213,7 +213,7 @@ public class MBPBankAccount extends X_C_BP_BankAccount
|
||||||
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
||||||
if (!Util.isEmpty(getIBAN())) {
|
if (!Util.isEmpty(getIBAN())) {
|
||||||
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
||||||
if (!IBAN.isCheckDigitValid(getIBAN())) {
|
if (!IBAN.isValid(getIBAN())) {
|
||||||
log.saveError("Error", "IBAN is invalid");
|
log.saveError("Error", "IBAN is invalid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class MBankAccount extends X_C_BankAccount
|
||||||
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
||||||
if (!Util.isEmpty(getIBAN())) {
|
if (!Util.isEmpty(getIBAN())) {
|
||||||
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
||||||
if (!IBAN.isCheckDigitValid(getIBAN())) {
|
if (!IBAN.isValid(getIBAN())) {
|
||||||
log.saveError("Error", "IBAN is invalid");
|
log.saveError("Error", "IBAN is invalid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -801,7 +801,7 @@ public class MPayment extends X_C_Payment
|
||||||
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
||||||
if (!Util.isEmpty(getIBAN())) {
|
if (!Util.isEmpty(getIBAN())) {
|
||||||
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
||||||
if (!IBAN.isCheckDigitValid(getIBAN())) {
|
if (!IBAN.isValid(getIBAN())) {
|
||||||
log.saveError("Error", "IBAN is invalid");
|
log.saveError("Error", "IBAN is invalid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class MPaymentTransaction extends X_C_PaymentTransaction implements Proce
|
||||||
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
if (MSysConfig.getBooleanValue(MSysConfig.IBAN_VALIDATION, true, Env.getAD_Client_ID(Env.getCtx()))) {
|
||||||
if (!Util.isEmpty(getIBAN())) {
|
if (!Util.isEmpty(getIBAN())) {
|
||||||
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
setIBAN(IBAN.normalizeIBAN(getIBAN()));
|
||||||
if (!IBAN.isCheckDigitValid(getIBAN())) {
|
if (!IBAN.isValid(getIBAN())) {
|
||||||
log.saveError("Error", "IBAN is invalid");
|
log.saveError("Error", "IBAN is invalid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
// adapted from http://how-blogz.blogspot.de/2007/08/java-iban-check-digit-validation.html
|
/******************************************************************************
|
||||||
// soastation.banking.IBAN
|
* Product: iDempiere Business Suite ERP/CRM/SCM *
|
||||||
|
* Copyright (C) 2017 Markus Bozem *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. 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 General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * *
|
||||||
|
*****************************************************************************/
|
||||||
package org.compiere.util;
|
package org.compiere.util;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import org.apache.commons.validator.routines.IBANValidator;
|
||||||
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
public class IBAN {
|
public class IBAN {
|
||||||
|
|
||||||
|
@ -22,73 +30,16 @@ public class IBAN {
|
||||||
}
|
}
|
||||||
return null ;
|
return null ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the given IBAN is valid based on the check digit. To
|
|
||||||
* validate the checksum: 1. Check that the total IBAN length is correct as
|
|
||||||
* per the country. If not, the IBAN is invalid. 2. Move the four initial
|
|
||||||
* characters to the end of the string. 3. Replace the letters in the string
|
|
||||||
* with digits, expanding the string as necessary, such that A=10, B=11 and
|
|
||||||
* Z=35. 4. Convert the string to an integer and mod-97 the entire number.
|
|
||||||
* If the remainder is 1 you have a valid IBAN number.
|
|
||||||
*
|
|
||||||
* @param iban
|
* @param iban
|
||||||
* @return boolean indicating if specific IBAN has a valid check digit
|
* @return boolean indicating if specific IBAN is valid
|
||||||
*/
|
*/
|
||||||
public static boolean isCheckDigitValid(String iban) {
|
|
||||||
try {
|
|
||||||
if (null == iban)
|
|
||||||
return false;
|
|
||||||
int validIBANLength = getValidIBANLength(iban);
|
|
||||||
if (validIBANLength < 4)
|
|
||||||
return false;
|
|
||||||
if (iban.length() != validIBANLength)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
BigInteger numericIBAN = getNumericIBAN(iban, false);
|
public static boolean isValid(String iban) {
|
||||||
|
IBANValidator iBANValidator = IBANValidator.getInstance() ;
|
||||||
|
|
||||||
int checkDigit = numericIBAN.mod(new BigInteger("97")).intValue();
|
return iBANValidator.isValid(iban) ;
|
||||||
return checkDigit == 1;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Using the IBAN.properties file gets the valid fixed length value for a
|
|
||||||
* country code. Only uses the first 2 characters of the given string.
|
|
||||||
*
|
|
||||||
* @param countryCode
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static int getValidIBANLength(String countryCode) {
|
|
||||||
String code = countryCode.substring(0, 2).toUpperCase();
|
|
||||||
String length = ResourceBundle.getBundle(IBAN.class.getCanonicalName()).getString("length." + code);
|
|
||||||
if (length == null)
|
|
||||||
return -1;
|
|
||||||
return Integer.valueOf(length).intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BigInteger getNumericIBAN(String iban, boolean isCheckDigitAtEnd) {
|
|
||||||
String endCheckDigitIBAN = iban;
|
|
||||||
if (!isCheckDigitAtEnd) {
|
|
||||||
// Move first four characters to end of string to put check digit at
|
|
||||||
// end
|
|
||||||
endCheckDigitIBAN = iban.substring(4) + iban.substring(0, 4);
|
|
||||||
}
|
|
||||||
StringBuffer numericIBAN = new StringBuffer();
|
|
||||||
for (int i = 0; i < endCheckDigitIBAN.length(); i++) {
|
|
||||||
if (Character.isDigit(endCheckDigitIBAN.charAt(i))) {
|
|
||||||
numericIBAN.append(endCheckDigitIBAN.charAt(i));
|
|
||||||
} else {
|
|
||||||
numericIBAN.append(10 + getAlphabetPosition(endCheckDigitIBAN.charAt(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigInteger(numericIBAN.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getAlphabetPosition(char letter) {
|
|
||||||
return Character.valueOf(Character.toUpperCase(letter)).compareTo(Character.valueOf('A'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
# IBAN related properties. Includes IBAN lengths for different countries
|
|
||||||
length.AD=24
|
|
||||||
length.AT=20
|
|
||||||
length.BE=16
|
|
||||||
length.BA=20
|
|
||||||
length.BG=22
|
|
||||||
length.CH=21
|
|
||||||
length.CY=28
|
|
||||||
length.CZ=24
|
|
||||||
length.DE=22
|
|
||||||
length.DK=18
|
|
||||||
length.EE=20
|
|
||||||
length.ES=24
|
|
||||||
length.FO=18
|
|
||||||
length.FI=18
|
|
||||||
length.FR=27
|
|
||||||
length.GB=22
|
|
||||||
length.GI=23
|
|
||||||
length.GL=18
|
|
||||||
length.GR=27
|
|
||||||
length.HU=28
|
|
||||||
length.HR=21
|
|
||||||
length.IE=22
|
|
||||||
length.IS=26
|
|
||||||
length.IT=27
|
|
||||||
length.LI=21
|
|
||||||
length.LT=20
|
|
||||||
length.LU=20
|
|
||||||
length.LV=21
|
|
||||||
length.MA=24
|
|
||||||
length.MC=27
|
|
||||||
length.MK=19
|
|
||||||
length.MT=31
|
|
||||||
length.NL=18
|
|
||||||
length.NO=15
|
|
||||||
length.PL=28
|
|
||||||
length.PT=25
|
|
||||||
length.RO=24
|
|
||||||
length.RS=22
|
|
||||||
length.SE=24
|
|
||||||
length.SI=19
|
|
||||||
length.SK=24
|
|
||||||
length.SM=27
|
|
||||||
length.TN=24
|
|
||||||
length.TR=26
|
|
Loading…
Reference in New Issue