BrazilUtils API

Pessoal, ontem eu entrei no site do Sintegra - http://www.sintegra.gov.br/ - e encontrei os requisitos e formas de cálculo das inscrições estaduais. Cada uma é de uma forma. Eu implementei uma AbstractInscricaoEstadual para servir de superclasse para cada classe específica (uma por estado). Ela tem vários métodos que as subclasses vão precisar, inclusive o cálculo de pesos para cada dígito. Assim as classes dos estados ficaram co 5 ou 6 métodos para implementar somente, incluindo o de validação principal.
Superclasse Abstrata:

/*
 * Created on 10/04/2005
 */
package org.brazilutils.br.uf.ie;

import java.text.ParseException;

import org.brazilutils.utilities.GenericNumberComposed;
import org.brazilutils.utilities.NumberComposed;
import org.brazilutils.validation.Validable;
import org.brazilutils.validation.ValidationException;

/**Represents a IE (Inscrição Estadual)<br>
 * Each state implements a IE<p>
 * 
 * The Subclasses must implement:<p>
 * getDigitCount() - Determines how much Digits the IE must have<br>
 * getDvCount() - Determines how much Check Digits the IE must have<br>
 * getMask() - Determines the mask must be applyed in toString() and getValue() methods<br>
 * getPesosList() - the list of Pesos<br>
 * isValid() - the validation method
 * 
 * @see <a href="http://www.sintegra.gov.br/insc_est.html"></a>
 * 
 * @author Douglas Siviotti
 */
