validation and barcode extraction for Iran bills
package io.github.farhad;
import java.util.regex.Pattern;
/**
* Created by farhad on 1/15/17.
*/
public class BillHelper {
private static final int BILL_WATER = 1 ;
private static final int BILL_POWER = 2 ;
private static final int BILL_GAS = 3 ;
private static final int BILL_LANDLINE = 4 ;
private static final int BILL_MOBILE = 5 ;
private static final int BILL_URBAN = 6 ;
private static final int BILL_URBAN_NEW = 7 ;
private static final int BILL_UD = 8 ;
private static final int BILL_CAR_PENALTY = 9 ;
private static final int BILL_ERROR = 10 ;
private static final String WATER = "قبض آب" ;
private static final String POWER = "قبض برق" ;
private static final String GAS = "قبض گاز" ;
private static final String LANDLINE = "قبض تلفن ثابت" ;
private static final String MOBILE = "قبض تلفن همراه" ;
private static final String URBAN = "قبض عوارض شهرداری" ;
private static final String URBAN_NEW = "قبض عوارض شهرداری جدید" ;
private static final String UD = "تعریف نشده" ;
private static final String CAR_PENALTY = "جریمه خودرو" ;
private static final String ERROR = "خطا" ;
public static String extractPaymentId(String scannedBarcode) {
if(scannedBarcode.length() == 26) {
return removeLeadingZeroes(scannedBarcode.substring(17,26)) ;
}
return null ;
}
public static String extractBillId(String scannedBarcode) {
if(scannedBarcode.length() == 26) {
return removeLeadingZeroes(scannedBarcode.substring(0,13)) ;
}
return null ;
}
public static String getBillType(String billId) {
if (isEmpty(billId) || !validateBillId(billId))
return ERROR;
int id = billId.charAt(billId.length() - 2) - '0';
switch (id) {
case BILL_WATER : return WATER ;
case BILL_POWER : return POWER ;
case BILL_GAS : return GAS ;
case BILL_LANDLINE : return LANDLINE ;
case BILL_MOBILE : return MOBILE ;
case BILL_URBAN: return URBAN;
case BILL_URBAN_NEW: return URBAN_NEW;
case BILL_UD : return UD ;
case BILL_CAR_PENALTY : return CAR_PENALTY ;
case BILL_ERROR : return ERROR ;
default: return ERROR ;
}
}
public static boolean validateBillId(String billId) {
if(isEmpty(billId) || !isDigitsOnly(billId))
return false ;
if (billId.length() < 6 || billId.length() > 13)
return false;
if (billId.charAt(billId.length() - 2) == '0')
return false;
if (!Pattern.compile("^[0-9]+$") .matcher(billId).matches())
return false;
return (getCheckDigit(billId.substring(0, billId.length() - 1)) == billId.charAt(billId.length() - 1));
}
public static boolean validatePaymentId(String billId , String paymentId){
if(isEmpty(billId) || !isDigitsOnly(paymentId))
return false ;
if(!validateBillId(billId))
return false ;
if (paymentId.length() < 6 || paymentId.length() > 13)
return false;
Pattern pattern = Pattern.compile("^[0-9]+$") ;
if (!pattern.matcher(billId).matches() || !pattern.matcher(paymentId).matches())
return false;
boolean isValidBillId = getCheckDigit(paymentId.substring(0, paymentId.length() - 2)) == paymentId.charAt(paymentId.length() - 2);
boolean isValidPaymentId = getCheckDigit(billId + paymentId.substring(0, paymentId.length() - 1)) == paymentId.charAt(paymentId.length() - 1);
return isValidBillId && isValidPaymentId;
}
public static String removeLeadingZeroes(String paymentId) {
try
{
String intPayId = String.valueOf(Integer.valueOf(paymentId)) ;
return intPayId ;
}
catch (Exception exc)
{
String temp = paymentId ;
while (temp.indexOf("0")==0)
temp = temp.substring(1);
return temp;
}
}
private static int getBillAmount(String billPaymentId){
if (billPaymentId.length() < 6)
return 0;
return Integer.parseInt(billPaymentId.substring(0, billPaymentId.length() - 5))*1000;
}
private static int getCheckDigit(String billId){
int i = 2;
int checker = 0;
for (int index = billId.length() - 1; index >= 0; index--) {
checker += (billId.charAt(index) - '0')*i;
i++;
if (i > 7)
i = 2;
}
checker = checker%11;
if (checker == 1 || checker == 0)
checker = 0;
else
checker = 11 - checker;
return checker + '0';
}
private static boolean isEmpty(CharSequence str) {
return str == null || str.length() == 0;
}
private static boolean isDigitsOnly(CharSequence str) {
final int len = str.length();
for (int cp, i = 0; i < len; i += Character.charCount(cp)) {
cp = Character.codePointAt(str, i);
if (!Character.isDigit(cp)) {
return false;
}
}
return true;
}
}