Blame | Last modification | View Log | RSS feed
package com.spice.profitmandi.common.util;import java.util.regex.Pattern;/*** Reads the parts of a GSTIN that other data is supposed to agree with.** <p>A GSTIN is 15 characters: a two digit state code, the holder's ten character PAN, an entity number, a* fixed 'Z', and a check character. The state code is therefore the authority on which state a party belongs* to - a separately stored state id is a copy that can drift, and has.*/public final class GstinUtil {private static final Pattern GSTIN = Pattern.compile("^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][0-9A-Z]Z[0-9A-Z]$");private GstinUtil() {}/** Trims and upper-cases, so a value typed with stray spaces or in lower case still compares equal. */public static String normalise(String gstin) {if (gstin == null) {return null;}String trimmed = gstin.replace("\t", "").replace(" ", " ").trim().toUpperCase();return trimmed.isEmpty() ? null : trimmed;}public static boolean isBlank(String gstin) {return normalise(gstin) == null;}/** True only for a value of the exact shape the GST authority issues. */public static boolean isValidFormat(String gstin) {String normalised = normalise(gstin);return normalised != null && GSTIN.matcher(normalised).matches();}/** The two digit state code, e.g. "07" for Delhi. Null unless the GSTIN is well formed. */public static String stateCodeOf(String gstin) {return isValidFormat(gstin) ? normalise(gstin).substring(0, 2) : null;}/** The PAN embedded in the GSTIN. Null unless the GSTIN is well formed. */public static String panOf(String gstin) {return isValidFormat(gstin) ? normalise(gstin).substring(2, 12) : null;}/*** Whether two parties are registered in the same state, which is what decides CGST+SGST against IGST.* Null unless both GSTINs are well formed - an unknown answer, never a false "same".*/public static Boolean sameState(String oneGstin, String otherGstin) {String one = stateCodeOf(oneGstin);String other = stateCodeOf(otherGstin);return one == null || other == null ? null : one.equals(other);}}