farhad
12/17/2017 - 10:07 AM

validation and barcode extraction for Iran bills

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;
    }
}