Segue um exemplo de utilização da carta de correção eletrônica utilizando o ACBrNFe, a carta de correção é disciplinada pela Nota Técnica 2011.003 e alguns pontos devem ser observados, segue texto:
A Carta de Correção é disciplinada pelo § 1º-A do art. 7º do Convênio S/N, de 15 de dezembro de 1970 e pode ser utilizada para regularização de erro ocorrido na emissão de documento fiscal, desde que o erro não esteja relacionado com:
I – as variáveis que determinam o valor do imposto tais como: base de cálculo, alíquota, diferença de preço, quantidade, valor da operação ou da prestação;
II – a correção de dados cadastrais que implique mudança do remetente ou do destinatário; III – a data de emissão ou de saída.
É importante saber que a última carta de correção enviada substitui as anteriores, portanto a última deve sempre conter todas as correções, mesmo as já enviadas.
O número sequencial da Carta de Correção (nSeqEvento) deve ser controlado pelo aplicativo e deve sempre incrementar a cada envio.
// Adicione a unit pcnConversao ao uses. // numero do lote de envio NumeroLote := StrToInt(FormatDateTime('yymmddhhmm', NOW)); // preenchimento dos dados da carta de correção ACBrNFe.EventoNFe.Evento.Clear; ACBrNFe.EventoNFe.idLote := NumeroLote; with ACBrNFe.EventoNFe.Evento.Add do begin infEvento.chNFe := ChaveNFe; infEvento.CNPJ := CnpjEmitente; infEvento.dhEvento := Now; infEvento.tpEvento := teCCe; infEvento.nSeqEvento := <Numero Sequencial>; infEvento.detEvento.xCorrecao := <Texto da Carta de Correção>; end; // envio da carta de correção if ACBrNFe.EnviarEventoNFe(NumeroLote) then begin with ACBrNFe.WebServices.EnvEvento do begin if not(EventoRetorno.retEvento.Items[0].RetInfEvento.cStat in [135, 136]) then begin raise EDatabaseError.CreateFmt( 'Ocorreu o seguinte erro ao enviar a carta de correção:' + sLineBreak + 'Código:%d' + sLineBreak + 'Motivo: %s', [ EventoRetorno.retEvento.Items[0].RetInfEvento.cStat, EventoRetorno.retEvento.Items[0].RetInfEvento.xMotivo ]); end; // retornos DataHoraEvento := EventoRetorno.retEvento.Items[0].RetInfEvento.dhRegEvento; NumeroProtocolo := EventoRetorno.retEvento.Items[0].RetInfEvento.nProt; XMLCCe := EventoRetorno.retEvento.Items[0].RetInfEvento.XML; CodigoStatus := EventoRetorno.retEvento.Items[0].RetInfEvento.cStat; MotivoStatus := EventoRetorno.retEvento.Items[0].RetInfEvento.xMotivo; end; end else begin with ACBrNFe.WebServices.EnvEvento do begin raise Exception.Create( 'Ocorreram erros ao enviar a Carta de Correção:' + sLineBreak + 'Lote: ' + IntToStr(EventoRetorno.idLote) + sLineBreak + 'Ambiente: ' + TpAmbToStr(EventoRetorno.tpAmb) + sLineBreak + 'Orgao: ' + IntToStr(EventoRetorno.cOrgao) + sLineBreak + sLineBreak + 'Status: ' + IntToStr(EventoRetorno.cStat) + sLineBreak + 'Motivo: ' + EventoRetorno.xMotivo ); end; end;
Olá Régys, tudo tranquilo?
Me tira uma dúvida, existe alguma maneira de eu gerar o xml de evento num programa A, exportar o xml p/ um programa B, assinar o xml no programa B, devolver para o programa A o xml assinado, carregar o evento assinado e transmitir no programa A?
Pois ja faço esse processo com NF-e comum, tipo eu gero o xml em um programa sem assinar, e exporto p/ outro programa.. nesse outro programa eu assino e transmito, tipo isso:
ACBrNFe1.NotasFiscais.Clear;
ACBrNFe1.NotasFiscais.LoadFromString(xml);
ACBrNFe1.NotasFiscais.Assinar();
ACBrNFe1.Enviar(1, False);
Gostaria de fazer o mesmo processo com os Eventos (CC-e, Cancelamento e Inut)
Alguma luz no fim do tunel? sendo que ja vasculhei os fóruns e o código, e me parece que a parte de evento do componente ACBrNFe não permite enviar xml carregado
Agradeço antecipadamente
Se não estou enganado para os eventos não vai dar, porque eles não tem a opção de salvar o XML cru e assinar depois como existe no envio da NF-e.
Só não entendi porque o troca troca, montar o XML em um, assinar em outro, enviar no anterior, não consegui entender porque.
Foi a mesmo o que eu achei depois de alguns dias pesquisando e tentando fazer funcionar esse esquema em eventos, sem sucesso! na verdade eu preciso deste modelo porque eu tenho um sistema web, em que as assinaturas em certificado A3 tem que ser feita na maquina do cliente, ai no caso eu tenho um servidor de transmissão que aciona o client na maquina do client. a idéia é que o servidor de transmissão acione o client e o client devolta o xml assinado para o servidor de transmissão transmitir. eu consegui isso com o envio de NF-e, que eu consigo exportar e importar o xml… agora com eventos não achei uma maneira de fazer! você teria alguma sugestão!
Obrigado pela resposta!
Tente isto:
if ACBrNFe1.EventoNFe.GerarXML then
begin
// salvar o arquivo use
MinhaVariavelString := ACBrNFe1.EventoNFe.Gerador.ArquivoFormatoXML
ou
ACBrNFe1.EventoNFe.Gerador.SalvarArquivo(‘meu caminho do arquivo’);
end;
regis o que devo fazerr qdo me reotorna o erro falha no xml qdo envio a carta de correção
pedrotiago@hotmail.com.br
Poderia detalhar melhor a mensagem de erro? Talvez postar a mensagem de erro completa ou somente é retornado isso na mensagem?
Olá Régys Tudo Bem. Excelente post!!
Mas uma dúvida gostaria de saber como faço pra pegar o nome do arquivo xml gerado da carta de correção? Já tentei de várias formas e não consigo obter o nome do arquivo gerado.
Ex:1101104116121737935700012555001000014930100014930802-procEventoNFe
Preciso do nome do arquivo pra poder fazer o próprio sistema encontre o arquivo do evento gerado pra poder fazer a impressão.
Desde já Muito Obrigado pela Atenção!!
Feliz Ano Novo!!!
Se você chamar a impressão após enviar a carta de correção o componente já imprimirá corretamente, você também pode ler a propriedade XML e salvar onde quiser para imprimir depois.
O mais comum é usar a propriedade para salvar o XML no Banco de dados e usar quando quiser.
A propriedade é: ACBrNFe1.WebServices.EnvEvento.EventoRetorno.retEvento.Items[0].RetInfEvento.XML
Olá Régys, após atualizar o componente para a versão do Trunk2 do ACBr a CCe que antes funcionava redondo agora ocorre o erro: 493 – Rejeicao: Evento nao atende o Schema XML especifico.
E a rotina esta assim:
ACBrNFe1.NotasFiscais.Clear;
ACBrNFe1.EventoNFe.Evento.Clear;
ACBrNFe1.EventoNFe.idLote := wlote;
with ACBrNFe1.EventoNFe.Evento.Add do
begin
infEvento.cOrgao := 23;
infEvento.tpAmb := StrToTpAmb(Ok, IntToStr(rgTipoAmb.ItemIndex + 1));
infEvento.chNFe := wnfe;
infEvento.CNPJ := wcnpj;
infEvento.dhEvento := Now;
infEvento.tpEvento := teCCe;
infEvento.versaoEvento := ‘1.00’;
infEvento.nSeqEvento := wSeqEvento;
infEvento.detEvento.xCorrecao := memo_correcao.Text;
infEvento.detEvento.nProt := wprotocolonfe; //Protocolo de Autorização da Nfe
infEvento.detEvento.xCondUso := memo_cond_uso.Text; //Texto fixo conforme NT 2011.003
end;
if ACBrNFe1.EnviarEvento(wlote) then
begin
with ACBrNFe1.WebServices.EnvEvento do
begin
if not (EventoRetorno.retEvento.Items[0].RetInfEvento.cStat in [135, 136]) then
begin
raise EDatabaseError.CreateFmt(
‘Ocorreu o seguinte erro:’ + sLineBreak +
‘Código: %d’ + ‘ – %s’, [
EventoRetorno.retEvento.Items[0].RetInfEvento.cStat,
EventoRetorno.retEvento.Items[0].RetInfEvento.xMotivo
]);
end;
end;
end;
O ACBrNFe1 esta configurado para versão da NF-e; ve310.
Gostaria de uma ajuda ai pra resolver esse probleminha.
Obrigado.
Seria melhor abrir um tópico no fórum do projeto ACBr, por lá é mais fácil de ajudar, faça isso por favor.
Boa tarde Regys, eu atualizei meu acbr e identifiquei uma mudança em relação a carta de correção eu verificava como vocÊ o cStat = 135 ou 136 para saber se não houve erro, após a mudança não encontro mais esse campo, no exemplo do acbr não tem o devido tratamento, pode me dizer como verifico hoje se o envio foi bem sucedido?
exemplo acbr novo
ACBrNFe1.EventoNFe.Evento.Clear;
// ACBrNFe1.EnvEvento.EnvEventoNFe..idLote := StrToInt(idLote) ;
with ACBrNFe1.EventoNFe.Evento.Add do
begin
infEvento.chNFe := Chave;
infEvento.CNPJ := CNPJ;
infEvento.dhEvento := now;
infEvento.tpEvento := teCCe;
infEvento.nSeqEvento := StrToInt(nSeqEvento);
infEvento.detEvento.xCorrecao := Correcao;
end;
ACBrNFe1.EnviarEventoNFe(StrToInt(idLote));
MemoResp.Lines.Text := UTF8Encode(ACBrNFe1.WebServices.EnvEvento. etWS);
//memoRespWS.Lines.Text := UTF8Encode(ACBrNFe1.WebServices.EnvEvento.EventoRetorno);
// ACBrNFe1.WebServices.EnvEvento.EventoRetorno.retEvento.Items[0].XXXX
LoadXML(MemoResp, WBResposta);
Rodolfo, este artigo é de 2012, depois destes 3 anos muita coisa mudou na NF-e, para entender melhor como é feito hoje lhe sugiro estudar o aplicativo de demonstração de uso do ACBrNFe, ele está bem atualizado, inclusive constando as alterações necessárias para a NF-e 3.10.
Régys, não consigo enviar a CC-e, dá erro do ID, esta maior que 52.
pode me ajudar?
Você tentou fazer a carta utilizando o Demo do ACBrNFe, talvez algo no seu código não esteja implementado corretamente, qualquer dúvida você também pode utilizar o fórum do projeto ACBr em http://www.projetoacbr.com.br.
gostei muito do post regys, utilizei, funcionou e já está em produção nos meus clientes, obrigado pela contribuição.
Que bom que o site conseguiu lhe ajudar, obrigado pelo feedback.
Consegui gerar a carta de correção com esse exemplo, coloquei o caminho no PathCCe porém não foi salvo nenhum XML nesse diretório e em nenhum outro local. Tenho que fazer algo a mais para isso acontecer?
Preciso do XML para poder imprimir os dados.
EventoRetorno.retEvento.Items[0].RetInfEvento.XML;
Utilize essa propriedade para ler o XML de retorno e gravar no seu Banco de Dados, mas os arquivos são sempre salvos a não ser que você não tenha marcado para salvar (ACBrNFe.Arquivos.Salvar)
O sequencial da Carta de Correção deve ser um sequencial para cada nota fiscal, ou um sequencial para todas cartas .
O sequencial da CC-e deve ser controlado por nota fiscal, uma mesma nota fiscal pode ter até 20 correções, lembrando que a última sempre substitui as anteriores, portanto, deve-se repetir as ultimas correções sempre.
obrigado pela resposta..valeu.