Ir para conteúdo
  • Cadastre-se

adenilton

Membros
  • Total de ítens

    67
  • Registro em

  • Última visita

  • Days Won

    1

Posts postados por adenilton

  1. A solução está divida em 5 projetos:

    1 - NFe.Classes - Contém todas as classes descritas nos manuais técnicos;

    2 - NFe.Certificado - Contém as classes responsáveis por manipular certificados digitais; 

    3 - NFe.Wsdl - Contém todas as classes que herdam de SoapHttpClientProtocol e que implementam o consumo de um determinado serviço;

    4 - NFe.Servicos - Contém a implementação de cada serviço e as classes com o tratamento de cada retorno;

    5 - NFe.Utils - Contém as classes que tem por objetivo estender as funcionalidades de algumas classes localizadas no projeto NFe.Classes, assim como classes auxiliares de apoio aos demais projetos.

     

    Até o domingo devo estar postando mais detalhes da estrutura e semana que vem irei liberar para vocês o código fonte do projeto, até mais.

    • Curtir 2
  2. Projeto sendo finalizado, segue algumas informações sobre o projeto:

     

    Serviços implementados (para todos os estados, todos os ambientes - Homologação e Produção, todas as formas de emissão - para os serviços de envio de NFe/NFc-e) 

    1 - RecepecaoEvento - Cancelamento de NFe/NFC-e, Carta de Correção e EPEC;

    2 - NfeRecepcao - Envio de NFe e lote versão 2.00;

    3 - NfeRetRecepcao - Consulta de recebimento de lote versão 2.00;

    4 - NfeInutilizacao - Inutilização de NFe/NFc-e;

    5 - NfeConsultaProtocolo - Consulta dados da NFe/NFc-e;

    6 - NfeStatusServico - Consulta status do serviço;

    7 - NfeAutorizacao - Envio de NFc-e e lote versão 3.10;

    8 - NfeRetAutorizacao - Consulta de recebimento de lote versão 3.10;

     

    Falta implementar:

    1 - NfeConsultaCadastro;

    2 - NfeDistribuicaoDFe;

    3 - NfeConsultaDest;

    4 - NfeDownlodNF;

     

    Outras coisas que falta implementar:

    1 - Impressão dos DANFES nativo c#;

    2 - Envio de emails;

    3 - Envio de NFc-e compactada versão 3.10;

    4 - Envio síncrono de NFe/NFc-e versão 3.10.

     

    Segue abaixo as telas do aplicativo de demonstração:

     

     

    post-1976-0-51071200-1419019461_thumb.pn

    post-1976-0-44015300-1419019470_thumb.pn

    post-1976-0-39086200-1419019476_thumb.pn

    post-1976-0-56845800-1419019483_thumb.pn

    post-1976-0-41074700-1419019490_thumb.pn

    • Curtir 4
  3. Aqui na empresa, utilizamos o delphi para desenvolver nosso principal produto, um ERP, no entanto, neste ano fizemos uma análise do futuro do mercado de software e temos visto que o visual studio tem agregado uma série de tecnologias até então indisponíveis no delphi, e que, com exceção do Brasil e Russia, o delphi tem perdido força no mundo inteiro, fazendo com que em agumas regiões já não se encontre mão de obra especializada.

    Por isso vamos desenvolver a solução para NFCe em visual studio e C#. 

    Quando decidimos isto, fizemos uma pesquisa por bibliotecas que já estivessem prontas para tal, e analisamos a UniNfe da Unimake Software, o ACBRNFeMonitor e o projeto Open NFe.

     

    No caso da UniNfe, vimos que ela implementa o consumo dos webservices para NF-e, NFC-e, CT-e, MDF-e e NFS-e e faz a Integração ao ERP via arquivos, mas infelizmente não gera o XML e não possui classes para tal. Outro ponto negativo é o fato de ter que persistir arquivos em disco para poder consumir os serviços, o que diminui a eficiência.

     

    O ACBRNFeMonitor possui integração via troca de arquivos, como no caso da UniNfe, e via telnet, mas o retorno de alguns serviços deixa a desejar pelo fato de devolver uma resposta em formato diferente dos manuais para aquele serviço. Outro fator é a integração com o C#.

     

    Por último o OpenNFe tem um acoplamento forte com o Sql Server, e ainda a forma como foram implementadas as classes não facilita o uso. Basicamente o autor pegou os schemas e importou-os no c#, sem muito tratamento.

     

    No meu caso, estou tendo o cuidado de escrever as classes seguindo rigorosamente os manuais disponíveis, inclusive quanto a forma como os serviços são consumidos. Até mesmo os comentários para cada campo disponíveis nos manuais foram adicionados em cada campo de cada classe.

     

    Uma coisa que percebi analisando o código do componente do ACBR para NFe é que por conta das limitações do Delphi, o estilo de programação utilizado apresenta risco considerável e dificuldade de manutenibilidade do código. Por exemplo, existe muita, mas muita magic string no código, enquanto no C# o tratamento de XML é nativo via serialização.

     

    Em breve postarei mais informações sobre a biblioteca, saudações.

    • Curtir 4
  4. Estou finalizando o desenvolvimento de uma biblioteca 100% em C# que englobará o consumo de todos os serviços em todas as versões disponibilizadas e em para todos os estados. Essa biblioteca será utilizada em produção em um aplicativo de frente de loja para emissão de NFC-e. Também está sendo construído um aplicativo de demonstração em wpf semelhante ao ACBrNFe_demo. Se for de interesse da comunidade nestes quinze dias ela deve ficar pronta, e posso disponibilizar se houver interesse em utilizá-la e me ajudar a mantê-la

    • Curtir 6
  5. Boa tarde, fiz uma alteração na função TRetDPEC.LerXml da unit pcnRetDPEC, permitindo assim a obtenção dos valores dos campos tpAmb, verAplic, cStat e xMotivo para quando nenhuma DPEC é anexada ao arquivo de retorno.

     

    Essa situação pode ocorrer, por exemplo, ao utilizar a consulta DPEC para uma chave que não tenha sido enviada anteriormente, caso onde o serviço retornará a cstat 127 (Inexiste DPEC para a chave de acesso informada), ou em qualquer situação onde nenhuma DPEC seja anexada ao retorno.

     

    Alteração da função de:

    function TRetDPEC.LerXml: boolean;
    var
      ok: boolean;
    begin
      Result := False;
      try
        if Leitor.rExtrai(1, 'infDPECReg') <> '' then
        begin
          (*AR04 *)FId := Leitor.rAtributo('infDPECReg Id=');
          (*AR05 *)FtpAmb := StrToTpAmb(ok, Leitor.rCampo(tcStr, 'tpAmb'));
          (*AR06 *)FverAplic := Leitor.rCampo(tcStr, 'verAplic');
          (*AR07 *)FcStat := Leitor.rCampo(tcInt, 'cStat');
          (*AR08 *)FxMotivo := Leitor.rCampo(tcStr, 'xMotivo');
          if cStat = 124 then
          begin
            (*AR09 *)FdhRegDPEC := Leitor.rCampo(tcDatHor, 'dhRegDPEC');
            (*AR10 *)nRegDPEC := Leitor.rCampo(tcStr, 'nRegDPEC');
    
            (*AR10 *)FchNFe := Leitor.rCampo(tcStr, 'chNFe');
          end;
          Result := True;
        end;
      except
        Result := False;
      end;
    end;
    

    para:

    function TRetDPEC.LerXml: boolean;
    var
      ok: boolean;
    begin
      Result := False;
      try
        if Leitor.rExtrai(1, 'infDPECReg') <> '' then
        begin
          (*AR04 *)FId := Leitor.rAtributo('infDPECReg Id=');
          (*AR05 *)FtpAmb := StrToTpAmb(ok, Leitor.rCampo(tcStr, 'tpAmb'));
          (*AR06 *)FverAplic := Leitor.rCampo(tcStr, 'verAplic');
          (*AR07 *)FcStat := Leitor.rCampo(tcInt, 'cStat');
          (*AR08 *)FxMotivo := Leitor.rCampo(tcStr, 'xMotivo');
          if cStat = 124 then
          begin
            (*AR09 *)FdhRegDPEC := Leitor.rCampo(tcDatHor, 'dhRegDPEC');
            (*AR10 *)nRegDPEC := Leitor.rCampo(tcStr, 'nRegDPEC');
    
            (*AR10 *)FchNFe := Leitor.rCampo(tcStr, 'chNFe');
          end;
          Result := True;
        end
        else //Não foi anexado um retorno de DPEC "retDPEC" ao XML, logo não encontrou a tag infDPECReg. Ver pg 139 e 140 do manual de orientação 5.0, item 8.6.3
             //Retorno: Estrutura XML de retorno, "pode" conter uma DPEC localizada. {Nem sempre vai encontrar uma DPEC anexada ao retorno}
        begin
          if Leitor.rExtrai(1, 'retConsDPEC') <> '' then
          begin
            (*BR03 *)FtpAmb := StrToTpAmb(ok, Leitor.rCampo(tcStr, 'tpAmb'));
            (*BR04 *)FverAplic := Leitor.rCampo(tcStr, 'verAplic');
            (*BR05 *)FcStat := Leitor.rCampo(tcInt, 'cStat');
            (*BR06 *)FxMotivo := Leitor.rCampo(tcStr, 'xMotivo');
            Result := True;
          end
        end;
      except
        Result := False;
      end;
    end;
    
    

    Além disso, a função "TNFeConsultaDPEC.Executar" da unit ACBrNFeWebServices, deveria ter seu resultado alterado de:

    Result := ({RetDPEC}FretDPEC.cStat = 125);
    

    para:

    Result := ({RetDPEC}FretDPEC.cStat in [124, 125]); 

    Uma vez que quando o resultado da consulta traz uma DPEC anexada, o componente trata a tag "infDPECReg", e nesta tag o cStat para "DPEC recebido pelo Sistema .." é 124 e não 125. O cStat 125 fica para a tag "retConsDPEC".

     

     

    Alguém poderia verificar isso e subir para o svN?

  6. Boa tarde,

     

    Observei que o DANFE em Fast Reports está imprimindo a informação de CSOSN para empresas com CRT = 2 " Simples Nacional - excesso de sublimite de receita bruta", quando deveria imprimir as informações de CST, semelhante às empresas com tributação Normal.

     

    O erro está na linha 643 da unit ACBrNFeDANFEFRDM.pas onde encontramos:

             case FNFe.Emit.CRT of
                crtSimplesNacional, crtSimplesExcessoReceita:
                  begin
                    case CSOSN of
                      csosn101, csosn102, csosn103, csosn201, csosn202, csosn203, csosn300, csosn400, csosn500, csosn900:
                        begin
                          FieldByName('CST').AsString  := CSOSNIcmsToStr(CSOSN);
                          FieldByName('VBC').AsFloat   := vBC;
                          FieldByName('PICMS').AsFloat := pICMS;
                          FieldByName('VICMS').AsFloat := vICMS;
                        end;
                    end;
                  end;
              else
    

    Quando deveria ser:

             case FNFe.Emit.CRT of
                crtSimplesNacional:
                  begin
                    case CSOSN of
                      csosn101, csosn102, csosn103, csosn201, csosn202, csosn203, csosn300, csosn400, csosn500, csosn900:
                        begin
                          FieldByName('CST').AsString  := CSOSNIcmsToStr(CSOSN);
                          FieldByName('VBC').AsFloat   := vBC;
                          FieldByName('PICMS').AsFloat := pICMS;
                          FieldByName('VICMS').AsFloat := vICMS;
                        end;
                    end;
                  end;
              else
    

    E na linha 868 da unit ACBrNFeDANFEFRDM.pas onde encontramos:

    if Trim(FieldByName('CRT').AsString) = '3' then 
      FieldByName('DESCR_CST').AsString := 'CST'   
    else
      FieldByName('DESCR_CST').AsString  := 'CSOSN';
    

    Quando deveria ser:

    if Trim(FieldByName('CRT').AsString) = '1' then 
      FieldByName('DESCR_CST').AsString := 'CSOSN'   
    else
      FieldByName('DESCR_CST').AsString  := 'CST';
    

    Alguém poderia verificar isso?

     

  7. A função CollateBr suprimia caracteres não identificados no case, exemplo: se passásemos 'N.TESTE' ela devolvia 'NN TESTE'.

     

    Sugestão de correção da função function CollateBr(Str: String): String;

    para:

    function CollateBr(Str: String): String;
    var
      Resultado,Temp: string;
      vChar: Char;
      Tamanho, i: integer;
    begin
      Result := '';
      Tamanho := Length(str);
      i := 1;
      while i <= Tamanho do
      begin
        Temp := Copy(str,i,1);
        vChar := Temp[1];
        Resultado := vChar; //Adicionado, pois quando encontrava um caractere não previsto no case abaixo, a função suprimia o caractere. Exemplo 'N. TESTE' ficava 'NN TESTE'
        case vChar of
          'á', 'â', 'ã', 'à', 'ä', 'å', 'Á', 'Â', 'Ã', 'À', 'Ä', 'Å': Resultado := 'A';
          'é', 'ê', 'è', 'ë', 'É', 'Ê', 'È', 'Ë': Resultado := 'E';
          'í', 'î', 'ì', 'ï', 'Í', 'Î', 'Ì', 'Ï': Resultado := 'I';
          'ó', 'ô', 'õ', 'ò', 'ö', 'Ó', 'Ô', 'Õ', 'Ò', 'Ö': Resultado := 'O';
          'ú', 'û', 'ù', 'ü', 'Ú', 'Û', 'Ù', 'Ü': Resultado := 'U';
          'ç', 'Ç': Resultado := 'C';
          'ñ', 'Ñ': Resultado := 'N';
          'ý', 'ÿ', 'Ý', 'Y': Resultado := 'Y';
        else
          if vChar > #127 then Resultado := #32
          {$IFDEF DELPHI12_UP}
          else if CharInset(vChar, ['a'..'z','A'..'Z','0'..'9','-',' ']) then
          {$ELSE}
          else if vChar in ['a'..'z','A'..'Z','0'..'9','-',' '] then
          {$ENDIF}
            Resultado := UpperCase(vCHAR);
        end;
        Result := Result + Resultado;
        i := i + 1;
      end;
    end;
    
    
  8. EMBarbosa, Bom dia. Passei pelo mesmo problema relatado por maooliveira e altc, eles têm razão, mas talvez não tenha passado o problema em pormenores. Então vejamos:

    No guia prático versão 1.06, registro C481 nos informa que os campos 01 (REG), 02 (CST_PIS) e 03 (VL_ITEM) são obrigatórios, os demais são opcionais, a mesma coisa para o registro C485.

    Em suma, no guia, as configurações de obrigatoriedade dos dois registros são idênticas, mas não é isso que vemos na unit ACBrEPCBloco_C_Class.pas, veja a declaração dos dois registros como estão:

    [C481]

    
            Add( LFill('C481')             +
    
                 LFill(strCST_PIS)         +
    
                 LFill(VL_ITEM,0,2)        +
    
                 DFill(VL_BC_PIS,      2, True) +
    
                 DFill(ALIQ_PIS,       4, True) +
    
                 DFill(QUANT_BC_PIS,   3, True) +
    
                 DFill(ALIQ_PIS_QUANT, 4, True) +
    
                 LFill(VL_PIS,0,2)         +
    
                 LFill(COD_ITEM)           +
    
                 LFill(COD_CTA) ) ;
    
    
    [C485]
    
            Add( LFill('C485')               +
    
                 LFill(strCST_COFINS)        +
    
                 LFill(VL_ITEM,0,2)          +
    
                 LFill(VL_BC_COFINS,0,2)     +
    
                 DFill(ALIQ_COFINS, 4)       +
    
                 DFill(QUANT_BC_COFINS,   3, True) +
    
                 DFill(ALIQ_COFINS_QUANT, 4, True) +
    
                 LFill(VL_COFINS,0,2)        +
    
                 LFill(COD_ITEM)             +
    
                 LFill(COD_CTA) ) ;
    
    
    Então o que acontece é que para a CST 06, por exemplo, o registro C481 está indo com o campo 04 (VL_BC_PIS) e 05 (ALIQ_PIS) vazios "|" e no registro C485, para o mesmo item, o campo 04 (VL_BC_COFINS) e o campo 05 (ALIQ_COFINS) está indo com 0 "|0,00|". E isto é entendido pelo validador como erro, tanto que ele exibe a seguinte mensagem de erro na validação: "Mensagem: Para cada registro filho referente ao PIS deve existir outro registro filho referente a COFINS com CST referente ao PIS/PASEP igual ao CST referente à COFINS, e Valor da Base de Cálculo do PIS/PASEP, igual ao Valor da base de cálculo da COFINS. Veja a screen: 50780822.jpg Agora note que o registro C481 está com os campos acima informados, vazios: 97082944.jpg E por último o registro C485 com os campos preenchidos com 0: 97316534.jpg O erro está no registro C485, que deveria estar assim:
    
            Add( LFill('C485')                     +
    
                 LFill(strCST_COFINS)              +
    
                 LFill(VL_ITEM,0,2)                +
    
                 DFill(VL_BC_COFINS, 2, True)      +
    
                 DFill(ALIQ_COFINS, 4, True)       +
    
                 DFill(QUANT_BC_COFINS, 3, True)   +
    
                 DFill(ALIQ_COFINS_QUANT, 4, True) +
    
                 LFill(VL_COFINS,0,2)              +
    
                 LFill(COD_ITEM)                   +
    
                 LFill(COD_CTA) ) ;
    
    

  9. Pois é, a dúvida é tenho que mandar TODAS as correções anteriores como EVENTO ou pode ser no campo de texto livre xCORRECAO ??? Alguém será que já conseguiu mandar mais de uma correção ??? Se eu mandar somente 1 correção no EVENTO001, registra normalmente e retorna ok pelo monitor e quando consulto na pagina da RECEITA, a correção tá lá...

    t+

    Wagner as Notas técnicas 2010.008 e 2011.003 são claras com respeito a não cumulatividade das correções feitas à NFE. Desta forma, a última correção (ou evento do tipo correção) implica na nulidade completa da correção anterior, sendo que só é possível enviar até 20 correções para uma mesma nfe.

    Quanto à sua dúvida de como montar o arquivo para envio em lote com diversas correções, sugiro que consulte o fonte do AcbrNfe_Demo e faça os testes nele. Agora se pensarmos melhor, pra que enviar correções em lote para uma mesma nfe? sendo que só será válida a última, ou seja as demais serão desconsideradas.

    Abaixo segue a parte do código fonte p/envio de lote de correções, constante no AcbrNfe_Demo. Eu fiz com o Demo do ACBR e deu tudo certo, o único problema que encontrei foi o que relatei no post anterior, que diz respeito ao elemento do xml gerado pelo acbr.

    
    var
    
     Chave, idLote, codOrgao, CNPJ, nSeqEvento, Correcao : string;
    
    begin
    
      if not(InputQuery('WebServices Carta de Correção', 'Chave da NF-e', Chave)) then
    
         exit;
    
      Chave := Trim(OnlyNumber(Chave));
    
    {  if not ValidarChave(Chave) then
    
       begin
    
         MessageDlg('Chave Inválida.',mtError,[mbok],0);
    
         exit;
    
       end;   }
    
      idLote := '1';
    
      if not(InputQuery('WebServices Carta de Correção', 'Identificador de controle do Lote de envio do Evento', idLote)) then
    
         exit;
    
      codOrgao := copy(Chave,1,2);
    
      if not(InputQuery('WebServices Carta de Correção', 'Código do órgão de recepção do Evento', codOrgao)) then
    
         exit;
    
      CNPJ := copy(Chave,7,14);
    
      if not(InputQuery('WebServices Carta de Correção', 'CNPJ ou o CPF do autor do Evento', CNPJ)) then
    
         exit;
    
      nSeqEvento := '1';
    
      if not(InputQuery('WebServices Carta de Correção', 'Sequencial do evento para o mesmo tipo de evento', nSeqEvento)) then
    
         exit;
    
      Correcao := 'Correção a ser considerada, texto livre. A correção mais recente substitui as anteriores.';
    
      if not(InputQuery('WebServices Carta de Correção', 'Correção a ser considerada', Correcao)) then
    
         exit;
    
      ACBrNFe1.CartaCorrecao.CCe.Evento.Clear;
    
       ACBrNFe1.CartaCorrecao.CCe.idLote := StrToInt(idLote) ;
    
      with ACBrNFe1.CartaCorrecao.CCe.Evento.Add do
    
       begin
    
         infEvento.chNFe := Chave;
    
         infEvento.cOrgao := StrToInt(codOrgao);
    
         infEvento.CNPJ   := CNPJ;
    
         infEvento.dhEvento := now;
    
         infEvento.tpEvento := 110110;
    
         infEvento.nSeqEvento := StrToInt(nSeqEvento);
    
         infEvento.versaoEvento := '1.00';
    
         infEvento.detEvento.descEvento := 'Carta de Correção';
    
         infEvento.detEvento.xCorrecao := Correcao;
    
         infEvento.detEvento.xCondUso := ''; //Texto fixo conforme NT 2011.003 -  http://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=tsiloeZ6vBw=
    
       end;
    
      ACBrNFe1.EnviarCartaCorrecao(StrToInt(idLote));
    
    
      MemoResp.Lines.Text := UTF8Encode(ACBrNFe1.WebServices.CartaCorrecao.RetWS);
    
      memoRespWS.Lines.Text := UTF8Encode(ACBrNFe1.WebServices.CartaCorrecao.RetornoWS);
    
      LoadXML(MemoResp, WBResposta);
    
    

×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...