Clique para saber mais...
  Home     Download     Produtos / Cursos     Revista     Vídeo Aulas     Fórum     Contato   Clique aqui para logar | 12 de Junho de 2026
  Login

Codinome
Senha
Salvar informações

 Esqueci minha senha
 Novo Cadastro

  Usuários
168 Usuários Online

  Revista ActiveDelphi
 Assine Já!
 Edições
 Sobre a Revista

  Conteúdo
 Apostilas
 Artigos
 Componentes
 Dicas
 News
 Programas / Exemplos
 Vídeo Aulas

  Serviços
 Active News
 Fórum
 Produtos / Cursos

  Outros
 Colunistas
 Contato
 Top 10

  Publicidade

  [Artigos]  Assinatura em Massa e geração de Lote para NF-e
Publicado por ActiveDelphi : Quinta, Maio 21, 2009 - 12:10 GMT-3 (4633 leituras)
Comentários 11 Comentários   Enviar esta notícia a um amigo Enviar para um amigo   Versão para Impressão Versão para impressão
Victory Fernandes No artigo “Assinatura Digital para NF-e”, abordamos e exemplificamos os aspectos envolvidos no uso de certificados digitais da CertiSign para assinatura dos arquivos de Nota Fiscal Eletrônica (NF-e) gerados

A NFe é um documento emitido e armazenado eletronicamente, com validade jurídica garantida por processo de assinatura digital. O principal objetivo da implantação desta nova modalidade é o acompanhamento em tempo real das operações comercias pelo Fisco e a substituição do modelo atual de emissão de documentos fiscais em papel, de forma a simplificar uma série de obrigações do contribuinte. Maiores informações podem ser obtidas através do portal nacional em www.nfe.fazenda.gov.br
Seguindo a linha de publicações voltadas às soluções para NFe damos continuidade a esta série mantendo o foco no processo de assinatura digital, desta vez para assinatura de NFe em massa e criação de lotes de NFe. Para realizar o processo de assinatura utilizamos a assinaturaNFe32dll.dll.
Para o entendimento desse artigo, partiremos do princípio de que o leitor já possui o conhecimento de como gerar e assinar uma NFe, abordado nos artigos “Certificação Digital para NF-e” e “Assinatura Digital para NF-e”.
 

Assinatura em massa de NFe e criação de Lotes
    De acordo com o manual de integração da NFe disponibilizado no portal oficial em www.nfe.fazenda.gov.br  somente arquivos de Lote de NFe podem ser transmitidos, ou seja, mesmo que se deseje transmitir apenas uma única NFe teremos de criar um lote contendo a mesma para que seja possível transmiti-la.
    Um arquivo de lote de NFe pode conter de 1 até 50 NFe e deve ter tamanho máximo de 500Kbytes, e somente os arquivos de NFe devem ser assinados, o lote em si não é assinado.
    Para demonstrar como é fácil assinar uma NFe, utilizaremos a assinaturaNFe32dll.dll e o aplicativo demo que acompanha a mesma, e pode ser obtido a partir do site http://www.igara.com.br/produto.php?cod_produto=114
    Após o download, executamos o aplicativo Demo_EnviNFe_.exe (Figura 01) contido na pasta de Geracao_XML/PL005a/enviNFe e selecionamos o caminho dos arquivos a serem assinados através da árvore de pastas apresentada à esquerda da tela. À direita podem ser visualizados os arquivos contidos na pasta escolhida. Selecione quais arquivos de NFe devem ser assinados, caso não tenha nenhum arquivo de NFe disponível é possível gerá-los com base no demo disponível na pasta Geracao_XML/PL005a/nfe. Para selecionar mais de uma, segure a tecla Ctrl e clique sobre os arquivos desejados.
 
    Uma vez selecionados os arquivos da NFe, é possível:
        · Assinar digitalmente todos os arquivos de NFe selecionados;
        · Criar um lote contendo todas as notas selecionadas; Para o uso desta opção parte-se do princípio que os arquivos de NFe selecionados já se encontram assinados.
        · Assinar todos os arquivos de NFe e logo em seguida criar um lote com todas as notas selecionadas;
 

Figura 01 – Aplicativo EnviNFe


    Para apenas assinar as notas selecionadas, clique no botão “Assinar Arquivos Selecionados”. Será mostrada ao usuário uma caixa de seleção (Figura 02) onde deve ser escolhido o Certificado Digital a ser utilizado. Selecione o certificado e clique em OK. Caso esteja utilizando o eToken da CertiSign, ou outro certificado A3, uma janela será exibida (Figura 03) solicitando a senha para uso do certificado.
 

Figura 02 – Caixa de seleção de certificado

 

Figura 03 – Seleção do eToken e senha


    De forma resumida, o código do evento OnClick do botão “Assinar Arquivos Selecionados” implementa um loop nos arquivos selecionados e faz uma chamada da função fncAssinarXML assinando sequencialmente cada um dos arquivos selecionados.
    A seguir apresentado código que mostra como é  simples realizar o processo de assinatura em massa com o trecho de código relativo ao evento OnClick do botão citado.
 

procedure TForm1.Button2Click(Sender: TObject);
var
  i: integer;
  nfe_STR: TStrings;
  antes, depois: TTime;
begin
  //Se nenhuma NFe selecionada
  if FileListBox1.SelCount <= 0 then
  begin
    ShowMessage('Nenhum arquivo de NFe selecionado' + #13 +

    'Selecione pelo menos um arquivo de NFe para assinar');
    Exit;
  end;
 
  antes := now;
 
  //inicializa o progressbar
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;
  ProgressBar1.max := FileListBox1.SelCount;
 
  //cria objeto da nota
  nfe_STR := TStringList.Create;
  nfe_STR.Clear;
 
  //Faz loop nas notas selecionadas assinando-as
  for i := 0 to FileListBox1.Items.Count - 1 do
  begin
    if FileListBox1.Selected[i] then //se o arquivo estiver selecionado
    begin
      //carrega para a variável
      nfe_STR.LoadFromFile(DirectoryListBox1.Directory + '\' + FileListBox1.Items.Strings[i]);
  
      //assina nota
      nfe_STR.Text := fncAssinarXML(nfe_STR);
  
      //salva nota assinada
      nfe_STR.SaveToFile(DirectoryListBox1.Directory + FileListBox1.Items.Strings[i]);
 
      //incrementa progressbar
      ProgressBar1.StepIt;
    end;
  end;
  //libera memoria da nota
  nfe_STR.Free;
 
  depois := now;
  //mostra mensagem de nota salva e calcula tempo gasto para assiná-la
  Showmessage('Assinatura Concluída' + #13#10 +
  'Tempo Total (seg): ' + inttostr(SecondsBetween(antes, depois)) + #13#10 +
  'Tempo Médio (seg): ' + formatfloat('0.00', SecondsBetween(antes, depois)/FileListBox1.SelCount));
end;

 

    Como o objetivo da aplicação é assinar várias notas de uma só vez, não teria sentido se o usuário fosse solicitado a selecionar o certificado e digitar a senha a cada nota durante o loop principal da aplicação. Visando eliminar este trabalho, é possível marcar a opção “Usar este certificado como padrão e não perguntar novamente” na tela de seleção de certificados, para que a caixa de seleção não seja mais exibida e todas as suas notas sejam assinadas com o certificado selecionado.
    Esse recurso é disponibilizado pela assinaturaNFe32dll.dll e pode ser utilizado em qualquer aplicativo que use a mesma.
    Ao selecionar a opção para não mais perguntar sobre o certificado, é criado na mesma pasta da assinaturaNFe32dll.dll, um arquivo chamado “DefCertificado.res”. Esse arquivo armazena qual o índice do certificado na lista. Caso queira que a caixa de seleção de certificados volte a aparecer basta apagar o arquivo “DefCertificado.res”.
    O procedimento de apagar o arquivo pode ser feito tanto manualmente pelo usuário, como pelo aplicativo que está utilizando a assinaturaNFe32dll.dll. A seguir é apresentada uma proposta de código que permite excluir o arquivo “DefCertificado.res” a partir do clique em um botão da sua aplicação.
 

procedure TForm1.Button3Click(Sender: TObject);
var
  myfilename: String;
begin
  try
  //Configura o diretório onde se encontra o arquivo que armazena o índice
  //Da forma que está implementada aqui só funciona se a dll estiver localizada no mesmo diretório do .exe
  myfilename := ExtractFilePath(application.ExeName) + '\DefCertificado.res';
 
  //testa se arquivo existe
  if fileexists(myfilename) then
  begin
    //exclue o arquivo q armazena o índice
    //Usuário logado no windows deve ter permissões sobre o diretório e o arquivo em questão
    DeleteFile(myfilename);
 
    showmessage('Arquivo' + myfilename + 'excluído. O sistema voltará a solicitar que o usuário selecione o    

    certificado desejado para a assinatura');
  end;
  except
    showmessage('Erro durante exclusão do arquivo ' + myfilename)
  end;
end;

 

    Agora que já vimos como realizar o processo de assinatura em massa de arquivos de NFe, vamos gerar um lote a partir dos arquivos que foram assinados.
    Para criar um lote de NFe, selecione as notas desejadas e clique no botão “Gerar lotes dos arquivos assinados”. Vale lembrar que só é possível gerar lotes contendo arquivos de NFe já assinados.
    Conforme já dito anteriormente o lote é necessário para que seja possível transmitir suas notas, pois não é possível transmitir notas  individualmente sem que as mesmas estejam contidas em um lote. Elas precisam ser agrupadas em lotes, para depois serem enviadas. Mesmo que deseje enviar apenas uma nota, essa deve estar dentro de um lote.
    Conforme descrito no manual de integração (Figura 4), a estrutura de um lote é muito simples e consiste em uma concatenação de todos os arquivos XML que vão formá-lo e a adição de um cabeçalho e um rodapé.
 

Figura 04 – Estrutura do arquivo de lote conforme manual de integração


    No cabeçalho do lote o conteúdo do campo “versão” é fixo e deverá ser conforme valor apresentado na tabela (Figura 05) também disponibilizada no manual de integração da NFe.
 

Figura 05 – Valor do campo versão do arquivo de lote
 


    Ainda conforme a tabela que define a estrutura do arquivo de lote (Figura 04) temos que o campo ‘id”, identificador de controle do envio do lote é um número seqüencial auto-incremental sendo a responsabilidade de gerar e controlar este número exclusiva do contribuinte.
    Assim espera-se que o cabeçalho do lote gerado seja algo conforme mostrado a seguir.
 

<?xml version="1.0" encoding="UTF-8" ?>
<enviNFe xmlns=http://www.portalfiscal.inf.br/nfe xmlns:ds=http://www.w3.org/2000/09/xmldsig# xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.portalfiscal.inf.br/nfe enviNFe_v1.10.xsd" versao="1.10">
<idLote>000000000000001</idLote>

 

  Algumas UFs rejeitam os parâmetros de NameSpace informados no cabeçalho anterior, podendo o mesmo ser gerado da seguinte forma alternativa.

 

<?xml version="1.0" encoding="UTF-8" ?>
<enviNFe xmlns=http://www.portalfiscal.inf.br/nfe xsi:schemaLocation="http://www.portalfiscal.inf.br/nfe enviNFe_v1.10.xsd" versao="1.10">
<idLote>000000000000001</idLote>

 

    Segundo o manual de integração do contribuinte, cada arquivo XML só pode possuir uma única declaração do cabeçalho “<?xml version="1.0" encoding="UTF-8"?>”, ou seja, nas situações onde um documento XML pode conter outros dentro do mesmo, arquivos de lote por exemplo, apenas o lote pode conter a tag em questão, removendo dos XML de todas as outras notas essa tag.
    Sendo assim, ao realizar a concatenação de todos os arquivos XML de NFe selecionados para compor o lote é muito importante retirar dos arquivos somente o conteúdo a partir da tag “<NFe”, excluindo qualquer coisa que venha antes (Figura 06).
 

Figura 06 – Arquivo de NFe. Remoção do conteúdo antes da tag “<NFe”
 


    Ao final da concatenação a aplicação deve somente incluir o rodapé “</enviNFe>” que finaliza o arquivo de lote fechando a tag que foi aberta no cabeçalho.
    Aseguir temos o código do evento OnClick do botão “Gerar lotes dos arquivos assinados” que executa os procedimentos descritos anteriormente.
 

procedure TForm1.Button5Click(Sender: TObject);
var
  F: TextFile;
  i: integer;
  nfe_STR: TStrings;
  buf: String;
  antes, depois: TTime;
begin
  //Se nenhuma NFe selecionada
  if FileListBox1.SelCount <= 0 then
  begin
    ShowMessage('Nenhum arquivo de NFe selecionado' + #13 +
    'Selecione pelo menos um arquivo de NFe para integrar o novo lote');
    Exit;
  end;
 
  //Nº máximo de Notas por lote é 50
  if FileListBox1.SelCount > 50 then
  begin
    ShowMessage('O lote não pode possuir mais de 50 notas' + #13 +
    'Retire algumas notas e tente novamente');
    Exit;
  end;
 
  antes := now;
 
  //inicializa o progressbar
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;
  ProgressBar1.max := FileListBox1.SelCount;
 
  //cria objeto da nota
  nfe_STR := TStringList.Create;
  nfe_STR.Clear;
 
  AssignFile(F, DirectoryListBox1.Directory + '\' + copy(ValueListEditor76.Values['idLote'], 4, 44) + '-env-lot.xml');
  Rewrite(F);
 
  //cria cabeçalho do lote
  Write(F, '<?xml version="1.0" encoding="UTF-8"?>');
  if FormataCampo(ValueListEditor76, 'versao', 'N', 4) then
    Write(F, '<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.portalfiscal.inf.br/nfe   enviNFe_v1.10.xsd" versao="' + ValueListEditor76.Values['versao'] + '">');
  if FormataCampo(ValueListEditor76, 'idLote', 'N', 15) then
    Write(F, '<idLote>' + ValueListEditor76.Values['idLote'] + '</idLote>');
 
  //Faz loop nas notas selecionadas assinando-as
  for i := 0 to FileListBox1.Items.Count - 1 do
  begin
    if FileListBox1.Selected[i] then //se o arquivo estiver selecionado
    begin
      nfe_STR.LoadFromFile(DirectoryListBox1.Directory + '\' + FileListBox1.Items.Strings[i]);
   
      //Adiciona todas as notas ao buffer
      buf := copy(nfe_STR.text, pos('<NFe', nfe_STR.text), length(nfe_STR.text));
 
      Write(F, buf);
 
      ProgressBar1.StepIt;
    end;
  end;
  //fecha rodapé de lote
  Write(F, '</enviNFe>');
 
  //libera arquivo
  CloseFile(F);
 
  depois := now;
  //mostra mensagem de nota salva e calcula tempo gasto para assiná-la
  Showmessage('Geração do Lote Concluída' + #13#10 +
  'Tempo Total (seg): ' + inttostr(SecondsBetween(antes, depois)) + #13#10 +
  'Tempo Médio (seg): ' + formatfloat('0.00', SecondsBetween(antes, depois)/FileListBox1.SelCount));
 
end;

 

    Para agilizar ainda mais o processo de assinatura em massa de notas, podemos usar o botão “Assinar e Gerar Lote dos arquivos selecionados”. Esse botão junta a funcionalidade de assinatura em massa e geração de lote em apenas um click facilitando ainda mais o processo.
    O código do evento OnClick desse botão é simplesmente a junção do código dos outros dois botões apresentados anteriormente, como pode ser visto a seguir.
 

procedure TForm1.Button61Click(Sender: TObject);
var
  i: integer;
  nfe_STR: TStrings;
  F: TextFile;
  F_Temp: File of Byte;
  buf, myfilename: String;
  antes, depois: TTime;
  Tamanho_Lote: Double;
begin
  //Se nenhuma NFe selecionada
  if FileListBox1.SelCount <= 0 then
  begin
    ShowMessage('Nenhum arquivo de NFe selecionado' + #13 +
    'Selecione pelo menos um arquivo de NFe para integrar o novo lote');
    Exit;
  end;
 
  //Nº máximo de Notas por lote é 50
  if FileListBox1.SelCount > 50 then
  begin
    ShowMessage('O lote não pode possuir mais de 50 notas' + #13 +
    'Retire algumas notas e tente novamente');
    Exit;
  end;
 
  antes := now;
 
  //Inicializa o progressbar
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;
  ProgressBar1.max := FileListBox1.SelCount;
 
  //cria o objeto da nota
  nfe_STR := TStringList.Create;
  nfe_STR.Clear;
 
  myfilename := DirectoryListBox1.Directory + '\' + copy(ValueListEditor76.Values['idLote'], 4, 44) + '-env-lot.xml';
 
  AssignFile(F, myfilename);
  Rewrite(F);
 
  //cria cabeçalho do lote
  Write(F, '<?xml version="1.0" encoding="UTF-8"?>');
  if FormataCampo(ValueListEditor76, 'versao', 'N', 4) then
    Write(F, '<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.portalfiscal.inf.br/nfe enviNFe_v1.10.xsd" versao="' + ValueListEditor76.Values['versao'] + '">');
  if FormataCampo(ValueListEditor76, 'idLote', 'N', 15) then //Número seqüencial auto-incremental.   

    Responsabilidade exclusiva do contribuinte
  Write(F, '<idLote>' + ValueListEditor76.Values['idLote'] + '</idLote>');
 
  //Faz loop nas notas selecionadas assinando-as
  for i := 0 to FileListBox1.Items.Count - 1 do
  begin
    if FileListBox1.Selected[i] then //se arquivo selecionado
    begin
      //carrega arquivo para variável
      nfe_STR.LoadFromFile(DirectoryListBox1.Directory + '\' + FileListBox1.Items.Strings[i]);
  
      //assina nota
      nfe_STR.Text := fncAssinarXML(nfe_STR);
 
      //adiciona ao buffer do lote
      buf := copy(nfe_STR.text, pos('<NFe', nfe_STR.text), length(nfe_STR.text));
 
      //Escreve no arquivo
      Write(F, buf);
 
      ProgressBar1.StepIt;
    end;
  end;
  //fecha o rodapé do lote
  Write(F, '</enviNFe>');
 
  //libera arquivo
  CloseFile(F);
 
  //Verifica tamanho do lote criado. Arquivo de lote não pode ser maior que 500KB
  AssignFile(F_Temp, myfilename);
  Reset(F_Temp);
  Tamanho_Lote := FileSize(F_Temp)/1000;
  if Tamanho_Lote > 500 then
    ShowMessage('Arquivo de lote é maior que tamanho máximo permitido' + #13 +
    'Seu tamanho máximo é de 500KB.');
 
  //libera memória do objeto da nota
  nfe_STR.Free;
  depois := now;
  //mostra mensagem de nota salva e calcula tempo gasto para gerar lote e assiná-la
  Showmessage('Assinatura e Geração do Lote Concluída' + #13#10 +
  'Tempo Total (seg): ' + inttostr(SecondsBetween(antes, depois)) + #13#10 +
  'Tempo Médio (seg): ' + formatfloat('0.00', SecondsBetween(antes, depois)/FileListBox1.SelCount));
 
end;

 

    Observe que dos trechos de código mostrados para geração do lote, apenas algumas linhas são necessárias para assinar a nota e gerar o lote, o restante das linhas executam funções secundárias, como atualizar progressbar e mostrar mensagens na tela, ou seja, o processo de assinatura e geração de lote são muito simples e de fácil implementação em qualquer aplicação.
    Testes de performance mostraram que o processo de assinatura em massa de um grande volume de NFe utilizando certificados A1 é ligeiramente mais rápido do que utilizando certificados A3. Tipicamente o tempo médio de assinatura utilizando certificados A3 é da ordem de 3 segundos para cada NFe enquanto com certificados A1 os tempos obtidos foram da ordem de 2 segundos.
    Importante lembrar que este valores estão condicionados a aspectos de configuração da máquina, como memória disponível, processamento etc.
    Caso haja a necessidade de grande performance, com a assinatura de um volume realmente muito grande de notas em um curto espaço de tempo é possível ainda se adotar hardwares específicos, chamados de HSM - Host Security Module, que atualmente permitem assinar até 175 notas por segundo como é o caso do equipamento Net D-Fence da True Access Consulting apresentado a seguir.
 

Figura 07 – Solução True Access para assinatura digital de grande performance.

 


Conclusão
   
Com este artigo abordamos conceitos gerais sobre assinatura digital em massa e geração de lotes no que tange a NF-e, e vimos como é fácil assinar e gerar tais documentos. A NF-e já é uma realidade, e muito em breve todos serão obrigados a adotar este novo formato. Mesmo as empresas não obrigadas, estão interessadas em ter seus sistemas atualizados para trabalhar nesta nova modalidade de emissão de documentos fiscais.
    Demos continuidade à nossa série de artigos sobre NFe, e desta vez, demonstramos como realizar de forma simples e prática a assinatura digital em massa e criação de lotes a partir da sua aplicação, com o uso da assinaturaNFe32dll.dll, apresentamos resultados de performance de certificados A1 e A3 obtidos através de testes com a solução proposta bem como indicamos trouxemos ao conhecimento do leitor o uso dos equipamentos HSM para assinatura de grandes volumes de NFe em um curto espaço de tempo. De agora em diante, assinar uma Nota Fiscal    Eletrônica e gerar o lote é questão apenas de chamar uma função e indicar os arquivos a serem assinados e que irão compor o lote, simples assim!
 

 

Victory Fernandes é Professor do Departamento de Engenharia da UNIFACS, Engenheiro Mestrando em Redes de Computadores, e desenvolvedor sócio da TKS Software - Soluções de Automação e Softwares Dedicados. Pode ser contatado em victory@igara.com.br , ou através dos sites www.igara.com.br – www.igara.com.br/victory
 
Fellipe Capolupo é estudante de Engenharia Elétrica da UNIFACS – Universidade Salvador e desenvolvedor da TKS Software - Soluções de Automação e Softwares Dedicados. Pode ser contatado em capolupofellipe@yahoo.com.br



Comentários Comentários
   Ordem:  
Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos.


por: adrianogalvao (adrianogalvao2005@yahoo.com.br) : Mai 21, 2009 - 09:52
(Informações sobre o membro | Enviar uma mensagem) http://http://
Parabéns Victory, muito Bom Mesmo, valeu...


por: JULIO_MORAES (juliomoraes@tradeone.com.br) : Mai 21, 2009 - 11:38
(Informações sobre o membro | Enviar uma mensagem) http://
Olá Victory e Fellipe,
Primeiramente gostaria de registrar meus parabéns pelos artigos apresentados aqui no Active.
Aproveitando a oportunidade, gostaria de saber como posso testar minha aplicação já adaptada para a NF-e, tenho que comprar um certificado? ou existe certificados e ambiente de testes na SEFAZ? já que não sou inscrito na SEFAZ e desejo somente fazer testes para validar meu software.

atenciosamente,

Júlio Moraes
Tapes (RS)


por: unabomber (progman@terra.com.br) : Set 25, 2009 - 11:11
(Informações sobre o membro | Enviar uma mensagem)
O artigo é até bom, mas basicamente é propaganda do seu produto, aliás, a ActiveDelphi está se especializando em artigos que vendem coisas dos próprios colunistas...
  Edição 112

Revista ActiveDelphi

  50 Programas Fontes


  Produtos

Conheça Nossos Produtos

Copyright© 2001-2016 – Active Delphi – Todos os direitos reservados