Página 2 de 3

Fim do Emissor Gratuito

Enviado: 18 Mai 2016 11:53
por JoséQuintas
Sim.
É usado o CN do certificado, e não o serial.
Geralmente é o nome da empresa.

Fim do Emissor Gratuito

Enviado: 18 Mai 2016 18:15
por depaula.jau
Boa noite!

José, o oSefaz:NfeStatus() funcionou perfeitamente após sua dica sobre o Nome do Certificado, então comecei a estudar a classe AssinaXml() para tentar assinar o meu XML.

Bom! Ele insere a TAG <Signature> inicio e fim, mas não completa por alguma razão. Vi que na rotina você ja precisou salvar o arquivo até aquele ponto pelo MemoWrit talvez pelo mesmo motivo que o meu.

O Retorno da rotina é a seguinte: "Problemas para Assinar XML" que é a mensagem padrão de inicio da variável o que significa que nenhum dos outros possíveis erros foram detectados.

Você teria alguma dica para me dar qual seria o possível problema?, Na chamada da AssinaXml Estou passando os parâmetros cXml (variável que contem o xml em construção) e cCertificado (que seguindo sua explicação é o Nome do certificado, o mesmo que usei no oSefaz:NfeStatus().

Agradeço muito até o momento.

Fim do Emissor Gratuito

Enviado: 18 Mai 2016 19:39
por JoséQuintas
Estou passando os parâmetros cXml (variável que contem o xml em construção)
Lá está certo sem o fechamento da tag, é que o fechamento vai no final.
Apenas como conteúdo aproximado:
<inf nfe...>
<nfe>
</nfe>
<signature>
<signature>
</infnfe>
A rotina separa a parte até </nfe>, acrescenta o bloco de assinatura, e depois acrescenta a finalização.
Até dá pra ver os tipos de documento/blocos nesta parte da rotina de assinatura:

Código: Selecionar todos

   aDelimitadores := { ;
      { "<enviMDFe",              "</MDFe></enviMDFe>" }, ;
      { "<eventoMDFe",            "</eventoMDFe>" }, ;
      { "<eventoCTe",             "</eventoCTe>" }, ;
      { "<infMDFe",               "</MDFe>" }, ;
      { "<infCte",                "</CTe>" }, ;
      { "<infNFe",                "</NFe>" }, ;
      { "<infDPEC",               "</envDPEC>" }, ;
      { "<infInut",               "<inutNFe>" }, ;
      { "<infCanc",               "</cancNFe>" }, ;
      { "<infInut",               "</inutNFe>" }, ;
      { "<infEvento",             "</evento>" }, ;
      { "<infPedidoCancelamento", "</Pedido>" }, ;               // NFSE ABRASF Cancelamento
      { "<LoteRps",               "</EnviarLoteRpsEnvio>" }, ;   // Lote NFSE
      { "<infRps",                "</Rps>" } }                   // NFSE ABRASF
A coisa comum de um XML é que cada parte tem início e fim, os chamados "nodes"

Código: Selecionar todos

<inicio></inicio>
Faz parte da assinatura validar se todo bloco tem abertura e encerramento.
Como disse que está em construção, não sei se esta parte está ok no XML.

Fim do Emissor Gratuito

Enviado: 18 Mai 2016 19:49
por JoséQuintas
Importante:
Como a classe altera todo funcionamento da hbnfe original, antes de fazer a possível limpeza nos fontes da hbnfe, tenho deixado em separado.
Aqui é onde venho salvando: https://github.com/JoseQuintas/sefazclass

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 07:44
por depaula.jau
José, Bom dia!

Revisei o Xml e os Nodes estão corretos, até o validei nesses sites que oferecem Validação de Estrutura

Tipo de arquivo: NF-e (Nota Fiscal eletrônica)

Resultado da Validação do arquivo

Nome do arquivo: NFe35160543127570000150550010000165021000788024-nfe.xml

Dados da validação:

Dados da NF-e
Chave da NF-e: 35160543127570000150550010000165021000788024
Versão do layout da NF-e: 3.10
Número da NF-e: 16502
Ambiente: Homologação
Tipo de emissão: 1 – Normal – emissão normal
Finalidade: NF-e normal
Valor da NF-e: 6.208,30
Data de emissão: 18/05/2016 16:58:00

Arquivo validado com sucesso!


Vou anexar o xml teste que gerei e caso tenha tempo de dar uma olhada pode ser que possa me dar uma luz.
Nesse tempo vou continuar analisando a estrutura.

Muito obrigado até o momento,

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 09:40
por depaula.jau
IMPORTANTE: Notei que em seus últimos comentários, onde detalhava a estrutura do XML, você colocou o <infoNfe> antes do <Nfe> a na minha formação o <Nfe> vem a frente do <infoNfe>, no caso eles estão invertidos segundo seu exemplo. Não sei se tem algo haver mas é um detalhe diferente.

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 11:05
por JoséQuintas
Faz tempo que não olho um XML, por isso comentei lá que era aproximado.
Aqueles blocos da rotina de assinatura tiram dúvida.

Código: Selecionar todos

      { "<infNFe",                "</NFe>" }, ;
Quando vi a rotina do ACBR pela primeira vez também me confundi com a retirada de parte do XML.
A rotina intercala o bloco de assinatura dentro do XML original, então separa o início e o fim, pra colocar a assinatura no meio de determinada posição.

Reparei que os dois XMLs são diferentes, dá pra ver pela data/hora de emissão da nota.

O correto na identificação da nota é com id="NFe351605..."
A assinatura utiliza esse id, e provavelmente não achou por faltar "NFe" no segundo XML.

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 11:23
por JoséQuintas
Só complemento/curiosidade:

Como é feita a assinatura de uma NFE:

É calculado um hash de todo documento, algo como um dígito de controle.
Isso é feito usando o bloco <NFe> até </NFe>
A assinatura é sobre uma combinação desse "dígito de controle" e a ID do documento.

É que seria extremamente lento assinar o documento inteiro, então fizeram desse jeito.

Problemas que podem acontecer na assinatura:
- Faltar certificado
- Certificado vencido
- Não encontrar a ID, ou blocos incompletos
- Caracteres inválidos: aquele velho problema de letra acentuada ser caractere diferente conforme codepage

Fora isso, existe uma "limpeza" do XML.
Tem rotina de assinatura que faz isso na hora de assinar, e por isso às vezes acusa assinatura diferente.

Por exemplo:

Código: Selecionar todos

<umacoisa></umacoisa>
O correto, definido no manual, quando está vazio é fazer assim:

Código: Selecionar todos

<uma coisa />
outro exemplo:

Código: Selecionar todos

<nome>jose            </nome>
Dependendo do que estiver definido, esse espaço em branco é inválido ou não considerado, teria que limpar

Código: Selecionar todos

<nome>jose</nome>
Tem rotina de assinatura que faz isso, tem rotina de assinatura que não.
É onde acusa erro de assinatura, porque a assinatura não corresponde a exatamente o que está no XML.
O mesmo acontece com caracteres acentuados ou especiais, porque são tratados diferentes em cada codepage.

Dos dois modos o XML está correto, mas do segundo modo o XML fica menor, economiza espaço, tempo de transmissão, etc.
Vai depender das rotinas de assinatura considerarem da mesma forma.
Pra evitar problemas, o melhor é sempre já gerar do jeito que aceita em qualquer assinatura, que é o modo "econômico".

Isso está no manual, é aquela parte que diz que pra assinatura são usados transform.... ou algo assim.

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 11:31
por JoséQuintas
Complementando sobre a curiosidade, o bloco de assinatura:

Código: Selecionar todos

   cSignatureNode +=       [<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>]
   cSignatureNode +=       [<Transforms>]
   cSignatureNode +=          [<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />]
   cSignatureNode +=          [<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />]
   cSignatureNode +=       [</Transforms>]
   cSignatureNode +=       [<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />]
   cSignatureNode +=       [<DigestValue>]
   cSignatureNode +=       [</DigestValue>]
DigestValue é o "dígito de controle" que mencionei.
DigestMethod Algorithm é a forma de calcular o "dígito de controle", usando SHA1
Transform Algorithm e CanonicalizationMethod Algorithm são as formas de "padronizar/limpar" o XML

Pra gente, de um modo geral, basta saber que é pra evitar caracteres especiais, e não acrescentar espaços em branco inúteis.

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 12:14
por depaula.jau
O correto na identificação da nota é com id="NFe351605..."
Que vc mencionou já estava com "NFe" , foi eu quem propositalmente eliminei para testar outras formas. Ja retornei como estava

Vou revisar as rotinas de criação seguindo suas orientações sobre preenchimento quando vazio, por que CHR(13), CHR(10) e Espaços Eu limpo antes de enviar.

Rodei a Rotina com DEBUG e ele da erro exatamente nessa Linha:
xmldsig:store := oCapicomStore
* oCapicomStore é um objeto né!

Mesmo assim você acredita que o problema esteja na montagem do XML ou Pode ser algo na criação do Objeto ?

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 14:19
por JoséQuintas
Antes de mais nada, melhor continuar o assunto na hbnfe, porque saiu totalmente do Clipper.

Esqueci de considerar que você poderia não ter nada instalado.
É necessário capicom.dll e msxml5.dll.
Tá junto no projeto, incluindo instruções de instalação.

https://github.com/JoseQuintas/sefazcla ... master/dll

o download fica na página inicial do projeto "download or clone".
https://github.com/JoseQuintas/sefazclass

Nota: São da Microsoft. Capicom tem na Microsoft pra baixar, mas o XML 5.0 só vinha no Office.

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 14:49
por depaula.jau
Tranquilo!

Acho que já podemos da por encerrado o assunto por hora, mesmo porque o que eu poderia resolver com você já foi dito.

Quanto a ter instaladas as dlls, eu já as tinha por conta da instalação do AcbrPlusMonitor, ele já faz a copia e registras essas mesmas dlls.

A unica coisa que notei é que as suas são mais antigas que as dele.

Vou tentar pegar uma maquina sem nada instalado e usar a suas para testar.

Se houver necessidade de recorrer ao grupo em outra oportunidade eu abro um assunto sobre no HBNFe.

Muito Obrigado pela sua atenção.

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 16:20
por JoséQuintas
Não precisa obrigatoriamente serem essas do download, só estão lá pra facilitar.

A Capicom deixou de ter atualizações.
Na última vez que vi, o instalador da Microsoft não funcionava em 64 bits, instalava em local errado.

Talvez acompanhar pelo debug passo a passo pra ver aonde acontece o erro.
Se for no win_OleCreateObject() significaria que a capicom não está instalada, ou por algum motivo o nome padrão pode ser diferente (difícil mas não impossível), ou a versão instalada é só pra programas 64 bits, ou não instalou como administrador (apesar que seria estranho funcionar no ACBR).

Como o HD do meu servidor deu erro no domingo, reinstalei tudo, e usei essas duas DLLs. Windows 7 Professional 64 bits.

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 18:14
por depaula.jau
Ja que mencionou isso, sem querer estender mais o dialogo, é esse mesmo o problema "win_OleCreateObject()."

Mas eu tenho uma pergunta: Você deve usar o xHarbour correto?
Porque na hora que fui compilar as rotinas, minha variável ambiente não é __XHARBOUR__ e sim __HARBOUR__ Pois bem! Mesmo incluindo a rotina ze_xharbour.prg no Projeto ele da erro de indefinição da função win_OleCreateObject(). justamente onde falta a definição dela pelo #ifdef

Estava pensando em reinstalar as suas dlls, registrar Mas o que posso fazer para incluir no meu projeto esse prg ?

Fim do Emissor Gratuito

Enviado: 19 Mai 2016 18:31
por JoséQuintas
Isso tem no Harbour 3.2 e no Harbour 3.4, faz parte da hbwin (hbwin tem rotinas referentes a Windows).

Acrescente no hbp:
hbwin.hbc