public abstract class AbstractInscricaoEstadual 
	implements NumberComposed, Validable{

    public static final int MOD11 = 11;
    private GenericNumberComposed number= new GenericNumberComposed();
    private Pesos pesos = new Pesos();

    /**
     * 
     */
    public AbstractInscricaoEstadual() {
        super();
        try {
            number.setMask(getMask());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        pesos.setPesosString(getPesosList());
    }
    
    public int applyPesos(int digitBegin, int digitEnd, Pesos p){
        int result = 0;
        if (p == null) p = pesos;
        for (int i=digitBegin; i <= digitEnd; i++){
            result = result + getDigitValue(i) * p.getValue(i); 
        }
        return result;
    }
    
    /**The count of digits by default
     * @return The number of digits by default
     */
    public abstract int defaultDigitCount();
    /** 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        return this.toString().equals(obj.toString());
    }
    
    /**Returns the char of digit requested
     * @param digitPosition The digit position 
     * @return the char on digitPosition
     */
    public char getDigit(int digitPosition){
        return getNumber().charAt(digitPosition);
    }
    
    /**Returns the value of a digit
     * @param digitPosition The digit position
     * @return the value of the digit
     */
    public short getDigitValue(int digitPosition){
        String s = "" + getDigit(digitPosition);
        return Short.parseShort(s);
    }
    
    /**<pre>
     * 12345-67
     *       ^
     *       This is the fisrt Check Digit (Dv1)
     * 	     Check Digite = 6
     *       Position = 5 (starts in 0) 
     * </pre><p>
     * By default is the last digit -1 (= getDigitCount - 1)
     */ 
    public int getDv1Position(){
        if (getDvCount() == 1){
            return defaultDigitCount() - 1; 
        } else {
            return defaultDigitCount() - 2;
        }

    }
    /**Returns the value of the fisrt check digit
     * @return the value of the fisrt check digit
     */
    public short getDv1Value(){
        return getDigitValue(getDv1Position());
    }

    /**<pre>
     * 12345-67
     *        ^
     *        This is the Second Check Digit (Dv2) 
     * 	      Check Digite = 7
     *        Position = 6 (starts in 0) 
     * </pre><p>
     * By default is the last digit (= getDigitCount) 
     * @return The Second Check Digit Position
     */
    
    public int getDv2Position(){
        return defaultDigitCount() - 1;        
    }
    
    /**Returns the value of the second check digit
     * @return the value of the second check digit
     */
    public short getDv2Value(){
        return getDigitValue(getDv2Position());
    }
    
    /**The count of check digits
     * @return The number of chek digits
     */
    public abstract int getDvCount();
    
    /**Returns the IE mask 
     * @return The IE mask
     */
    public abstract String getMask();
    /** 
     * @see org.brazilutils.utilities.NumberComposed#getNumber()
     */
    public String getNumber() {
        return number.getNumber();
    }
    /**
     * @return Returns the pesos.
     */
    public Pesos getPesos() {
        return pesos;
    }
    
    public abstract String getPesosList();
    /** 
     * @see org.brazilutils.utilities.NumberComposed#getValue()
     */
    public String getValue() {
        return number.getValue();
    }
    
    /**Determines if the 
     * @return True if the number has the same count of digitCount
     */
    public boolean isDigitCountCorrect(){
        return defaultDigitCount() == getNumber().length();
    }

    /** 
     * @see org.brazilutils.validation.Validable#isValid()
     */
    public abstract boolean isValid();
    /**Sets the number of Inscricao Estadual
     * @param number The number to set.
     */
    public void setNumber(String number){
        this.number.setNumber(number);
    }
    /** 
     * @see org.brazilutils.utilities.NumberComposed#toLong()
     */
    public long toLong() {
        return number.toLong();
    }
    /** 
     * @see java.lang.Object#toString()
     */
    public String toString() {
        return getValue();
    }
    
    /** 
     * @throws ValidationException
     * @see org.brazilutils.br.uf.ie.AbstractInscricaoEstadual#validate()
     */
    public void validate() throws ValidationException {
        if ( !isValid() ) throw new ValidationException();
    }
    
}

Classe de Inscrição Estadual do Acre que fiz para testar (funcionou):

/*
 * Created on 10/04/2005
 */
package org.brazilutils.br.uf.ie;



/**
 * @author Douglas Siviotti
 */
public class InscricaoEstadualAC extends AbstractInscricaoEstadual {



    /** 
     * @see org.brazilutils.br.uf.ie.AbstractInscricaoEstadual#defaultDigitCount()
     */
    public int defaultDigitCount() {
        return 13;
    }

    /** 
     * @see org.brazilutils.br.uf.ie.AbstractInscricaoEstadual#getDvCount()
     */
    public int getDvCount() {
        return 2;
    }

    /** 
     * @see org.brazilutils.br.uf.ie.AbstractInscricaoEstadual#getMask()
     */
    public String getMask() {
        return "##.###.###/###-##";
    }

    /** 
     * @see org.brazilutils.br.uf.ie.AbstractInscricaoEstadual#getPesosList()
     */
    public String getPesosList() {
        return "43298765432";
    }
    /** 
     * @see org.brazilutils.br.uf.ie.AbstractInscricaoEstadual#isValid()
     */
    public boolean isValid() {
        if (!isDigitCountCorrect()) return false;
        int sum1 = applyPesos(0, 10, getPesos());
        int mod1 = sum1 % MOD11;
        int dif1 = MOD11 - mod1;
        int dv1;
        if (dif1 >= 10)  dv1 = 0; else dv1 = dif1;
        System.out.println(sum1 + " : 11 = " + mod1 + " - dif = " + dif1 + " - dv1 = " + dv1 );
        int sum2 = applyPesos(0, 11, new Pesos("543298765432"));
        int mod2 = sum2 % MOD11;
        int dif2 = MOD11 - mod2;
        int dv2;
        if (dif2 >= 10)  dv2 = 0; else dv2 = dif2;
        System.out.println(sum2 + " : 11 = " + mod2 + " - dif = " + dif2 + " - dv1 = " + dv2 );
        return getDv1Value() == dv1 && getDv2Value() == dv2;
    }
}

Classe para fazer o teste:

public class TestUF {

    public static void main(String[] args) {
        UF uf = null;
        try {
            uf = new UF("AC");
        } catch (UfException e) {
            e.printStackTrace();
        }
        uf.getInscricaoEstadual().setNumber("01004823001-12");
        System.out.println(uf.getInscricaoEstadual().toString());
        System.out.println("isValid() = " + uf.getInscricaoEstadual().isValid());
        System.out.println(uf.getAbbreviature());
        System.out.println(uf.getName());
    }
}

Só uma observação. Algumas inscrições estaduais tem peculiaridades.
O mato grosso por exemplo, pode ter 9, 10 ou 11 dígitos (Isso não é falado no site).
Eu tenho um código aqui de cálculo de Inscrição Estadual de uns 8 estados, que não posso postar (apesar de eu mesmo ter feito).

Esse é o código em C que fizemos em uma dll separada da aplicação aqui que é em VB.

Vou retirar alguns comentários, mudar alguns nomes de variáveis e posto aqui novamente (quem sabe animo em converter pra Java). :lol:

[quote=Ssalgado]Só uma observação. Algumas inscrições estaduais tem peculiaridades.
O mato grosso por exemplo, pode ter 9, 10 ou 11 dígitos (Isso não é falado no site).
Eu tenho um código aqui de cálculo de Inscrição Estadual de uns 8 estados, que não posso postar (apesar de eu mesmo ter feito).

Esse é o código em C que fizemos em uma dll separada da aplicação aqui que é em VB.

Vou retirar alguns comentários, mudar alguns nomes de variáveis e posto aqui novamente (quem sabe animo em converter pra Java). :lol: [/quote]

se não se animar eu faço … ja faço isso o dia inteiro …

vou mudar minha assinatura para:

Tradutor juramentado C++ -> Java. …

[quote=scottys0][quote=Ssalgado]Só uma observação. Algumas inscrições estaduais tem peculiaridades.
O mato grosso por exemplo, pode ter 9, 10 ou 11 dígitos (Isso não é falado no site).
Eu tenho um código aqui de cálculo de Inscrição Estadual de uns 8 estados, que não posso postar (apesar de eu mesmo ter feito).

Esse é o código em C que fizemos em uma dll separada da aplicação aqui que é em VB.

Vou retirar alguns comentários, mudar alguns nomes de variáveis e posto aqui novamente (quem sabe animo em converter pra Java). :lol: [/quote]

se não se animar eu faço … ja faço isso o dia inteiro …

vou mudar minha assinatura para:

Tradutor juramentado C++ -> Java. … [/quote]

Se eu não animar te passo por email então. :thumbup:

dsviotti, pq nao usar JUnit pra testar, ao inves da psvm?

[quote=Ssalgado]Só uma observação. Algumas inscrições estaduais tem peculiaridades.
O mato grosso por exemplo, pode ter 9, 10 ou 11 dígitos (Isso não é falado no site).
[/quote]

Eu sei. Dei uma olhada em todos os estados no site do sintegra. A pior é de São paulo, tem 2 tipos, um dos dífgitos fica no meio do número :shock: e um dos tipos tem um P. Mas os métodos na superclasse servem bem a mais 90% dos estados. No caso de MT e SP é só fazer um override de alguns. No de Sp, pro exemplo, teria que fazer um override de getDv1Potision() que retorna count -1 ou count-2, ele teria que retornar 9 ou 9 calculado.

Cv, não usei o Junit por preguiça 8) mesmo. Não estou acostumado com JUnit mas vou aceitar a sugestão e refazer os testes enquanto são poucos. Valeu. :wink:

