| 37768 |
amit |
1 |
package com.spice.profitmandi.common.util;
|
|
|
2 |
|
|
|
3 |
import java.util.regex.Pattern;
|
|
|
4 |
|
|
|
5 |
/**
|
|
|
6 |
* Reads the parts of a GSTIN that other data is supposed to agree with.
|
|
|
7 |
*
|
|
|
8 |
* <p>A GSTIN is 15 characters: a two digit state code, the holder's ten character PAN, an entity number, a
|
|
|
9 |
* fixed 'Z', and a check character. The state code is therefore the authority on which state a party belongs
|
|
|
10 |
* to - a separately stored state id is a copy that can drift, and has.
|
|
|
11 |
*/
|
|
|
12 |
public final class GstinUtil {
|
|
|
13 |
|
|
|
14 |
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]$");
|
|
|
15 |
|
|
|
16 |
private GstinUtil() {
|
|
|
17 |
}
|
|
|
18 |
|
|
|
19 |
/** Trims and upper-cases, so a value typed with stray spaces or in lower case still compares equal. */
|
|
|
20 |
public static String normalise(String gstin) {
|
|
|
21 |
if (gstin == null) {
|
|
|
22 |
return null;
|
|
|
23 |
}
|
|
|
24 |
String trimmed = gstin.replace("\t", "").replace(" ", " ").trim().toUpperCase();
|
|
|
25 |
return trimmed.isEmpty() ? null : trimmed;
|
|
|
26 |
}
|
|
|
27 |
|
|
|
28 |
public static boolean isBlank(String gstin) {
|
|
|
29 |
return normalise(gstin) == null;
|
|
|
30 |
}
|
|
|
31 |
|
|
|
32 |
/** True only for a value of the exact shape the GST authority issues. */
|
|
|
33 |
public static boolean isValidFormat(String gstin) {
|
|
|
34 |
String normalised = normalise(gstin);
|
|
|
35 |
return normalised != null && GSTIN.matcher(normalised).matches();
|
|
|
36 |
}
|
|
|
37 |
|
|
|
38 |
/** The two digit state code, e.g. "07" for Delhi. Null unless the GSTIN is well formed. */
|
|
|
39 |
public static String stateCodeOf(String gstin) {
|
|
|
40 |
return isValidFormat(gstin) ? normalise(gstin).substring(0, 2) : null;
|
|
|
41 |
}
|
|
|
42 |
|
|
|
43 |
/** The PAN embedded in the GSTIN. Null unless the GSTIN is well formed. */
|
|
|
44 |
public static String panOf(String gstin) {
|
|
|
45 |
return isValidFormat(gstin) ? normalise(gstin).substring(2, 12) : null;
|
|
|
46 |
}
|
|
|
47 |
|
|
|
48 |
/**
|
|
|
49 |
* Whether two parties are registered in the same state, which is what decides CGST+SGST against IGST.
|
|
|
50 |
* Null unless both GSTINs are well formed - an unknown answer, never a false "same".
|
|
|
51 |
*/
|
|
|
52 |
public static Boolean sameState(String oneGstin, String otherGstin) {
|
|
|
53 |
String one = stateCodeOf(oneGstin);
|
|
|
54 |
String other = stateCodeOf(otherGstin);
|
|
|
55 |
return one == null || other == null ? null : one.equals(other);
|
|
|
56 |
}
|
|
|
57 |
}
|