Created
May 28, 2024 14:22
-
-
Save rodrigocananea/5fbca1cac36f3cdf690149daf843c9a1 to your computer and use it in GitHub Desktop.
Útil para validação de códigos GTIN, aplicado cálculos baseado no GS1.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lombok.AccessLevel; | |
import lombok.Getter; | |
import lombok.NoArgsConstructor; | |
import lombok.RequiredArgsConstructor; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.concurrent.atomic.AtomicInteger; | |
import java.util.regex.Pattern; | |
import java.util.stream.Collectors; | |
import java.util.stream.IntStream; | |
/** | |
* | |
* @author Rodrigo Cananea <rodrigoaguiar35@gmail.com> | |
*/ | |
@NoArgsConstructor(access = AccessLevel.PRIVATE) | |
public class GTINUtil { | |
private static final String SEM_GTIN = "SEM GTIN"; | |
public static boolean isGTIN(int gtin) { | |
return gtin == 8 || gtin == 12 || gtin == 13 || gtin == 14; | |
} | |
public static boolean isGTIN(String barras) { | |
if (barras == null) return false; | |
String numeric = barras.replaceAll("\\D", ""); | |
int length = numeric.length(); | |
return length >= 8 && length <= 14 && validaPrefixos(barras); | |
} | |
public static boolean isValido(String barras) { | |
return !SEM_GTIN.equals(validar(barras)); | |
} | |
public static String validar(String barras) { | |
if (!isGTIN(barras)) { | |
return SEM_GTIN; | |
} | |
GTINEnum gtinEnum = GTINEnum.get(barras.replaceAll("\\D", "").length()); | |
return validar(barras, gtinEnum); | |
} | |
public static String validar(String barras, GTINEnum gtinEnum) { | |
if (isGTIN(barras) && isGTIN(gtinEnum.getCodigo())) { | |
switch (gtinEnum) { | |
case GTIN8: return validaGTIN(barras, Arrays.asList(0, 2, 4, 6)); | |
case GTIN12: return validaGTIN(barras, Arrays.asList(0, 2, 4, 6, 8, 10)); | |
case GTIN13: return validaGTIN(barras, Arrays.asList(1, 3, 5, 7, 9, 11)); | |
case GTIN14: return validaGTIN(barras, Arrays.asList(0, 2, 4, 6, 8, 10, 12)); | |
default: return SEM_GTIN; | |
} | |
} | |
return SEM_GTIN; | |
} | |
private static String validaGTIN(String barras, List<Integer> indices) { | |
List<Integer> barrasArray = Arrays.stream(barras.split("")) | |
.map(Integer::valueOf) | |
.collect(Collectors.toList()); | |
AtomicInteger soma = new AtomicInteger(0); | |
IntStream.range(0, barrasArray.size() - 1).forEach(i -> { | |
int n = barrasArray.get(i); | |
if (indices.contains(i)) { | |
n *= 3; | |
} | |
soma.addAndGet(n); | |
}); | |
int multiplo = obterMultiploDeDez(soma.get()); | |
int resultado = multiplo - soma.get(); | |
boolean isValido = resultado == barrasArray.get(barrasArray.size() - 1); | |
return isValido ? barras : SEM_GTIN; | |
} | |
/** | |
* Múltiplo mais próximo, igual ou superior de dez | |
* https://www.gs1.org/services/how-calculate-check-digit-manually | |
* | |
* @param soma | |
* @return | |
*/ | |
private static int obterMultiploDeDez(int soma) { | |
return (soma % 10 == 0 ? soma : (soma - (soma % 10)) + 10); | |
} | |
/** | |
* Validar prefixos validos de acordo com: | |
* https://www.gs1.org/standards/id-keys/company-prefix | |
* | |
* @param barras | |
* @return | |
*/ | |
public static boolean validaPrefixos(String barras) { | |
return Arrays.stream(GS1Prefixo.values()) | |
.anyMatch(gs1 -> Pattern.compile(gs1.getPrefixos()).matcher(barras).find()); | |
} | |
@Getter | |
@RequiredArgsConstructor | |
public enum GS1Prefixo { | |
GS1_US("^(001|019|030|039|050|059|060|139)"), | |
GS1_FRANCE("^(300|379)"), | |
GS1_BULGARIA("^(380)"), | |
GS1_SLOVENIJA("^(383)"), | |
GS1_CROATIA("^(385)"), | |
GS1_BIH("^(387)"), | |
GS1_MONTENEGRO("^(389)"), | |
GS1_GERMANY("^(400|440)"), | |
GS1_JAPAN("^(450|459|490|499)"), | |
GS1_RUSSIA("^(460|469)"), | |
GS1_KYRGYZSTAN("^(470)"), | |
GS1_CHINESE_TAIPEI("^(471)"), | |
GS1_ESTONIA("^(474)"), | |
GS1_LATVIA("^(475)"), | |
GS1_AZERBAIJAN("^(476)"), | |
GS1_LITHUANIA("^(477)"), | |
GS1_UZBEKISTAN("^(478)"), | |
GS1_SRI_LANKA("^(479)"), | |
GS1_PHILIPPINES("^(480)"), | |
GS1_BELARUS("^(481)"), | |
GS1_UKRAINE("^(482)"), | |
GS1_TURKMENISTAN("^(483)"), | |
GS1_MOLDOVA("^(484)"), | |
GS1_ARMENIA("^(485)"), | |
GS1_GEORGIA("^(486)"), | |
GS1_KAZAKSTAN("^(487)"), | |
GS1_TAJIKISTAN("^(488)"), | |
GS1_HONG_KONG("^(489)"), | |
GS1_UK("^(500|509)"), | |
GS1_GREECE("^(520|521)"), | |
GS1_LEBANON("^(528)"), | |
GS1_CYPRUS("^(529)"), | |
GS1_ALBANIA("^(530)"), | |
GS1_MACEDONIA("^(531)"), | |
GS1_MALTA("^(535)"), | |
GS1_IRELAND("^(539)"), | |
GS1_BELGIUM_LUXEMBOURG("^(540|549)"), | |
GS1_PORTUGAL("^(560)"), | |
GS1_ICELAND("^(569)"), | |
GS1_DENMARK("^(570|579)"), | |
GS1_POLAND("^(590)"), | |
GS1_ROMANIA("^(594)"), | |
GS1_HUNGARY("^(599)"), | |
GS1_SOUTH_AFRICA("^(600|601)"), | |
GS1_GHANA("^(603)"), | |
GS1_SENEGAL("^(604)"), | |
GS1_OMAN("^(607)"), | |
GS1_BAHRAIN("^(608)"), | |
GS1_MAURITIUS("^(609)"), | |
GS1_MOROCCO("^(611)"), | |
GS1_ALGERIA("^(613)"), | |
GS1_NIGERIA("^(615)"), | |
GS1_KENYA("^(616)"), | |
GS1_CAMEROON("^(617)"), | |
GS1_COTE_D_IVOIRE("^(618)"), | |
GS1_TUNISIA("^(619)"), | |
GS1_TANZANIA("^(620)"), | |
GS1_SYRIA("^(621)"), | |
GS1_EGYPT("^(622)"), | |
GS1_LIBYA("^(624)"), | |
GS1_JORDAN("^(625)"), | |
GS1_IRAN("^(626)"), | |
GS1_KUWAIT("^(627)"), | |
GS1_SAUDI_ARABIA("^(628)"), | |
GS1_EMIRATES("^(629)"), | |
GS1_NAMIBIA("^(631)"), | |
GS1_FINLAND("^(640|649)"), | |
GS1_CHINA("^(680|681|690|699)"), | |
GS1_NORWAY("^(700|709)"), | |
GS1_ISRAEL("^(729)"), | |
GS1_SWEDEN("^(730|739)"), | |
GS1_GUATEMALA("^(740)"), | |
GS1_EL_SALVADOR("^(741)"), | |
GS1_HONDURAS("^(742)"), | |
GS1_NICARAGUA("^(743)"), | |
GS1_COSTA_RICA("^(744)"), | |
GS1_PANAMA("^(745)"), | |
GS1_DOMINICAN_REPUBLIC("^(746)"), | |
GS1_MEXICO("^(750)"), | |
GS1_CANADA("^(754|755)"), | |
GS1_VENEZUELA("^(759)"), | |
GS1_SWITZERLAND("^(760|769)"), | |
GS1_COLOMBIA("^(770|771)"), | |
GS1_URUGUAY("^(773)"), | |
GS1_PERU("^(775)"), | |
GS1_BOLIVIA("^(777)"), | |
GS1_ARGENTINA("^(778|779)"), | |
GS1_CHILE("^(780)"), | |
GS1_PARAGUAY("^(784)"), | |
GS1_ECUADOR("^(786)"), | |
GS1_BRASIL("^(789|790)"), | |
GS1_ITALY("^(800|839)"), | |
GS1_SPAIN("^(840|849)"), | |
GS1_CUBA("^(850)"), | |
GS1_SLOVAKIA("^(858)"), | |
GS1_CZECH("^(859)"), | |
GS1_SERBIA("^(860)"), | |
GS1_MONGOLIA("^(865)"), | |
GS1_NORTH_KOREA("^(867)"), | |
GS1_TURKEY("^(868|869)"), | |
GS1_NETHERLANDS("^(870|879)"), | |
GS1_SOUTH_KOREA("^(880|881)"), | |
GS1_MYANMAR("^(883)"), | |
GS1_CAMBODIA("^(884)"), | |
GS1_THAILAND("^(885)"), | |
GS1_SINGAPORE("^(888)"), | |
GS1_INDIA("^(890)"), | |
GS1_VIETNAM("^(893)"), | |
GS1_PAKISTAN("^(896)"), | |
GS1_INDONESIA("^(899)"), | |
GS1_AUSTRIA("^(900|919)"), | |
GS1_AUSTRALIA("^(930|939)"), | |
GS1_NEW_ZEALAND("^(940|949)"), | |
GS1_MALAYSIA("^(955)"), | |
GS1_MACAU("^(958)"); | |
private final String prefixos; | |
} | |
@Getter | |
@RequiredArgsConstructor | |
public enum GTINEnum { | |
SEM_GTIN(0), | |
GTIN8(8), | |
GTIN12(12), | |
GTIN13(13), | |
GTIN14(14); | |
private final Integer codigo; | |
public static GTINEnum get(int codigo) { | |
return Arrays.stream(GTINEnum.values()) | |
.filter(enums -> enums.getCodigo() == codigo) | |
.findFirst() | |
.orElse(GTINEnum.SEM_GTIN); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment