Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 1667 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Olá Prezados, 

Estou com erro no cancelamento da NFs de Betha.

Ao cancelar a nota recebo um XML apenas com Fault String 172, pelo codigo indica um erro de assinatura.

Notei que nas versões anteriores do sistema esse erro não estava ocorrendo, então voltei o ACBr para a revision que o cancelamento estava funcionando e voltou a funcionar.

Voltei para a revision 17491 e consegui fazer o cancelamento normalmente.

Ao analisar os XML notei a seguinte diferença na contrução do XML para cancelamento:

CompareNFs.thumb.png.10e26846adf7e0ccc15ac5cb9a16e54f.png

 

No arquivo a esquerda esta funcionando, portanto, notei que a diferença está no <Reference URI="#canc3".

Alguém poderia me orientar como faço para inserir essa URI="#canc3" na revision atual?

OBS: Para esse municipio realizamos a contrução do XML manualmente e utilizamos o compontene ACBr apenas para realizar o envio e assinatura.

Postado

Boa tarde, Pessoal.

Encontrei onde está o problema, acontece que da revision 17491 para a revision atual teve alterações na função ExtraiURI, que passou a se chamar EncontrarURI e teve sua estrutura alterada.

Encontrei o erro na seguinte rotina:

[...]

  if (docElement <> '') then
    I := Pos('<'+docElement, AXML)
  else
    I := 0;

  //AQUI QUANDO É PASSODO O PARAMETRO I O VALOR ESTÁ 0, NO ENTANTO, O OFFSET PADRÃO SERIA 1
  I := PosEx(IdAttr+'=', AXML, I);
  if I = 0 then       // XML não tem URI
    Exit;
      
[...]
  

 

Pelo que pude perceber o parametro offset da função PosEx deveria inciar em 1 não 0, como na rotina acima onde é feito o Pos no docElement está retornando o valor 0 para a variavel I, está sendo passado o valor 0 para o parametro offset, o qual tem seu valor default 1.

Acredito que seria incorreto atribuirmos o valor 1 para a variavel I, devido a comparação posterior para verificar se foi encontrado a URI no XML, portanto dexei a seguinte sugestão de alteração:

[...]

  if (docElement <> '') then
    I := Pos('<'+docElement, AXML)
  else
    I := 0;

  if I = 0 then  
    I := PosEx(IdAttr+'=', AXML) // offset default é 1
  else 
    I := PosEx(IdAttr+'=', AXML, I)
      
[...]

 

Peço por gentileza se os moderadores/commiters poderiam analisar essa sugestão de alteração.

Grato!

 

  • Moderadores
Postado
Em 05/05/2020 at 09:59, João Paulo Müller disse:

Notei que nas versões anteriores do sistema esse erro não estava ocorrendo, então voltei o ACBr para a revision que o cancelamento estava funcionando e voltou a funcionar.

Você está com os arquivos .ini atualizados junto com a versão atual da sua aplicação?

No arquivo Betha.ini deve conter o elemento a localizar no cancelamento:

Citar

[Cancelar]
IncluiEncodingCab=0
IncluiEncodingDados=0
InfElemento=InfPedidoCancelamento

Que parece correto de acordo com a imagem do XML.

Está dessa forma no seu .ini?

Equipe ACBr BigWings
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

 

 

Postado (editado)

 

1 hora atrás, BigWings disse:

Você está com os arquivos .ini atualizados junto com a versão atual da sua aplicação?

No arquivo Betha.ini deve conter o elemento a localizar no cancelamento:

Que parece correto de acordo com a imagem do XML.

Está dessa forma no seu .ini?

 

Boa tarde, @BigWings.

 

Em 05/05/2020 at 10:59, João Paulo Müller disse:

OBS: Para esse municipio realizamos a contrução do XML manualmente e utilizamos o compontene ACBr apenas para realizar o envio e assinatura.

Utilizo o componente apenas para fazer a assinatura e envio do XML atráves da classe ACBrDFeSSL, não utilizo o componente ACBrNFSe por completo.

Faço a assinatura da seguinte forma:

A := ACBrDFE.Assinar(XML, 'Pedido></CancelarNfseEnvio', 'InfPedidoCancelamento');

 

Acredito que a função EncontrarURI da forma que está pode acabar gerando problemas para outros provedores em casos que não encontrar o DocElement,  consequentemente a variavel I receber o valor 0 (o qual está incorreto, pois o offset deveria ser 1).

 

Entendo que com a sugestão proposta a baixo resolveria por completo a situação, tanto do meu caso, quanto para outros cenários em que o DocElement não for encontrado, ou seja, não seria uma implementação especifica para min, mas sim uma correção de bug.

[...]

  if (docElement <> '') then
    I := Pos('<'+docElement, AXML)
  else
    I := 0;

  if I = 0 then  
    I := PosEx(IdAttr+'=', AXML) // offset default é 1
  else 
    I := PosEx(IdAttr+'=', AXML, I)
      
