Validação da Inscrição Estadual

2,138 views
Skip to first unread message

Renato Lima

unread,
Dec 12, 2011, 2:37:47 PM12/12/11
to openerp...@googlegroups.com
Pessoal,


Estou organizando os blueprints do projeto da localização brasileira, eu comecei a atualizar algumas tarefas como a da verificação da inscrição estadual, pois a partir da NFe 2.00 é validada a inscrição estadual e se estiver errada a NFe é rejeitada pela Sefaz. Para diminuir a possibilidade deste erro acontecer ao cadastrar um parceiro, a inscrição estadual ele deve ser verificada (claro que se ele é pessoa física ou isento não é verificada). Para organizar a contribuição eu criei um blueprint Validação da Incrição Estadual e coloquei outros blueprints para a implementação de cada estado para organizar a contribuição, desta forma quem quiser contribuir com a implementação da validação de um estado, pode atribui-la e faze-la, na branch https://code.launchpad.net/~openerp-brazil-team/openerp.pt-br-localiz/openerp.pt-br-localiz6-1 já implementei a Constraint e os métodos de validação para cada estado deste forma (exemplo do método de validação de São Paulo): 

def validate_ie_sp(self, inscr_est):
        """ Verificação da Inscrição Estadual-São Paulo """
        #TODO
        return True

Eu já fiz a validação do Rio de Janeiro, então quem quiser fazer as outras é só atribuir o blueprint e fazer :)
No blueprint de cada estado eu também coloquei um link um a regra de validação para cada estado !

Acre  https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-ap
Alagoas 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-al
Amapá 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-ap
Amazonas 
  https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-am
Bahia 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-ba
Ceará 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-ce
Distrito Federal 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-df
Espírito Santo 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-es
Goiás 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-go
Maranhão 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-ma
Mato Grosso 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-mt
Mato Grosso do Sul 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-ms
Minas Gerais 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-mg
Pará 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-pa
Paraíba 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-pb
Paraná 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-pr
Pernambuco 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-pe
Piauí 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-pi
Roraima 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-rr
Rondônia 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-ro
Rio de Janeiro 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-rj
Rio Grande do Norte 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-rn
Rio Grande do Sul 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-rs
Santa Catarina 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-sc
São Paulo 
 https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-sp
Sergipe 
– https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-se
Tocantins 
 
https://blueprints.launchpad.net/openerp.pt-br-localiz/+spec/validar-insc-estadual-to


Um grande abraço !


Renato Lima
Sócio Diretor
Assinatura_nova.png

Assinatura_nova.png

Luis Felipe Miléo

unread,
Dec 13, 2011, 8:14:25 AM12/13/11
to openerp...@googlegroups.com
Pode contar com a minha contribuição, vou baixar a branch 6.1, espero amanha já estar codando.

Abraços
--
Luis Felipe Sant' ana
+5512 8135-1450

Consultoria e Serviços em Tecnologia

Assinatura_nova.png

Renato Lima

unread,
Dec 13, 2011, 9:26:32 AM12/13/11
to openerp...@googlegroups.com
Olá pessoal,


Uma dica também para quem quiser contribuir, eu fiz a verificação da inscrição estadual do rio de janeiro, quem quiser pode dar uma olhada no código como base para a implementação da validações de outros estados. apesar de cada estado ter a sua regra, elas não são totalmente diferentes.


Um grande abraço,


Renato Lima
Sócio Diretor
Assinatura_nova.png

Assinatura_nova.png
Assinatura_nova.png

Carlos Alberto Fitl

unread,
Dec 13, 2011, 9:47:59 AM12/13/11
to openerp...@googlegroups.com
Olá Pessoal eu tenho uma função que eu usava em pascal que valida UF se alguem quiser transcrever fique a vontade, esta função foi retirada do componente do ACBrNFe, a diferença que foi feito um componente, o que precisa fazer e passar a UF e a IE por parametro, pois neste exemplo você não passa o parametro na função ele pega via metodo de acesso, onde ele pega a UF que é o campo fsComplemento e a Inscrição Estadual que é o fsDocto.

