Olá,
descobri qual o problema da validação de assinatura. O problema é que no parâmetro da função ValidaAssinatura (NotaUtil.ValidaAssinatura) estava sendo passado a property XML da classe NotaFiscal, e o read dessa property (a function GetNFeXML) gera um novo XML a partir das properties da classe NFe. E ao gerar o XML pela function GetNFeXML algumas propriedades são alteradas:
1. Os atributos versao e ID da tag InfNFe são invertidos de ordem;
2. As tags que possuem casas decimais variáveis (por exemplo, 0-10) estão sendo fixadas com o tamanho máximo;
3. Alguns caracteres de quebra de linha estão sendo removidos.
Para corrigir o problema, passei como parâmetro da função NotaUtil.ValidaAssinatura o ArquiloXML lido do arquivo e não alterado. As alterações foram:
1. Criei a property XMLInalterado na classe NotaFiscal da Unit ACBrNFeNotasFiscais:
NotaFiscal = class(TCollectionItem)
private
FNFe: TNFe;
FXML: AnsiString;
FXMLInalterado: AnsiString;
.
.
property XML: AnsiString read GetNFeXML write FXML;
property XMLInalterado: AnsiString read FXMLInalterado write FXMLInalterado;
2. A function LoadFromFile da Unit ACBrNFeNotasFiscais ficou assim:
function TNotasFiscais.LoadFromFile(CaminhoArquivo: string): boolean;
var
LocNFeR : TNFeR;
ArquivoXML: TStringList;
XML : AnsiString;
XMLInalterado : AnsiString;
begin
try
ArquivoXML := TStringList.Create;
ArquivoXML.LoadFromFile(CaminhoArquivo);
XMLInalterado := ArquivoXML.Text;
Result := True;
while pos('',ArquivoXML.Text) > 0 do
begin
if pos('',ArquivoXML.Text) > 0 then
begin
XML := copy(ArquivoXML.Text,1,pos('',ArquivoXML.Text)+5);
ArquivoXML.Text := Trim(copy(ArquivoXML.Text,pos('',ArquivoXML.Text)+10,length(ArquivoXML.Text)));
end
else
begin
XML := copy(ArquivoXML.Text,1,pos('',ArquivoXML.Text)+5);
ArquivoXML.Text := Trim(copy(ArquivoXML.Text,pos('',ArquivoXML.Text)+6,length(ArquivoXML.Text)));
end;
LocNFeR := TNFeR.Create(Self.Add.NFe);
try
LocNFeR.Leitor.Arquivo := XML;
LocNFeR.LerXml;
Items[self.Count-1].XML := LocNFeR.Leitor.Arquivo;
Items[self.Count-1].XMLInalterado := XMLInalterado;
Items[self.Count-1].NomeArq := CaminhoArquivo;
GerarNFe;
finally
LocNFeR.Free;
end;
end;
ArquivoXML.Free;
except
raise;
Result := False;
end;
end;
3. A function ValidaAssinatura da Unit ACBrNFeNotasFiscais ficou assim:
function TNotasFiscais.ValidaAssinatura(out Msg : String) : Boolean;
var
i: Integer;
FMsg : AnsiString;
begin
for i:= 0 to Self.Count-1 do
begin
if not(NotaUtil.ValidaAssinatura(('')+ ''), FMsg)) then
begin
Result := False;
Msg := 'Falha na validação da assinatura da nota '+
IntToStr(Self.Items.NFe.Ide.nNF)+sLineBreak+FMsg
end
else
Result := True;
end;
end;
Se eu cometi algum equívoco por favor me avisem.