Pessoal,

Os códigos de validações de Inscrições Estaduais já está pronto (rodando). O problema é que eu só tenho Inscrições Estaduais de São Paulo e Rio. O pessoal dos demais estados pode dar uma grande ajuda simplesmente me enviando algumas Inscrições Estaduais válidas. Melhor ainda seria testar a classe de IE do seu estado. O código já está lá no java.net, acho que o Fernando (Scottys0) já colocou inclusive no CVS.

Pequeno código para quem puder testar as classes:

package org.brazilutils.test;

import junit.framework.TestCase;
import org.brazilutils.br.uf.UF;
import org.brazilutils.br.uf.UfException;

public class UFTest2 extends TestCase {

    public void test() throws Exception {
        UF uf = null;
        try {
            uf = new UF("SP");//Cria a UF a partir da Sigla
        } catch (UfException e) {
            e.printStackTrace();
        }
        uf.getInscricaoEstadual().setNumber("110.042.490.114");
        assertTrue(uf.getInscricaoEstadual().isValid());        
    }
}

o código já está no cvs do java.net

ps. o teste para o paraná está ok [quote]90175758-53
PR
Paraná
Sum:160 Mod:6 Dif:5 Dv:5
Sum:206 Mod:8 Dif:3 Dv:3[/quote]