Que já trabalhou com Delphi é moleza reescrever, ainda tem uma função que valida a se a UF existe e outra para formatar a IE conforme o Estado.

//************************** Valida Inscrição Estadual *****************************//
Procedure TACBrValidador.ValidarIE ;
Const
   c0_9 : AnsiString = '0-9' ;
   cPesos : array[1..13] of array[1..14] of Integer =
      ((0 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,2 ,3 ,4 ,5 ,6 ),
       (0 ,0 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,2 ,3 ,4 ,5 ),
       (2 ,0 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,2 ,3 ,4 ,5 ,6 ),
       (0 ,2 ,3 ,4 ,5 ,6 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ),
       (0 ,8 ,7 ,6 ,5 ,4 ,3 ,2 ,1 ,0 ,0 ,0 ,0 ,0 ),
       (0 ,2 ,3 ,4 ,5 ,6 ,7 ,0 ,0 ,8 ,9 ,0 ,0 ,0 ),
       (0 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,1 ,2 ,3 ,4 ,5 ),
       (0 ,2 ,3 ,4 ,5 ,6 ,7 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ),
       (0 ,0 ,2 ,3 ,4 ,5 ,6 ,7 ,2 ,3 ,4 ,5 ,6 ,7 ),
       (0 ,0 ,2 ,1 ,2 ,1 ,2 ,1 ,2 ,1 ,1 ,2 ,1 ,0 ),
       (0 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10,11,2 ,3 ,0 ),
       (0 ,0 ,0 ,0 ,10,8 ,7 ,6 ,5 ,4 ,3 ,1 ,0 ,0 ),
       (0 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10,2 ,3 ,0, 0 ) ) ;

Var
   vDigitos : array of {$IFDEF FPC}Variant{$ELSE} AnsiString{$ENDIF} ;
   xROT, yROT :  AnsiString ;
   Tamanho, FatorF, FatorG, I, xMD, xTP, yMD, yTP, DV, DVX, DVY : Integer ;
   SOMA, SOMAq, nD, M : Integer ;
   OK : Boolean ;
   Passo, D : AnsiChar ;