[...]

 

 

 

Editado por João Paulo Müller
  • Moderadores
Postado
2 horas atrás, João Paulo Müller disse:

A := ACBrDFE.Assinar(XML, 'Pedido></CancelarNfseEnvio', 'InfPedidoCancelamento');

Tente alterar para:

A := ACBrDFE.Assinar(XML, 'Pedido', 'InfPedidoCancelamento');

 

2 horas atrás, João Paulo Müller disse:

outros cenários em que o DocElement não for encontrado

Você tem razão quanto a chamar PosEx com o terceiro parâmetro 0, o resultado será sempre 0. Então talvez caiba uma melhoria nesse código. O @Daniel Simoes deve poder comentar melhor.

Mas entendo que o método espera que se passe um elemento e um atributo, se o elemento não for encontrado, porque continuar?

  • Obrigado 1
Equipe ACBr BigWings
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

 

 

Postado
11 minutos atrás, BigWings disse:

Tente alterar para:


A := ACBrDFE.Assinar(XML, 'Pedido', 'InfPedidoCancelamento');

 

Opa, fiz a alteração que você sugeriu e funcionou perfeitamente em ambiente de homologação. Vou fazer um teste em produção para confirmar.

Pensei que iria dar problema na rotina a baixo que identifica o final da tag docElement, por isso acabei não mexendo nessa rotina.

//Função AdicionarSignatureElement
  URI := EncontrarURI(ConteudoXML, docElement, IdAttr);

  TagEndDocElement := '</' + docElement + '>';
  I := PosLast(TagEndDocElement, ConteudoXML);
  if I = 0 then
    raise EACBrDFeException.Create('Não encontrei final do elemento: ' + TagEndDocElement);

[...]

 

@BigWings Obrigado pela ajuda e atenção.

 

  • Curtir 1
  • Fundadores
Postado

Realmente parece um erro de programação... Chamar a PosEx, com OffSet=0, faz ela não funcionar...  Abaixo temos o trecho de código, da PosEx, da FPC

Function PosEx(const SubStr, S: string; Offset: SizeUint): SizeInt;
var
  i,MaxLen, SubLen : SizeInt;
  SubFirst: Char;
  pc : pchar;
begin
  PosEx:=0;
  SubLen := Length(SubStr);
  if (SubLen > 0) and (Offset > 0) and (Offset <= Cardinal(Length(S))) then     // AQUI nem entraria...

 

Mas acho que a correção, é mais simples..

  if (docElement <> '') then
    I := Pos('<'+docElement, AXML)
  else
    I := 1;   // AQUI

 

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Postado
2 horas atrás, Daniel Simoes disse:

Mas acho que a correção, é mais simples..


  if (docElement <> '') then
    I := Pos('<'+docElement, AXML)
  else
    I := 1;   // AQUI

 

Olá Daniel, agradeço o retorno.

Acredito que atribuindo o valor 1 nesse else deixará a próxima condição em sequencia sem lógica:

[...]

  if I = 0 then  
    I := PosEx(IdAttr+'=', AXML) // offset default é 1
  else 
    I := PosEx(IdAttr+'=', AXML, I)

[...]

Vai funcionar da mesma forma, pois ira cair no else e chamar o terceiro parametro (I) com o valor 1, mas acredito que esse IF I = 0 não terá mais uso, pois em nenhum momento será atribuido o valor 0 a váriavel I, confere?

  • Fundadores
Postado

Acho que está correto pois na linha seguinte o I é usando como Parâmetro de Entrada, mas também recebe o resultado
 

 if (docElement <> '') then
    I := Pos('<'+docElement, AXML)
  else
    I := 1;

  I := PosEx(IdAttr+'=', AXML, I);  // AQUI TEREMOS UM NOVO "I"
  if I = 0 then       // XML não tem URI
    Exit;    

 

  • Obrigado 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Postado
6 minutos atrás, Daniel Simoes disse:

Acho que está correto pois na linha seguinte o I é usando como Parâmetro de Entrada, mas também recebe o resultado
 


 if (docElement <> '') then
    I := Pos('<'+docElement, AXML)
  else
    I := 1;

  I := PosEx(IdAttr+'=', AXML, I);  // AQUI TEREMOS UM NOVO "I"
  if I = 0 then       // XML não tem URI
    Exit;    

 

Claro Daniel, está certo.

Perdão, fiz a anlise em cima da minha própria sugestão de alteração, por isso estária incorreto...

O código do repositório é esse mesmo que você comentou e vai funcionar perfeitamente. 

 

Obrigado!

  • Curtir 1
  • Administradores
Postado

Obrigado por reportar.

Fechando. Para novas dúvidas, criar um novo tópico.

  • Curtir 1
Consultora SAC ACBr

Juliana Tamizou

Gerente de Projetos ACBr / Diretora de Marketing AFRAC
Ajude o Projeto ACBr crescer - Seja Pro

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  Discord

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

  • Este tópico foi criado há 1667 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • 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.