A todos que forem audar a codificar !

Sempre façam o download da ultima versão do source do CVS !

aqui tem um tutorial que ensina como integrar o cvs ao eclipse.
http://www.jelb.org.br/~filipe/java/cvs-eclipse/index.html

Ultimo add, um Build.xml para geração da api em .jar e geração da documentação também em um jar

onde está configurado assim, podendo ser alterada :wink:
:arrow: brazilutils.$(version).jar - brazilutils.0.0.1.jar
:arrow: brazilutils.doc.$(version).jar - brazilutils.doc.0.0.1.jar

Galerinha, me diz uma coisa… toh vendo os fontes no CVS e vi um negocio q não gostei.

Como faz? Muda e comita?

A classe BrKit tem o contrutor privado e um get que não é estático :S Mui esquisito…

O contrutor deveria receber o estado como parâmetro, não ficava melhor…

Sei lá, deixa um estado X como default é só coisa pra dar confusão!!! 6 num axam?

Posso mudar e comitar?

VELO

Outra coisa, java 1.4 ou java 5?

VELO

[quote=velo]Outra coisa, java 1.4 ou java 5?
VELO[/quote]

Java 1.5

[quote=scottys0][quote=velo]Outra coisa, java 1.4 ou java 5?
VELO[/quote]

Java 1.5[/quote]

Show…

Mas como preenche isso?

[quote]Issue number:
Obtained from:
Submitted by:
Reviewed by:
CVS: ----------------------------------------------------------------------
CVS: Issue number:
CVS: If this change addresses one or more issues,
CVS: then enter the issue number(s) here.
CVS: Obtained from:
CVS: If this change has been taken from another system,
CVS: then name the system in this line, otherwise delete it.
CVS: Submitted by:
CVS: If this code has been contributed to the project by someone else; i.e.,
CVS: they sent us a patch or a set of diffs, then include their name/email
CVS: address here. If this is your work then delete this line.
CVS: Reviewed by:
CVS: If we are doing pre-commit code reviews and someone else has
CVS: reviewed your changes, include their name(s) here.
CVS: If you have not had it reviewed then delete this line.
[/quote]

Velo, Tiger rulezzz!Jah tah no 3ºupdate, jah não dah para ignorá-lo! :slight_smile:

Fernando, tô com o mesmo problema do velo… dah para rolar um howto?..heheh

Pessoal,

Vou fazrt um acerto na IE de SP por que esqueci de fazer a o segundo tipo possível de IE, para produtores rurais.

Quanto ao CVS tb estou dando umas cabeçadas, mas usando o eclipse ficou bem simples. Como vocês podem perceber já tem um monte de versões antigas pq eu e o Fernando fizemos uns testes e eu, pessoalmente, apanhei um pouco.

Volto a pedir para o pessoal de outros estados (fora Rio e SP) me enviarem números válidos de inscrição estadual e se possível dar uma testada no código. Obrigado…

[quote=velo]
A classe BrKit tem o contrutor privado e um get que não é estático :S Mui esquisito…

O contrutor deveria receber o estado como parâmetro, não ficava melhor…

Sei lá, deixa um estado X como default é só coisa pra dar confusão!!! 6 num axam?

Posso mudar e comitar?
VELO[/quote]

Esa classe é aquela que será tipo um canivete suiço da API. Assim, será uma das últimas a ficar prontas. Só coloquei ela lá pra lembrar que ela existe. Pode alterar o que estiver errado e adicionar mais funcionalidades se quiser.

[quote=dsiviotti]
Esa classe é aquela que será tipo um canivete suiço da API. Assim, será uma das últimas a ficar prontas. Só coloquei ela lá pra lembrar que ela existe. Pode alterar o que estiver errado e adicionar mais funcionalidades se quiser.[/quote]

Hoje ela tem um problema… é impossível obter uma instancia da classe :frowning: :frowning: :frowning:

VELO

Eu sou tosco e vou xingar um monte, mas por favor tomem um prozac e levem isso de forma construtiva enquanto ainda eh tempo, ou esse projeto vai ser um desastre.

Broncas:

:arrow: Cade os testes unitarios isolados?

:arrow: Cade os testes unitarios integrados?

