All Downloads are FREE. Search and download functionalities are using the official Maven repository.

br.com.caelum.stella.boleto.bancos.gerador.DigitoPara Maven / Gradle / Ivy

package br.com.caelum.stella.boleto.bancos.gerador;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * Uma fluent interface para o cálculo de dígitos, que é usado em diversos boletos e 
 * documentos. 
 * 
 * Para exemplificar, o dígito do trecho 0000039104766 para os multiplicadores indo de 
 * 2 a 7 e usando módulo 11 é a seguinte:
 * 
 * 
 *	0  0  0  0  0  3  9  1  0  4  7  6  6 (trecho numérico)
 *	2  7  6  5  4  3  2  7  6  5  4  3  2 (multiplicadores, da direita para a esquerda e ciclando)
 *	----------------------------------------- multiplicações algarismo a algarismo 
 *	 0  0  0  0  0  9 18  7  0 20 28 18 12 ---> soma = 112
 * 
* * Tira-se o módulo dessa soma e, então, calcula-se o complementar do módulo e, se o número * for 0, 10 ou 11, o dígito passa a ser 1. * *
 * 		soma = 112
 * 		soma % 11 = 2
 * 		11 - (soma % 11) = 9
 * 
* * @author ceci */ public class DigitoPara { private List numero; private List multiplicadores = new ArrayList(); private boolean complementar; private List aSubstituir; private String substituto; /** * Cria o objeto a ser preenchido com interface fluente e armazena o trecho numérico * em uma lista de algarismos. Isso é necessário porque a linha digitada pode ser * muito maior do que um int suporta. * * @param trecho Refere-se à linha numérica sobre a qual o dígito deve ser calculado */ public DigitoPara(String trecho) { comMultiplicadoresDeAte(2, 9); this.aSubstituir = Collections.emptyList(); this.numero = new ArrayList(); char[] digitos = trecho.toCharArray(); for (char digito : digitos) { this.numero.add(Character.getNumericValue(digito)); } Collections.reverse(numero); } /** * Para multiplicadores (ou pesos) sequenciais e em ordem crescente, esse método permite * criar a lista de multiplicadores que será usada cíclicamente, caso o número base seja * maior do que a sequência de multiplicadores. Por padrão os multiplicadores são iniciados * de 2 a 9. No momento em que você inserir outro valor este default será sobrescrito. * * @param inicio Primeiro número do intervalo sequencial de multiplicadores * @param fim Último número do intervalo sequencial de multiplicadores */ public DigitoPara comMultiplicadoresDeAte(int inicio, int fim) { this.multiplicadores.clear(); for (int i = inicio; i <= fim; i++) { multiplicadores.add(i); } return this; } /** * Há documentos em que os multiplicadores não usam todos os números de um intervalo * ou alteram sua ordem. Nesses casos, a lista de multiplicadores pode ser passada * através de varargs. * * @param multiplicadoresEmOrdem Sequência de inteiros com os multiplicadores em ordem */ public DigitoPara comMultiplicadores(Integer... multiplicadoresEmOrdem) { this.multiplicadores = Arrays.asList(multiplicadoresEmOrdem); return this; } /** * É comum que os geradores de dígito precisem do complementar do módulo em vez * do módulo em sí. Então, a chamada desse método habilita a flag que é usada * no método mod para decidir se o resultado devolvido é o módulo puro ou seu * complementar. */ public DigitoPara complementarAoModulo() { this.complementar = true; return this; } public DigitoPara trocandoPorSeEncontrar(String substituto, Integer... i) { this.substituto = substituto; this.aSubstituir = Arrays.asList(i); return this; } /** * Faz a soma geral das multiplicações dos algarismos pelos multiplicadores, tira o * módulo e devolve seu complementar. * * @param modulo Inteiro pelo qual o resto será tirado e também seu complementar * @return String o dígito vindo do módulo com o número passado e configurações extra. */ public String mod(int modulo) { int soma = 0; int multiplicadorDaVez = 0; for (int algarismo : numero) { soma += algarismo * multiplicadores.get(multiplicadorDaVez); multiplicadorDaVez = proximoMultiplicador(multiplicadorDaVez); } int resultado = soma % modulo; if (complementar) resultado = modulo - resultado; return aSubstituir.contains(resultado) ? substituto : String.valueOf(resultado); } /** * Devolve o próximo multiplicador a ser usado, isto é, a próxima posição da lista de * multiplicadores ou, se chegar ao fim da lista, a primeira posição, novamente. * * @param multiplicadorDaVez Essa é a posição do último multiplicador usado. */ private int proximoMultiplicador(int multiplicadorDaVez) { multiplicadorDaVez++; if (multiplicadorDaVez == multiplicadores.size()) multiplicadorDaVez = 0; return multiplicadorDaVez; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy