Walter,
Também uso o FireBird.
1 - Na Tabela de NFe, defini um campo para armazenar o XML da NFe assim:
XML_NFE BLOB SUB_TYPE 1 SEGMENT SIZE 80
Na verdade é um campo Memo.
2 – No Sistema eu tenho uma rotina que gera, assina e valida o XML, usando o ACBrNFe. Mais ou menos assim:
2.1 - Eu gero assim:
// Inicializa
ACBrNFe.NotasFiscais.Clear;
// Monta e Envia
try
with ACBrNFe.NotasFiscais.Add.NFe do
begin // Lote
begin // NFe (Dados da Nota Fiscal eletrônica)
begin // Identificação
infNFe.ID := IntToStr(Numero_NFe);
Ide.cUF := GetCodigoIBGEEstado(Q_DivisoesESTADO.Value);
Ide.cNF := Numero_NFe;
…
No final da Geração, eu salvo o XML (na pasta definida do ACBrNFe) e pego a Chave. Assim:
ACBrNFe.NotasFiscais.Items[0].SaveToFile; //(CaminhoNomeXML);
ChaveNFe := ACBrNFe.NotasFiscais.Items[0].NFe.infNFe.ID;
if UpperCase(Copy(ChaveNFe,1,3)) = 'NFE' then
ChaveNFe := Copy(ChaveNFe,4,Length(ChaveNFe));
2.2 – Depois eu Assino assim:
try
ACBrNFe.NotasFiscais.Assinar;
except
on E:Exception do
begin
MensagemErro := gAlocaSalvaPChar('Na Assinatura da NFe!'+#13#10+
'Verifique se o Certificado Carregado na Divisão'+#13#10+
'e Informado a Senha!'+#13#10+
'Detalhes do Erro: "'+E.Message+'"',
MensagemErro);
Exit;
end;
end;
2.3 – Valido assim:
try
ACBrNFe.NotasFiscais.Valida;
except
on E:Exception do
begin
MensagemErro := gAlocaSalvaPChar(E.Message,MensagemErro);
Exit;
end;
end;
3 – Salvo o XML no BD assim, considerando que Q_NotaFiscalXML_NFE é o campo memo que criei como mencionado acima:
// Salva XML no BD (Salva, mesmo ainda não tendo enviado, para o caso se Contigencia)
try
Q_NotaFiscal.Edit;
Q_NotaFiscalXML_NFE.Value := ACBrNFe.NotasFiscais.Items[0].XML; // XML da Nota Assinada sem Envelope
if Q_NotaFiscalCHAVE_NFE.IsNull then
Q_NotaFiscalCHAVE_NFE.Value := ChaveNFe;
if (Q_NotaFiscalFORMA_EMISSAO_NFE.IsNull) then
Q_NotaFiscalFORMA_EMISSAO_NFE.Value := Q_DivisoesFORMA_EMISSAO_NFE.Value;
Q_NotaFiscal.Post;
except
on E:Exception do
begin
Q_NotaFiscal.Cancel;
MensagemErro := gAlocaSalvaPChar('No Armazenamento do XML da NFe no Banco de Dados!'+#13#10+
'O Erro foi o Seguinte:'+#13#10+
'"'+E.Message+'"',
MensagemErro);
Exit;
end;
end;
4 – Em seguida eu Envio para o WS, assim:
// Envia para WS
try
ACBrNFe.WebServices.Enviar.Lote := IntToStr(NumeroLote); //NFe2
if (Q_DivisoesFORMA_EMISSAO_NFE.Value = cFormaEmissaoNFeContigenciaDPEC) then
ResultadoWS := ACBrNFe.WebServices.EnviarDPEC.Executar
else
ResultadoWS := ACBrNFe.WebServices.Enviar.Executar; //NFe2
if ResultadoWS = False then
begin
MensagemErro := gAlocaSalvaPChar('O WebService Retornou o Seguinte Erro ao Enviar a NFe:'+#13#10+
ACBrNFe.WebServices.Enviar.Msg,
MensagemErro);
Exit;
end;
// if (Q_DivisoesFORMA_EMISSAO_NFE.Value = cFormaEmissaoNFeContigenciaDPEC) then
// begin
// ACBrNFe.DANFE.ProtocoloNFe := ACBrNFe.WebServices.EnviarDPEC.nRegDPEC+' '+
// DateTimeToStr(ACBrNFe.WebServices.EnviarDPEC.DhRegDPEC);
// end;
except
on E:Exception do
begin
if UpperCase(E.Message) <> UpperCase('Lote em Processamento') then
begin
MensagemErro := gAlocaSalvaPChar('Ocorreu a Seguinte Exceção ao Enviar a NFe:'+#13#10+
TraduzXML(E.Message),
MensagemErro);
Exit;
end;
end;
end;
4.1 – ATENÇÃO AQUI: Não envio o XML como esta no demo do componente. Esta forma que envio é usados por outros desenvolvedores. Desta forma não entra no loop aguardando a resposta. Evitando assim aquele congelamento da tela, problema de lentidão da SEFAZ, etc. Assim eu tenho que pegar a resposta (se a NFe foi autorizada) em outra etapa.
4.2
5 – Salvo o XML de autorização assim:
// Salva XML de Autorização no BD (NFes em Contigencia, terão que passar por isto)
try
CaminhoNomeXML := CaminhoTemporario+'\XMLs\'+IntToStr(NumeroLote)+'-env-lot'+'.XML';
Q_NotaFiscal.Edit;
if (Q_DivisoesFORMA_EMISSAO_NFE.Value = cFormaEmissaoNFeNormalOnLine) then
Q_NotaFiscalXML_NFE.LoadFromFile(CaminhoNomeXML); // XML da Nota Assinada e Envelopada
Q_NotaFiscalXML_AUTORIZACAO_NFE.Value := ACBrNFe.WebServices.Retorno.RetWS;
if (Q_DivisoesFORMA_EMISSAO_NFE.Value = cFormaEmissaoNFeContigenciaDPEC) then
begin
Q_NotaFiscalNUMERO_PROTOCOLO_NFE_DPEC.Value := ACBrNFe.WebServices.EnviarDPEC.nRegDPEC;
Q_NotaFiscalDATA_HORA_PROTOCOLO_NFE_DPEC.Value := ACBrNFe.WebServices.EnviarDPEC.DhRegDPEC;
end;
Q_NotaFiscalSITUACAO_NFE.Value := 'Enviada';
Q_NotaFiscal.Post;
except
on E:Exception do
begin
Q_NotaFiscal.Cancel;
MensagemErro := gAlocaSalvaPChar('No Armazenamento do XML de Retorno no Banco de Dados!'+#13#10+
'O Erro foi o Seguinte:'+#13#10+
'"'+E.Message+'"',
MensagemErro);
Exit;
end;
end;
6 – Num botão chamado DNAFE, eu pego a resposta da NFe e se autorizada, visualizo ou imprimo o DANFE para o usuário.
6.1 – Pegando a Resposta pela Chave da NFe:
// Consulta NFe
try
ACBrNFe.WebServices.Consulta.NFeChave := Q_NotaFiscalCHAVE_NFE.Value; //Chave
ACBrNFe.WebServices.Consulta.Executar; //Chave
except
on E:Exception do
begin
MensagemErro := gAlocaSalvaPChar('Ocorreu o Seguinte Erro ao Consultar a NFe:'+#13#10+
TraduzXML(E.Message),
MensagemErro);
Exit;
end;
end;
6.2 – Carregando o Status da NFe:
var
NFeRetorno: TretConsSitNFe;
begin
….
// Le XML
NFeRetorno := TRetConsSitNFe.Create;
NFeRetorno.Leitor.Arquivo := TraduzXML(ACBrNFe.WebServices.Consulta.RetWS);
NfeRetorno.LerXml;
….
6.3 – Salvando no BD
// Salva no BD
if (NFeRetorno.CStat = 100) or
(NFeRetorno.CStat = 101) then
begin
begin
try
CaminhoNomeXML := CaminhoTemporario+'\XMLs\'+Q_NotaFiscalCHAVE_NFE.Value+'-nfe'+'.XML';
Q_NotaFiscal.Edit;
Q_NotaFiscalXML_NFE.LoadFromFile(CaminhoNomeXML); // XML da Nota Assinada, Envelopada e com Protocolo
if (Q_NotaFiscalXML_AUTORIZACAO_NFE.IsNull) then
Q_NotaFiscalXML_AUTORIZACAO_NFE.Value := ACBrNFe.WebServices.Consulta.RetWS;
if NFeRetorno.CStat = 100 then
Q_NotaFiscalSITUACAO_NFE.Value := 'Enviada'
else
if NFeRetorno.CStat = 101 then
Q_NotaFiscalSITUACAO_NFE.Value := 'Cancelada';
{$IFDEF NFe1}
Q_NotaFiscalNUMERO_PROTOCOLO_NFE_NORMAL.Value := NFeRetorno.NProt; // NFe2
{$ENDIF}
{$IFDEF NFe2}
Q_NotaFiscalNUMERO_PROTOCOLO_NFE_NORMAL.Value := NFeRetorno.ProtNFe.NProt;
{$ENDIF}
Q_NotaFiscal.Post;
except
Q_NotaFiscal.Cancel;
end;
end;
end;
7 – Para imprimir/visualizar a DANFE:
7.1 – Salvo XML no HD assim:
Q_NotaFiscalXML_NFE.SaveToFile(CaminhoNomeXML);
7.2 – Carrego XML para o Componente, assim:
// Carrega XML
ACBrNFe.NotasFiscais.Clear;
ACBrNFe.NotasFiscais.LoadFromFile(CaminhoNomeXML);
7.3 – Imprimo o DANFE assim:
ACBrNFe.NotasFiscais.ImprimirPDF;
Não sei qual componente você usa para acessar o FireBird. Eu uso o IBObjects. O exemplo aqui mostrado pode ajudar a salvar e recuperar o XML usando qualquer suite de acesso ao FireBird e até mesmo para outros SGBD.
Ubaltino Faleiro