begin
  if UpperCase( Trim(fsDocto) ) = 'ISENTO' then
     exit ;
    
  if fsComplemento = '' then
  begin
     fsMsgErro := 'Informe a UF no campo Complemento' ;
     exit ;
  end ;

  ValidarUF( fsComplemento ) ;
  if fsMsgErro <> '' then
     exit ;

  { Somente digitos ou letra P na primeira posicao }
  { P é usado pela Insc.Estadual de Produtor Rural de SP }
  if ( not StrIsNumber( copy(fsDocto,2,length(fsDocto) ))) or
     ( not CharIsNum(fsDocto[1]) and (fsDocto[1] <> 'P')) then
  begin
     fsMsgErro := 'Caracteres inválidos na Inscrição Estadual' ;
     exit
  end ;

  Tamanho := 0  ;
  xROT    := 'E';
  xMD     := 11 ;
  xTP     := 1  ;
  yROT    := '' ;
  yMD     := 0  ;
  yTP     := 0  ;
  FatorF  := 0  ;
  FatorG  := 0  ;

  SetLength( vDigitos, 13);
  vDigitos := VarArrayOf(['','','','','','','','','','','','','','']) ;

  if fsComplemento = 'AC' then
  begin
     if Length(fsDocto) = 9 then
      begin
        Tamanho := 9 ;
        vDigitos := VarArrayOf(
           ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'1','0','','','','',''] ) ;
      end
     else
      if Length(fsDocto) = 13 then
      begin
        Tamanho := 13 ;
        xTP := 2   ;   yROT := 'E'   ;   yMD  := 11   ;   yTP  := 1 ;
        vDigitos := VarArrayOf(
          ['DVY','DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'1','0','']);
      end ;
  end ;

  if fsComplemento = 'AL' then
  begin
     Tamanho := 9 ;
     xROT := 'BD' ;
     vDigitos   := VarArrayOf(
        ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'4','2','','','','',''] ) ;
  end ;

  if fsComplemento = 'AP' then
  begin
     if Length(fsDocto) = 9 then
      begin
        Tamanho := 9 ;
        xROT := 'CE' ;
        vDigitos   := VarArrayOf(
           ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'3','0','','','','',''] ) ;

        if (fsDocto >= '030170010') and (fsDocto <= '030190229') then
           FatorF := 1
        else if fsDocto >= '030190230' then
           xROT := 'E' ;
      end ;
  end ;

  if fsComplemento = 'AM' then
  begin
     Tamanho := 9 ;
     vDigitos  := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','','','',''] ) ;
  end ;

  if fsComplemento = 'BA' then
  begin
     Tamanho := 8 ;
     xTP := 2   ;   yTP  := 3   ;   yROT := 'E' ;
     vDigitos := VarArrayOf(
        ['DVX','DVY',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','','','','',''] ) ;

     if pos(fsDocto[1],'0123458') > 0 then
      begin
        xMD := 10   ;   yMD := 10 ;
      end
     else
      begin
        xMD := 11   ;   yMD := 11 ;
      end ;
  end ;

  if fsComplemento = 'CE' then
  begin
     Tamanho := 9 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'0','','','','',''] ) ;
  end ;

  if fsComplemento = 'DF' then
  begin
     Tamanho := 13 ;
     xTP := 2   ;   yROT := 'E'  ;   yMD  := 11   ;   yTP  := 1 ;
     vDigitos  := VarArrayOf(
        ['DVY','DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'3,4,5','7','0','']);
  end ;

  if fsComplemento = 'ES' then
  begin
     Tamanho  := 9 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'0,8','0','','','','',''] ) ;
  end ;

  if fsComplemento = 'GO' then
  begin
     if Length(fsDocto) = 9 then
     begin
        Tamanho  := 9 ;
        vDigitos := VarArrayOf(
           [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'0,1,5','1','','','','',''] ) ;

        if (fsDocto >= '101031050') and (fsDocto <= '101199979') then
           FatorG := 1 ;
     end ;
  end ;

  if fsComplemento = 'MA' then
  begin
     Tamanho  := 9 ;
     vDigitos := VarArrayOf(
        ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'2','1','','','','',''] ) ;
  end ;

  if fsComplemento = 'MT' then
  begin
     if Length(fsDocto) = 9 then
        fsDocto := padR(fsDocto,11,'0') ;

     Tamanho := 11 ;
     vDigitos := VarArrayOf(
        ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','',''] ) ;
  end ;

  if fsComplemento = 'MS' then
  begin
     Tamanho  := 9 ;
     vDigitos := VarArrayOf(
        ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'8','2','','','','',''] ) ;
  end ;

  if fsComplemento = 'MG' then
  begin
     Tamanho  := 13 ;
     xROT := 'AE'    ;   xMD := 10   ;   xTP := 10 ;
     yROT := 'E'     ;   yMD := 11   ;   yTP := 11 ;
     vDigitos := VarArrayOf(
       ['DVY','DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'']);
  end ;

  if fsComplemento = 'PA' then
  begin
     Tamanho  := 9 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'5','1','','','','',''] ) ;
  end ;

  if fsComplemento = 'PB' then
  begin
     Tamanho  := 9 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'6','1','','','','',''] ) ;
  end ;

  if fsComplemento = 'PR' then
  begin
     Tamanho := 10 ;
     xTP := 9   ;   yROT := 'E'   ;   yMD := 11   ;   yTP := 8 ;
     vDigitos := VarArrayOf(
        [ 'DVY','DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','','',''] ) ;
  end ;

  if fsComplemento = 'PE' then
  begin
     if Length(fsDocto) = 14 then
     begin
        Tamanho := 14;
        xTP := 7  ;   FatorF := 1;
        vDigitos := VarArrayOf(
          ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'1-9','8','1']);
     end
     else
      if Length(fsDocto) = 9 then
      begin
        Tamanho := 9;
        xTP  :=  9   ;  xMD := 11;
        yROT := 'E'  ;  yMD := 11  ;   yTP := 7;
        vDigitos := VarArrayOf(
        [ 'DVY','DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','','','',''] );
      end;
  end;

  if fsComplemento = 'PI' then
  begin
     Tamanho  := 9 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'9','1','','','','',''] ) ;
  end ;

  if fsComplemento = 'RJ' then
  begin
     Tamanho := 8 ;
     xTP := 8 ;
     vDigitos := VarArrayOf(
        ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'1,7,8,9','','','','','',''] ) ;
  end ;

  if fsComplemento = 'RN' then
  begin
      if Length(fsDocto) = 9 then
      begin
         Tamanho := 9 ;
         xROT := 'BD' ;
         vDigitos := VarArrayOf(
            [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'0','2','','','','',''] ) ;
      end
     else
       if Length(fsDocto) = 10 then
       begin
         Tamanho := 10 ;
         xROT := 'BD' ;
         xTP := 11 ;
         vDigitos := VarArrayOf(
            [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'0','2','','','',''] ) ;
       end;

  end ;

  if fsComplemento = 'RS' then
  begin
     Tamanho := 10 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'0-4','','','',''] ) ;
  end ;

  if fsComplemento = 'RO' then
  begin
     FatorF := 1 ;
     if Length(fsDocto) = 9 then
     begin
        Tamanho := 9 ;
        xTP := 4 ;
        vDigitos := VarArrayOf(
          [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'1-9','','','','',''] ) ;
     end ;

     if Length(fsDocto) = 14 then
     begin
        Tamanho  := 14 ;
        vDigitos := VarArrayOf(
        ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9]);
     end ;
  end ;
 
  if fsComplemento = 'RR' then
  begin
     Tamanho  := 9 ;
     xROT := 'D'   ;   xMD := 9   ;   xTP := 5 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'4','2','','','','',''] ) ;
  end ;

  if (fsComplemento = 'SC') or (fsComplemento = 'SE') then
  begin
     Tamanho  := 9 ;
     vDigitos := VarArrayOf(
        [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','','','',''] ) ;
  end;

  if fsComplemento = 'SP' then
  begin
     xROT := 'D'   ;   xTP := 12 ;
     if fsDocto[1] = 'P' then
      begin
        Tamanho  := 13 ;
        vDigitos := VarArrayOf(
         [c0_9,c0_9,c0_9,'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'P','']);
      end
     else
      begin
        Tamanho  := 12 ;
        yROT := 'D'   ;   yMD := 11   ;   yTP := 13 ;
        vDigitos := VarArrayOf(
         ['DVY',c0_9,c0_9,'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','']);
      end ;
  end ;

  if fsComplemento = 'TO' then
  begin
     if Length(fsDocto)=11 then
      begin
        Tamanho := 11 ;
        xTP := 6 ;
        vDigitos := VarArrayOf(
          ['DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'1,2,3,9','0,9','9','2','','','']);
      end
     else
      begin
{        Tamanho := 10 ;
        vDigitos := VarArrayOf(
          [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'0-4','','','',''] ) ; }
        Tamanho := 9 ;
        vDigitos := VarArrayOf(
          [ 'DVX',c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,c0_9,'','','','',''] )
      end;
  end ;

  { Verificando se o tamanho Total está correto }
  if fsAjustarTamanho then
     fsDocto := padR( fsDocto, Tamanho, '0') ;

  OK := (Tamanho > 0) and (Length(fsDocto) = Tamanho) ;
  if not OK then
     fsMsgErro := 'Tamanho Inválido' ;

  { Verificando os digitos nas posicoes são permitidos }
  fsDocto := padR(fsDocto,14) ;
  DVX := 0  ;
  DVY := 0  ;
  I   := 13 ;
  while OK and (I >= 0) do
  begin
     D := fsDocto[14-I] ;

     if vDigitos[I] = '' then
        OK := (D = ' ')

     else if (vDigitos[I] = 'DVX') or (vDigitos[I] = 'DVY') or
             (vDigitos[I] = c0_9) then
      begin
        OK := CharIsNum( D ) ;

        if vDigitos[I] = 'DVX' then
           DVX := StrToIntDef( D, 0 )
        else
           if vDigitos[I] = 'DVY' then
              DVY := StrToIntDef( D, 0 ) ;
      end

     else if pos(',',vDigitos[I]) > 0 then   { Ex: '2,5,7,8' Apenas os da lista}
        OK := (pos( D, vDigitos[I] ) > 0)

     else if pos('-',vDigitos[I]) > 0 then
        OK := ( (D >= copy(vDigitos[I],1,1)) and (D <= copy(vDigitos[I],3,1)) )

     else
        OK := ( D = vDigitos[I] ) ;

     if not OK then
        fsMsgErro := Format('Digito %d deveria ser %s ',
         [14-I-(14-Tamanho), vDigitos[I]]) ;

     I := I - 1 ;
  end ;

  Passo := 'X' ;
  while OK and (xTP > 0) do
  begin
     SOMA := 0  ;
     SOMAq:= 0  ;
     I    := 14 ;

     while OK and (I > 0) do
     begin
        D := fsDocto[15-I] ;

        if CharIsNum(D) then
        begin
           nD := StrToIntDef(D,0) ;
           M  := nD * cPesos[xTP,I] ;
           SOMA := SOMA + M ;

           if pos('A',xROT) > 0 then
              SOMAq := SOMAq + Trunc(M / 10) ;
        end ;

        I := I - 1 ;
     end ;

     if pos('A',xROT) > 0 then
        SOMA := SOMA + SOMAq

     else if pos('B',xROT) > 0 then
        SOMA := SOMA * 10

     else if pos('C',xROT) > 0 then
        SOMA := SOMA + (5 + (4 * FatorF) ) ;

     { Calculando digito verificador }
     DV := Trunc(SOMA mod xMD) ;
     if pos('E',xROT) > 0 then
        DV := Trunc(xMD - DV) ;

     if DV = 10 then
        DV := FatorG   { Apenas GO modifica o FatorG para diferente de 0 }
     else if DV = 11 then
        DV := FatorF ;

     if Passo = 'X' then
        OK := (DVX = DV)
     else
        OK := (DVY = DV) ;

     fsDigitoCalculado := IntToStr(DV) ;
     if not OK then
     begin
        fsMsgErro := 'Digito verificador inválido.' ;

        if fsExibeDigitoCorreto then
           fsMsgErro := fsMsgErro + '.. Calculado: '+fsDigitoCalculado ;
     end ;

     if PASSO = 'X' then
      begin
        PASSO := 'Y'  ;
        xROT  := yROT ;
        xMD   := yMD  ;
        xTP   := yTP  ;
      end
     else
        break ;
  end ;

  fsDocto := Trim( fsDocto ) ;
  if (fsMsgErro <> '') then
     fsMsgErro := 'Insc.Estadual inválida para '+fsComplemento +' '+ fsMsgErro ;

end;

//************************** Valida UF *****************************//
Procedure TACBrValidador.ValidarUF(UF: AnsiString) ;
begin
 if pos( ','+UF+',', ',AC,AL,AP,AM,BA,CE,DF,ES,GO,MA,MT,MS,MG,PA,PB,PR,PE,PI,'+
                     'RJ,RN,RS,RO,RR,SC,SP,SE,TO,') = 0 then
    fsMsgErro := 'UF inválido: '+UF ;
end;

//************************** Formata Inscrição Estadual *****************************//
function TACBrValidador.FormatarIE(AString, UF: AnsiString): AnsiString;
Var
  Mascara : AnsiString ;
  C : AnsiChar ;
  I, J, LenDoc, LenMas : Integer;
Begin
  Result := AString ;
  if UpperCase( Trim(AString) ) = 'ISENTO' then
     exit ;

  AString := LimpaDocto( AString ) ;
  UF      := UpperCase( UF ) ;

  LenDoc  := Length( AString ) ;
  Mascara := StringOfChar('*', LenDoc) ;

  IF UF = 'AC' Then Mascara := '**.***.***/***-**';
  IF UF = 'AL' Then Mascara := '*********';
  IF UF = 'AP' Then Mascara := '*********';
  IF UF = 'AM' Then Mascara := '**.***.***-*';
  IF UF = 'BA' Then Mascara := '******-**';
  IF UF = 'CE' Then Mascara := '********-*';
  IF UF = 'DF' Then Mascara := '***********-**';
  IF UF = 'ES' Then Mascara := '*********';
  IF UF = 'GO' Then Mascara := '**.***.***-*';
  IF UF = 'MA' Then Mascara := '*********';
  IF UF = 'MT' Then Mascara := '**********-*';
  IF UF = 'MS' Then Mascara := '*********';
  IF UF = 'MG' Then Mascara := '***.***.***/****';
  IF UF = 'PA' Then Mascara := '**-******-*';
  IF UF = 'PB' Then Mascara := '********-*';
  IF UF = 'PR' Then Mascara := '********-**';
  IF UF = 'PE' Then Mascara := IfThen((LenDoc>9),'**.*.***.*******-*','*******-**');
  IF UF = 'PI' Then Mascara := '*********';
  IF UF = 'RJ' Then Mascara := '**.***.**-*';
  IF UF = 'RN' Then Mascara := IfThen((LenDoc>9),'**.*.***.***-*','**.***.***-*');
  IF UF = 'RS' Then Mascara := '***/*******';
  IF UF = 'RO' Then Mascara := '*************-*'; // Antiga = '***.*****-*';
  IF UF = 'RR' Then Mascara := '********-*';
  IF UF = 'SC' Then Mascara := '***.***.***';
  IF UF = 'SP' Then Mascara := '***.***.***.***';
  IF UF = 'SE' Then Mascara := '**.***.***-*';
  IF UF = 'TO' Then Mascara := IfThen((LenDoc=11),'***********','**.***.***-*');

  Result := '';
  LenMas := Length( Mascara ) ;
  J := LenMas ;

  For I := LenMas downto 1 do
  begin
     C := Mascara[I] ;

     if C = '*' then
     begin
        if J <= ( LenMas - LenDoc ) then
           C := '0'
        else
           C := AString[( J - ( LenMas - LenDoc ) )] ;

        Dec( J ) ;
     end;

     Result := C + Result;
  End;

  Result := Trim( Result );
end;





Qualquer dúvida entre em contato.

Att.
Carlos Fitl.
Assinatura_nova.png

Renato Lima

unread,
Dec 13, 2011, 11:28:05 AM12/13/11
to openerp...@googlegroups.com
Olá Carlos,


Na localização brasileira fizemos parecido, mas com o python e o framework OpenObject é bem mais simples:

Colocamos a constraint no objeto res.partner

(_check_ie, u'Inscrição Estadual inválida!', ['inscr_est'])

Que ao salvar vai chamar o método privado da classe _check_ie:

def _check_ie(self, cr, uid, ids):
        """Checks if company register number in field insc_est is valid, 
        this method call others methods because this validation is State wise
        @param self: The object pointer
        @param cr: the current row, from the database cursor,
        @param uid: the current user’s ID for security checks,
        @param ids: List of partner Ids,
        @return: True or False.
        """       
        
        for partner in self.browse(cr, uid, ids):

            validate = getattr(self, '_validate_ie_%s' % partner.addr_fs_code, None)

            if not partner.inscr_est or partner.inscr_est == 'ISENTO' or not validate or partner.tipo_pessoa == 'F':
                return True

            if partner.tipo_pessoa == 'J':
                if callable(validate):
                    return validate(partner.inscr_est)

        return False

Este método é responsável por fazer dispatcher para todos os métodos que fazem a validação para cada estado, desta forma evita bastante no código vários "if":

 validate = getattr(self, '_validate_ie_%s' % partner.addr_fs_code, None)

Todos os métodos privados de validação para cada estado tem a nomeclatura _validate_ie_UF, desta forma concatenamos a string '_validate_ie_%s' % partner.addr_fs_code (UF do estado do endereço do parceiro) e atribuímos o método a variável validate, note que se o método não existir ele retorna o valor vazio (None).

E depois chamamos o método:

if callable(validate):
     return validate(partner.inscr_est)


O exemplo dos métodos de validação por estado:


def _validate_ie_rj(self, inscr_est):
        """Checks if company register number is valid to Brazilian
        state Rio de janeiro
        @param self: The object pointer
        @param inscr_est: The company state number value,
        @return: True or False.
        """
        
        # Limpando o cnpj
        if not inscr_est.isdigit():
            inscr_est = re.sub('[^0-9]', '', inscr_est)

        # verificando o tamano do  cnpj
        if len(inscr_est) != 8:
            return False

        # Pega apenas os 12 primeiros dígitos do CNPJ e gera os 2 dígitos que faltam
        inscr_est= map(int, inscr_est)
        nova_ie = inscr_est[:7]

        prod = [2, 7, 6, 5, 4, 3, 2]
        while len(nova_ie) < 8:
            r = sum([x*y for (x, y) in zip(nova_ie, prod)]) % 11
            if r > 1:
                f = 11 - r
            else:
                f = 0
            nova_ie.append(f)
            prod.insert(0, 6)

        # Se o número gerado coincidir com o número original, é válido
        if nova_ie == inscr_est:
            return True

        return False

def _validate_ie_sc(self, inscr_est):
        """Checks if company register number is valid to Brazilian
        state Santa Catarina
        @param self: The object pointer
        @param inscr_est: The company state number value,
        @return: True or False.
        """
        #TODO
        return True
    
def _validate_ie_se(self, inscr_est):
        """Checks if company register number is valid to Brazilian
        state Sergipe
        @param self: The object pointer
        @param inscr_est: The company state number value,
        @return: True or False.
        """
        #TODO
        return True
    
def _validate_ie_sp(self, inscr_est):
        """Checks if company register number is valid to Brazilian
        state São Paulo
        @param self: The object pointer
        @param inscr_est: The company state number value,
        @return: True or False.
        """
        #TODO
        return True
    
def _validate_ie_to(self, inscr_est):
        """Checks if company register number is valid to Brazilian
        state Tocantins
        @param self: The object pointer
        @param inscr_est: The company state number value,
        @return: True or False.
        """
        #TODO
        return True


Espero ter ajudado,


Renato Lima
Sócio Diretor
Assinatura_nova.png

Assinatura_nova.png
Assinatura_nova.png

Carlos Alberto Fitl

unread,
Dec 13, 2011, 11:43:10 AM12/13/11
to openerp...@googlegroups.com
Maravilha Renato, ficou show, como eu não conheço muito python eu enviei a função que utilizo do ACBr em um ERP que desenvolvi e Delphi, eu tambem desenvolvo em Java que tem mais semelhança com python do que delphi (rsrsrs), mas entendi seu código.

Estou dando uma mechida no Python para conhecer melhor e vou tentar ajudar conforme minha capacidade e no que precisar, não só em questão de desenvolver código mas também processos e analise.

Att.
Carlos Fitl.
Assinatura_nova.png

Renato Lima

unread,
Dec 13, 2011, 11:58:13 AM12/13/11
to openerp...@googlegroups.com
Olá Carlos,


Eu vim do VB e Java também rsrsrsrsrs, eu sei que no começo com Pyhton é um pouco complicado, não pela linguagem que no caso a sintaxes é bem simples principalmente para quem teve contato com Java, pois não tem muita burocracia na programação, a dificuldade é conhecer bem as bibliotecas do Pyhton e no caso do OpenERP conhecer o framework OpenObject, mas a medida que você se envolver com o OpenERP e estudar um pouco o código do OpenERP vai ajudar no seu aprendizado, um módulo que você pode estudar um pouco é o "base" que na versão 6.1 o pessoal da OpenERP S.A. melhorou bastante, principalmente na questão de boas práticas de programação com Pyhton, depois você pode dar uma olhada no PEP 8 para entender as boas praticas de estilo http://www.python.org/dev/peps/pep-0008/, pois infelizmente tem algumas coisas no OpenERP principalmente nos modulos do addons e addons-extra que precisa bastante melhorar nesta questão, mas até o momento ainda existe coisas muito mais urgente no framework que o pessoal esta investindo, por exemplo na questão de performance do OpenERP.


Um grande abraço !


Renato Lima
Sócio Diretor
Assinatura_nova.png


Assinatura_nova.png
Assinatura_nova.png

Leonardo Santagada

unread,
Dec 13, 2011, 12:01:09 PM12/13/11
to openerp...@googlegroups.com
Em 13 de dezembro de 2011 14:28, Renato Lima <renat...@gmail.com> escreveu:
>
> def _check_ie(self, cr, uid, ids):
>         """Checks if company register number in field insc_est is valid,
>         this method call others methods because this validation is State wise
>         @param self: The object pointer
>         @param cr: the current row, from the database cursor,
>         @param uid: the current user’s ID for security checks,
>         @param ids: List of partner Ids,
>         @return: True or False.
>         """
>
>         for partner in self.browse(cr, uid, ids):
>
>             validate = getattr(self, '_validate_ie_%s' % partner.addr_fs_code, None)
>
>             if not partner.inscr_est or partner.inscr_est == 'ISENTO' or not validate or partner.tipo_pessoa == 'F':
>                 return True
>
>             if partner.tipo_pessoa == 'J':
>                 if callable(validate):
>                     return validate(partner.inscr_est)
>
>         return False


Porque ele retorna falso caso não encontre o metodo de validação, isso
faz com que tenhamos que criar metodos para todos os estados ou o
usuário não vai poder cadastrar um ie de um estado que não temos
código de validação, fazendo uma profileferação de metodos vazios.

Outra, porque não dar um getattr e caso volte None já retorna True (ou
false), depois não precisa chamar callable.

Leonardo Santagada

unread,
Dec 13, 2011, 12:04:13 PM12/13/11
to openerp...@googlegroups.com
Em 13 de dezembro de 2011 14:58, Renato Lima <renat...@gmail.com> escreveu:
>
> , principalmente na questão de boas práticas de programação com Pyhton, depois você pode dar uma olhada no PEP 8 para entender as boas praticas de estilo http://www.python.org/dev/peps/pep-0008/,


Falando nisso, o PEP8 fala do http://www.python.org/dev/peps/pep-0257/
PEP 257 para docstrings boas. Porque não usar esse padrão ao invés do
que esta sendo usado (que se me lembro bem é o do doxygen)? Eu acho
esses @param feios e meio desnecessários, até porque o sphinx entende
docstrings no formado do pep 257

Carlos Alberto Fitl

unread,
Dec 13, 2011, 12:07:41 PM12/13/11
to openerp...@googlegroups.com
Ok, vou começar por onde você indicou e qualquer dúvida eu posto no fórum.

Obrigado pela atenção.

Carlos Fitl.

Renato Lima

unread,
Dec 13, 2011, 12:22:36 PM12/13/11
to openerp...@googlegroups.com
Leonardo,


Se você olhar antes de chamar o método eu faço isso: 

if not partner.inscr_est or partner.inscr_est == 'ISENTO' or validate or partner.tipo_pessoa == 'F':
      return True

Pois se o parceiro for isento ou pessoa física ou se não encontrou um método, não é preciso fazer a validação, eu criei os outros métodos vazios retornando True e coloquei #TODO para as validações ainda não implementada, mais para quem quiser contribuir só se preocupar em implementar o método, assim como coloquei as regras de validações nos blueprints.

Mas se não existisse os métodos não daria nenhum problema.


Espero ter ajudado,


Renato Lima
Sócio Diretor
Assinatura_nova.png


Assinatura_nova.png

Leonardo Santagada

unread,
Dec 13, 2011, 1:03:27 PM12/13/11
to openerp...@googlegroups.com
Em 13 de dezembro de 2011 15:22, Renato Lima <renat...@gmail.com> escreveu:
> if not partner.inscr_est or partner.inscr_est == 'ISENTO' or validate or partner.tipo_pessoa == 'F':
>       return True
>
> Pois se o parceiro for isento ou pessoa física ou se não encontrou um método, não é preciso fazer a validação


Por isso que não dá pra ter linhas tão compridas :). Outro problema,
esse bem pior, se tiver validando dois ao mesmo tempo, só vai rodar a
validação pro primeiro e o resultado vai valer para todos os partner?

Reply all
Reply to author
Forward
0 new messages