:arrow: Cade os testes funcionais?

:arrow: Pq o build.xml nao roda nenhum dos acima?

:arrow: Cade o relatorio de test coverage? Voces podem usar o Emma (http://emma.sourceforge.net/), que eh gratis. :wink:

:arrow: Singletons. Por favor, dsiviotti e scottys0, nem tentem se explicar por essa. Simplesmente apaguem essa BrKit de la, tentem de novo, e finjam que nao aconteceu nada. Voces tambem podem pedir desculpas, mas eh melhor todo mundo fazer vista grossa, e assim voces evitam a humilhacao de ter que admitir que uma classe como aquela um dia passou pela cabeca.

:arrow: A documentacao e a API metade em ingles e metade em portugues da arrepios. Facam tudo em portugues, logo duma vez, por favoooooooooor!

:arrow: As mensagens de commit no CVS nao dizem nada que va ajudar alguem como eu, que esta so passeando pelo codigo, a entender o que esta acontecendo - usem mensagens mais descritivas, please!

:arrow: Varias packages vazias, ou com codigo pela metade. Se voce nao tem codigo pra mostrar, nao mande pro CVS - assim fica bem mais facil gerenciar arquivos deletados, tags, branches etc e tal.

:arrow: EXPRESSOES REGULARES PELO AMOR DE DEUS! Voces parecem que gostam de sofrer fazendo substring! Gente, tenham doh, expressoes regulares entraram no Java na 1.4 e ja existem faz mais de 20 anos, se voces ainda nao aprenderam, tomem vergonha na cara!

:arrow: Se o codigo eh LGPL, faltou colocar um LICENSE na raiz do projeto, e idealmente, todo arquivo tem que incluir aquele bloquinho maldito explicando a licenca.

:arrow: Os construtores das classes Cnpj, Cpf e tantas outras estao duplicando codigo a toa. E lancar excecoes no construtor eh rude com os pobres usuarios da sua API :wink:

:arrow: Eu ja mencionei expressoes regulares?

:arrow: Pra que serve a interface Endereco? Declarar um monte de getter e setter? Que sao duplicados depois na EnderecoAdapter :?

:arrow: TipoLogradouro deveria ser uma enum, nao uma classe - afinal, vcs estao usando Java 1.5…

:arrow: Eu ja mencionei que “Represents the DDD of a Telefone” realmente nao ajuda quem nao fala portugues, e quase faz o pessoal que fala mijar de rir?

:arrow: Expressoes regulares? :mrgreen:

:arrow: Digam oi pro dsiviotti! Eh o que tem na TODO :mrgreen:

  • cv, enfiando o peh na maior e mais fedida jaca de todos os tempos

Olá!

As colocações do CV são sem dúvida ótimas!
Estou ainda por fora do que está acontecendo, mas lendo o que o Carlos escreveu, vi que vcs estão usando Ant!

Vcs teriam ainda que configurar o Ant para rodar todos os teste unitários, e testes em geral! O ideal é que durante o desenvolvimento o teste acontecesse várias vezes!

Para facilitar a vida do BrazilUtils, acho que seria melhor usarmos Maven! Além de não ser difícil usá-lo, você não se preocupa em ficar criando tantas configurações na unha igual é no ant!

se vc for no pronpt do comando, ou via um plugins no Eclipse, vc conseguirá rodar todos os testes sempre que quiser, usando o comando tes!

Outra coisa interessante é a geração da documentação! O Maven quebraria um galho e tanto!

Olha aqui um guiazinho!
http://hotwork.sourceforge.net/hotwork/manual/maven/maven-user-guide.html

Em breve posso ver isso para vocês, só que esta semana pra mim vai ser aquela correria. Se você não se importarem de esperar um pouquinho, blz!

Abraços!
Thiago

Maven nao vai resolver o problema, Thiago. O codigo continua ruim, e build automatizado de codigo ruim continua sendo um build automatizado de codigo ruim. Por enquanto, o que tem da pra compilar no Eclipse, mesmo, e o Ant fica so pra rodar builds de vez em quando, e empacotar os JARs. Pra isso, o Ant ja ta maaaaaaais do que suficiente, e nao tem aquela aberracao do Jelly que o Maven usa pra manter.