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());
}
}