de.knightsoftnet.validators.shared.impl.AbstractTaxTinNumberValidator Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package de.knightsoftnet.validators.shared.impl;
import org.apache.commons.lang3.StringUtils;
import java.lang.annotation.Annotation;
import jakarta.validation.ConstraintValidator;
/**
* Common Stuff from Tax and Tin Validator.
*
* @author Manfred Tremmel
*
*/
public abstract class AbstractTaxTinNumberValidator
implements ConstraintValidator {
/**
* modulo 11.
*/
protected static final int MODULO_11 = 11;
/**
* error message key.
*/
protected String message;
/**
* field name of the country code field.
*/
protected String fieldCountryCode;
/**
* are lower case country codes allowed (true/false).
*/
protected boolean allowLowerCaseCountryCode;
/**
* check the Tax Number/Tax Identification Number, country version for Austria.
*
* @param number tax number/tax identification number to check
* @return true if checksum is ok
*/
protected boolean checkAtNumber(final String number) {
final int checkSum = number.charAt(8) - '0';
final int sum = number.charAt(0) - '0' + squareSum((number.charAt(1) - '0') * 2) //
+ number.charAt(2) - '0' + squareSum((number.charAt(3) - '0') * 2) //
+ number.charAt(4) - '0' + squareSum((number.charAt(5) - '0') * 2) //
+ number.charAt(6) - '0' + squareSum((number.charAt(7) - '0') * 2);
final int calculatedCheckSum = (80 - sum) % 10;
return checkSum == calculatedCheckSum;
}
/**
* check the Tax Identification Number number, country version for Denmark.
*
* @param number vat id to check
* @return true if checksum is ok
*/
protected boolean checkDk(final String number) {
final int checkSum = number.charAt(9) - '0';
final int sum = ((number.charAt(0) - '0') * 4 //
+ (number.charAt(1) - '0') * 2 //
+ (number.charAt(2) - '0') * 3 //
+ (number.charAt(3) - '0') * 7 //
+ (number.charAt(4) - '0') * 6 //
+ (number.charAt(5) - '0') * 5 //
+ (number.charAt(6) - '0') * 4 //
+ (number.charAt(7) - '0') * 3 //
+ (number.charAt(8) - '0') * 2) //
% MODULO_11;
int calculatedCheckSum = MODULO_11 - sum;
if (calculatedCheckSum == 10) {
calculatedCheckSum = 0;
}
return checkSum == calculatedCheckSum;
}
/**
* check the Tax Identification Number number, country version for Estonia.
*
* @param number vat id to check
* @return true if checksum is ok
*/
protected boolean checkEe(final String number) {
final int checkSum = number.charAt(10) - '0';
int calculatedCheckSum = ((number.charAt(0) - '0') * 1 //
+ (number.charAt(1) - '0') * 2 //
+ (number.charAt(2) - '0') * 3 //
+ (number.charAt(3) - '0') * 4 //
+ (number.charAt(4) - '0') * 5 //
+ (number.charAt(5) - '0') * 6 //
+ (number.charAt(6) - '0') * 7 //
+ (number.charAt(7) - '0') * 8 //
+ (number.charAt(8) - '0') * 9 //
+ (number.charAt(9) - '0') * 1) //
% MODULO_11;
if (calculatedCheckSum == 10) {
calculatedCheckSum = ((number.charAt(0) - '0') * 3 //
+ (number.charAt(1) - '0') * 4 //
+ (number.charAt(2) - '0') * 5 //
+ (number.charAt(3) - '0') * 6 //
+ (number.charAt(4) - '0') * 7 //
+ (number.charAt(5) - '0') * 8 //
+ (number.charAt(6) - '0') * 9 //
+ (number.charAt(7) - '0') * 1 //
+ (number.charAt(8) - '0') * 2 //
+ (number.charAt(9) - '0') * 3) //
% MODULO_11 % 10;
}
return checkSum == calculatedCheckSum;
}
/**
* check the Tax Identification Number number, country version for Spain.
*
* @param number vat id to check
* @return true if checksum is ok
*/
protected boolean checkEs(final String number) {
final char[] checkArray = {'T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J',
'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E'};
final char checkSum = number.charAt(8);
final char calculatedCheckSum;
final int sum;
if (StringUtils.isNumeric(StringUtils.substring(number, 0, 8))) {
// dni
sum = Integer.parseInt(StringUtils.substring(number, 0, 8)) % 23;
calculatedCheckSum = checkArray[sum];
} else if (number.charAt(0) >= 'X' && number.charAt(0) <= 'Z') {
// cif
sum = Integer.parseInt(number.charAt(0) - '0' + StringUtils.substring(number, 1, 8)) % 23;
calculatedCheckSum = checkArray[sum];
} else {
// nie
final char letter = number.charAt(0);
final String numberWork = StringUtils.substring(number, 1, 8);
int evenSum = 0;
int oddSum = 0;
for (int i = 0; i < numberWork.length(); i++) {
int charAsNum = numberWork.charAt(i) - '0';
// Odd positions (Even index equals to odd position. i=0 equals first position)
if (i % 2 == 0) {
// Odd positions are multiplied first.
charAsNum *= 2;
// If the multiplication is bigger than 10 we need to adjust
oddSum += charAsNum < 10 ? charAsNum : charAsNum - 9;
// Even positions
// Just sum them
} else {
evenSum += charAsNum;
}
}
final int control_digit = (10 - (evenSum + oddSum) % 10) % 10;
final char control_letter = "JABCDEFGHI".charAt(control_digit);
switch (letter) {
case 'A':
case 'B':
case 'E':
case 'H':
// Control must be a digit
calculatedCheckSum = (char) (control_digit + '0');
break;
case 'K':
case 'P':
case 'Q':
case 'S':
// Control must be a letter
calculatedCheckSum = control_letter;
break;
default:
// Can be either
if (control_letter == checkSum) {
calculatedCheckSum = control_letter;
} else {
calculatedCheckSum = (char) (control_digit + '0');
}
break;
}
}
return checkSum == calculatedCheckSum;
}
/**
* check the Tax Identification Number number, default modulo 11.
*
* @param number vat id to check
* @return true if checksum is ok
*/
protected boolean checkModulo11(final String number) {
final int checkSum = number.charAt(number.length() - 1) - '0';
int sum = 10;
for (int i = 0; i < number.length() - 1; i++) {
int summe = (number.charAt(i) - '0' + sum) % 10;
if (summe == 0) {
summe = 10;
}
sum = 2 * summe % MODULO_11;
}
int calculatedCheckSum = MODULO_11 - sum;
if (calculatedCheckSum == 10) {
calculatedCheckSum = 0;
}
return checkSum == calculatedCheckSum;
}
/**
* check the Tax Identification Number number, country version for countries using unique master
* citizen number .
*
* @param number vat id to check
* @return true if checksum is ok
*/
protected boolean checkUniqueMasterCitizenNumber(final String number) {
final int checkSum = number.charAt(12) - '0';
final int sum = ((number.charAt(0) - '0' + number.charAt(6) - '0') * 7 //
+ (number.charAt(1) - '0' + number.charAt(7) - '0') * 6 //
+ (number.charAt(2) - '0' + number.charAt(8) - '0') * 5 //
+ (number.charAt(3) - '0' + number.charAt(9) - '0') * 4 //
+ (number.charAt(4) - '0' + number.charAt(10) - '0') * 3 //
+ (number.charAt(5) - '0' + number.charAt(11) - '0') * 2) //
% MODULO_11;
int calculatedCheckSum = MODULO_11 - sum;
if (calculatedCheckSum == 10) {
calculatedCheckSum = 0;
}
return checkSum == calculatedCheckSum;
}
/**
* check the Tax Identification Number number, country version for Netherlands.
*
* @param number vat id to check
* @return true if checksum is ok
*/
protected boolean checkNl(final String number) {
final int checkSum = number.charAt(8) - '0';
int sum = 0;
for (int i = 0; i < number.length() - 1; i++) {
sum += (number.charAt(i) - '0') * (9 - i);
}
sum -= checkSum;
return sum % 11 == 0;
}
/**
* check the Tax Identification Number number, country version for Poland.
*
* @param number vat id to check
* @return true if checksum is ok
*/
protected boolean checkPl(final String number) {
final int checkSum = number.charAt(number.length() - 1) - '0';
int calculatedCheckSum;
if (StringUtils.length(number) == 11) {
// PESEL
final int sum = (number.charAt(0) - '0') * 1 //
+ (number.charAt(1) - '0') * 3 //
+ (number.charAt(2) - '0') * 7 //
+ (number.charAt(3) - '0') * 9 //
+ (number.charAt(4) - '0') * 1 //
+ (number.charAt(5) - '0') * 3 //
+ (number.charAt(6) - '0') * 7 //
+ (number.charAt(7) - '0') * 9 //
+ (number.charAt(8) - '0') * 1 //
+ (number.charAt(9) - '0') * 3;
calculatedCheckSum = sum % 10;
if (calculatedCheckSum != 0) {
calculatedCheckSum = 10 - sum % 10;
}
} else {
// NIP
final int sum = (number.charAt(0) - '0') * 6 //
+ (number.charAt(1) - '0') * 5 //
+ (number.charAt(2) - '0') * 7 //
+ (number.charAt(3) - '0') * 2 //
+ (number.charAt(4) - '0') * 3 //
+ (number.charAt(5) - '0') * 4 //
+ (number.charAt(6) - '0') * 5 //
+ (number.charAt(7) - '0') * 6 //
+ (number.charAt(8) - '0') * 7;
calculatedCheckSum = sum % MODULO_11;
}
return checkSum == calculatedCheckSum;
}
/**
* calculate square sum.
*
* @param value value to calculate square sum for
* @return square sum
*/
protected static int squareSum(final int value) {
int result = 0;
for (final char valueDigit : String.valueOf(value).toCharArray()) {
result += Character.digit(valueDigit, 10);
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy