Página 2 de 3
Manifesto Destinatário - Ciência
Enviado: 31 Jul 2015 12:12
por JoséQuintas
Abrindo o endereço do webservice, que chamou a atenção o final ASMX, significa igual SP com manual:
https://www1.nfe.fazenda.gov.br/NFeDist ... eInteresse
Um manual pra ajudar.
Manifesto Destinatário - Ciência
Enviado: 31 Jul 2015 12:41
por JoséQuintas
Já dá pra identificar:
SOAPAction: "
http://www.portalfiscal.inf.br/nfe/wsdl ... eInteresse"
Serviço: "
http://www.portalfiscal.inf.br/nfe/wsdl ... ibuicaoDFe"
Projeto para o envelope: nfe
estranhei que esse envelope não tem cabeçalho (header), só corpo (body)
Diferente de todos os demais.
Manifesto Destinatário - Ciência
Enviado: 31 Jul 2015 12:46
por JoséQuintas
Muita pausa....
É porque encontrei o pacote de schemmas liberado dia 27/07/2015
E também o NOVO MANUAL 6.0
Só pra compartilhar a sensação...
Tentando entender se isso significa alguma coisa.
Manifesto Destinatário - Ciência
Enviado: 31 Jul 2015 14:51
por fladimir
Legal...
To colocando no projeto novo as alterações q vc sugeriu e vou testar em paralelo pra ver qual consigo definir primeiro.
Só 1 detalhe com relação ao método GetWebService do SPEDSEFAZClass.prg é q no q eu baixei do github estava
Código: Selecionar todos
METHOD GetWebService( cUF, cServico, cAmbiente, cProjeto ) CLASS SefazClass
e na sua postagem
Código: Selecionar todos
METHOD GetWebService( cUF, nWsServico, cAmbiente, cProjeto ) CLASS SefazClass
já entendi e alterei, percebi q vinha o mesmo e o q foi alterado foi o nome da variável pra facilitar o entendimento e coerência por ser Numérica.
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 02:28
por fladimir
Olá pessoal...
Será q estou progredindo...
Na classe padrão hbNFe atualizei a parte do WebService e no ambiente de homologação agora não deu um outro erro...
Na classe "Fork" digamos assim, q o José Quintas criou a partir da hbNFe q estou testando tb em paralelo apresentou o seguinte:
Código: Selecionar todos
<nfeDistDFeInteresseResponse xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe">
<nfeDistDFeInteresseResult>
<retDistDFeInt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" versao="3.10" xmlns="http://www.portalfiscal.inf.br/nfe">
<tpAmb>2</tpAmb>
<verAplic>1.1.5</verAplic>
<cStat>239</cStat>
<xMotivo>Rejeicao: Cabecalho - Versao do arquivo XML nao suportada</xMotivo>
<dhResp>2015-08-01T02:07:17</dhResp>
<ultNSU>000000000000000</ultNSU>
<maxNSU>000000000000000</maxNSU>
</retDistDFeInt>
</nfeDistDFeInteresseResult>
</nfeDistDFeInteresseResponse>
Envelope q foi criado antes
Código: Selecionar todos
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<nfeDistDFeInteresse xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe">
<nfeDadosMsg>
<distDFeInt xmlns="http://www.portalfiscal.inf.br/nfe" versao="3.10">
<tpAmb>2</tpAmb>
<cUFAutor>MS</cUFAutor>
<CNPJ>01234567000177</CNPJ> // Obs: CNPJ alterado
<distNSU>
<ultNSU>000000000000000</ultNSU>
</distNSU>
</distDFeInt>
</nfeDadosMsg>
</nfeDistDFeInteresse>
</soap:Body>
</soap:Envelope>
Códigos da Classe SefazClass (projeto novo a partir da hbNFe)
Código: Selecionar todos
STATIC FUNCTION UrlWebService( cUF, cAmbiente, nWsService, cVersao )
...
CASE cUF == "AN" .AND. cAmbiente == WSPRODUCAO
DO CASE
...
CASE nWsService == WSNFEDISTRIBUICAODFE ; cUrlWS := 'https://www1.nfe.fazenda.gov.br/NFeDistribuicaoDFe/NFeDistribuicaoDFe.asmx'
ENDCASE
CASE cUF == "AN" .AND. cAmbiente == WSHOMOLOGACAO
DO CASE
CASE nWsService == WSNFEDISTRIBUICAODFE ; cUrlWS := 'https://hom.nfe.fazenda.gov.br/NFeDistribuicaoDFe/NFeDistribuicaoDFe.asmx'
ENDCASE
...
Método Provisório para DistribuicaoDFe na classe SefazClass (projeto novo a partir da hbNFe)
Código: Selecionar todos
METHOD NFeDistribuicaoDFe( cCNPJ, indTodas, indEmi ) CLASS SefazClass
local nUltNSU, aRetorno:=HASH(),;
cUF, cCertificado, cAmbiente
default cCNPJ := "01234567000155" // Obs CNPJ alterado
default indTodas := 0 // 0 = Todas NF-e, 1 = Somente as NF-e que ainda não tiveram manifestação, 2 = Item anterior inluindo NF-e que não tiveram ciência da operacao
default indEmi := 0 // 0 = Todos emitentes e remetentes (incluso notas de transferencias), 1 = Somente notas por emissor / rementete diferente do CNPJ informado
default nUltNSU := 0 // Ultimo NSU recebido
default cCertificado := ::cCertificado
default cAmbiente := '2' //::cAmbiente
default cUF := 'MS'
::cVersaoXml := "3.10"
::cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe"
::cSoapAction := "http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe/nfeDistDFeInteresse"
::cWebService := ::GetWebService( cUF, WSNFEDISTRIBUICAODFE, cAmbiente, WSPROJETONFE )
*-- XML Miolo
::cXmlDados := ""
::cXmlDados += [<distDFeInt xmlns="http://www.portalfiscal.inf.br/nfe" versao="] + ::cVersaoXML + [">]
::cXmlDados += XmlTag( "tpAmb", cAmbiente )
::cXmlDados += XmlTag( "cUFAutor", "MS" ) //'<cUFAutor>'+::cUFAutor+'</cUFAutor>'+;
::cXmlDados += XmlTag( "CNPJ", cCNPJ ) //'<CNPJ>'+::cCNPJ+'</CNPJ>'+;
::cXmlDados += [<distNSU>]
::cXmlDados += XmlTag( "ultNSU", STRZERO(nUltNSU,15) )
::cXmlDados += [</distNSU>]
::cXmlDados += [</distDFeInt>]
MEMOWRIT("\distDFeInt-ped.xml", ::cXmlDados,.F.) // Miolo XML
//-- Comentei a chamada do método abaixo e transcrevi ele pra acompanhar isoladamente.
//::XmlSoapPost( cUF, cCertificado, WSPROJETONFE)
DO CASE
CASE Empty( ::cWebService )
::cXmlRetorno := "Erro SOAP: Não há endereço de webservice"
RETURN NIL
CASE Empty( ::cServico )
::cXmlRetorno := "Erro SOAP: Não há nome do serviço"
RETURN NIL
CASE Empty( ::cSoapAction )
::cXmlRetorno := "Erro SOAP: Não há endereço de SOAP Action"
RETURN NIL
CASE Empty( ::cVersaoXml )
::cXmlRetorno := "Erro SOAP: Não há número de versão"
RETURN NIL
ENDCASE
IF Empty( cUF )
::cXmlRetorno := "Erro SOAP: Não há sigla de UF"
RETURN NIL
ENDIF
//::XmlSoapEnvelope( cUF, cProjeto) //Nao usei por enquanto devido não ter o Header etc
::cXmlSoap := ""
::cXmlSoap += [<?xml version="1.0" encoding="utf-8"?>] // UTF-8
::cXmlSoap += [<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ]
::cXmlSoap += [xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">]
::cXmlSoap += [<soap:Body>]
::cXmlSoap += '<nfeDistDFeInteresse xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe">'
::cXmlSoap += '<nfeDadosMsg>'
::cXmlSoap += ::cXmlDados
::cXmlSoap += '</nfeDadosMsg>'
::cXmlSoap += '</nfeDistDFeInteresse>'
::cXmlSoap += [</soap:Body>]
::cXmlSoap += [</soap:Envelope>]
MEMOWRIT("distDFeEnvelope-ped.xml", ::cXMLSoap, .F.)
::MicrosoftXmlSoapPost()
IF Upper( Left( ::cXmlRetorno, 4 ) ) == "ERRO"
RETURN NIL
ENDIF
IF "<soap:Body>" $ ::cXmlRetorno .AND. "</soap:Body>" $ ::cXmlRetorno
::cXmlRetorno := XmlNode( ::cXmlRetorno, "soap:Body" )
ELSE
::cXmlRetorno := "Erro SOAP: XML retorno não está no padrão " + ::cXmlRetorno
ENDIF
MEMOWRIT("distDFeRetorno.xml", ::cXMLRetorno, .F.)
RETURN ::cXmlRetorno
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 12:52
por fladimir
Resolvi aki
o problema era q estava passando na TAG cUFAutor como a SIGLA o estado e tem q ser o CODIGO.
Vlw galera...
Agora vou pra outra etapa.
[]´s
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 16:04
por JoséQuintas
Correção:
Como sempre escrevi aqui, a rotina de assinatura tem origem na hbnfe.
Todo restante não.
E está em separado justamente por ser complicado ajustar a hbnfe pra usar minha classe.
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 16:11
por JoséQuintas
Alterei cService pra nWsService, porque no começo o conteúdo era uma string, depois mudou pra número e não tinha reparado antes que o nome tinha ficado em desacordo com o conteúdo.
Depois alterei novamente, pra nWsServico, porque uma vez o projeto sendo para o Brasil, não tem porque usar em inglês.
Não é problema pra quem use, porque o nome é interno.
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 17:59
por JoséQuintas
Uma consideração pra estes dois:
Código: Selecionar todos
::cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe"
::cSoapAction := "http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe/nfeDistDFeInteresse"
Isso é como se fossem nomes de pastas/diretórios.
Caso não seja indicado em SoapAction, o default é a pasta definida em Serviço.
Então, seguindo o padrão do restante da classe:
Código: Selecionar todos
::cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe"
::cSoapAction := "nfeDistDFeInteresse"
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 18:07
por JoséQuintas
Coloquei a diferença de envelope no envelope.
Fica visível que trata-se do Header.
Ainda quero testar se isso é um formato alternativo de escrever o Header.
UF e versão não tem, talvez porque vai retornar documentos de qualquer UF e versão
Código: Selecionar todos
METHOD XmlSoapEnvelope( cUF, cProjeto ) CLASS SefazClass
cUF := iif( cUF == NIL, ::cUF, cUF )
cProjeto := iif( cProjeto == NIL, ::cProjeto, cProjeto )
::cXmlSoap := ""
::cXmlSoap += [<?xml version="1.0" encoding="utf-8"?>] // UTF-8
::cXmlSoap += [<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ]
::cXmlSoap += [xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">]
IF ::cSoapAction == "nfeDistDFeInteresse"
::cXmlSoap += [<nfeDistDFeInteresse xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe">]
ELSE
::cXmlSoap += [<soap12:Header>]
::cXmlSoap += [<] + cProjeto + [CabecMsg xmlns="] + ::cServico + [">]
::cXmlSoap += [<cUF>] + UFCodigo( cUF ) + [</cUF>]
::cXmlSoap += [<versaoDados>] + ::cVersaoXml + [</versaoDados>]
::cXmlSoap += [</] + cProjeto + [CabecMsg>]
::cXmlSoap += [</soap12:Header>]
ENDIF
::cXmlSoap += [<soap12:Body>]
::cXmlSoap += [<] + cProjeto + [DadosMsg xmlns="] + ::cServico + [">]
::cXmlSoap += ::cXmlDados
::cXmlSoap += [</] + cProjeto + [DadosMsg>]
::cXmlSoap += [</soap12:Body>]
IF ::cSoapAction == "nfeDistDFeInteresse"
::cXmlSoap += [</nfeDistDFeInteresse>]
ENDIF
::cXmlSoap += [</soap12:Envelope>]
RETURN ::cXmlSoap
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 18:29
por JoséQuintas
Aquilo de UF ou código.
Se viu na classe, ou no XML de Soap, tem uma função UFCodigo( cUF ) pra isso.
Como complemento, já fica destacado aonde vai código.
Sobre a checagem de UF e versão em branco:
Como esse novo webservice não usa isso, e existe um default para os dois valores, eliminar a checagem de vez.
Fazia falta antes, quando comecei com isso.
Manifesto Destinatário - Ciência
Enviado: 01 Ago 2015 22:05
por fladimir
No projeto hbNFe
antes do oSender:Send( ::cXmlSoap ) tem a parte abaixo q não tem no projeto novo, vc poderia explicar novamente pq, pq esta dando erro e no hbNFe nao, acredito q talvez seja a falta do trecho abaixo:
Código: Selecionar todos
#ifdef __XHARBOUR__
oDOMDoc := xhb_CreateObject( _MSXML2_DOMDocument )
#else
oDOMDoc := win_oleCreateObject( _MSXML2_DOMDocument )
#endif
oDOMDoc:async := .F.
oDOMDoc:validateOnParse := .T.
oDOMDoc:resolveExternals := .F.
oDOMDoc:preserveWhiteSpace := .T.
oDOMDoc:LoadXML(cXML)
IF oDOMDoc:parseError:errorCode <> 0 // XML não carregado
cMsgErro := "Não foi possível carregar o documento pois ele não corresponde ao seu Schema"+HB_OsNewLine() +;
" Linha: " + STR(oDOMDoc:parseError:line)+HB_OsNewLine() +;
" Caractere na linha: " + STR(oDOMDoc:parseError:linepos)+HB_OsNewLine() +;
" Causa do erro: " + oDOMDoc:parseError:reason+HB_OsNewLine() +;
"code: "+STR(oDOMDoc:parseError:errorCode)
aRetorno['OK'] := .F.
aRetorno['MsgErro'] := cMsgErro
RETURN(aRetorno)
ENDIF
Manifesto Destinatário - Ciência
Enviado: 02 Ago 2015 16:09
por fladimir
Pessoal, na classe original hbNFe, com a alteração da URL do WebService q eu estava usando e a questão da UF q coloquei String e era Numerico blz funcionou, vou pra parte da manifestação e download depois posto aki.
Zé, não consegui adaptar no projeto novo, mas queria ver isto, ai não sei se a gente continua no outro tópico ou se continuamos por aki, tem q ver se não fere as regras do fórum se não vai confundir o povo.
[]´s
Manifesto Destinatário - Ciência
Enviado: 02 Ago 2015 17:03
por JoséQuintas
Isso na hbnfe não sei se foi proposital, ou se porque veio do ACBR.
A transmissão é.... transmitir o XML.
Na hbnfe, primeiro ela carrega para um componente de XML, o DOMDOC, pra depois enviar o XML que está no componente.
Não sei se pode servir pra validação extra, ou pra ajustar alguma formatação errada, mas é apenas suposição.
Mesmo que seja isso, pode esconder algum erro eventual (se é que seja pra isso).
Acabei mostrando de onde pego parte das informações, que é nos "manuais" em webservices.
Sobre o projeto novo:
A intenção era agrupar tudo: a classe + hbnfe.
Na época que comecei a mexer na hbnfe perguntei por aqui, mas não houve resposta.
Mas acho que já deu uma boa idéia das mudanças radicais que podem ser feitas na hbnfe.
No momento, nenhum dos projetos contém tudo que precisa.
Inclusive já não funciona o acesso à hbnfe do gogglecode.
Como todos devem saber, o googlecode entrou em modo somente leitura, com contagem regressiva para a eliminação de vez.
Isso referente a TODOS os projetos do googlecode, e não apenas à hbnfe.
Continua dependendo do autor do projeto decidir o que fazer.
Se eu transferir para o github vai ficar em meu nome, mas não sou o autor, vai parecer que estou sequestrando o projeto... rs
De qualquer forma, enquanto isso não acontece, a hbnfe está paralisada e totalmente desatualizada.
Talvez até melhor pra todos migrar de vez, e ir atualizando.
Depois vai ser só transferir para o autor, assim que ele der notícias.
O googlecode só vai ser desativado no ano que vém... tá longe ainda.
Mas não sei se a atualização da hbnfe pode esperar, ainda mais agora que tem interessado nela.
Manifesto Destinatário - Ciência
Enviado: 02 Ago 2015 20:45
por JoséQuintas
Voltando aquela parte da hbnfe, pra tirar dúvida, dá pra olhar o que acontece.
Só comparar o XML original com o retornado pelo DomDocument.
Usando o fonte da hbnfe:
Código: Selecionar todos
#ifdef __XHARBOUR__
oDOMDoc := xhb_CreateObject( _MSXML2_DOMDocument )
#else
oDOMDoc := win_oleCreateObject( _MSXML2_DOMDocument )
#endif
oDOMDoc:async := .F.
oDOMDoc:validateOnParse := .T.
oDOMDoc:resolveExternals := .F.
oDOMDoc:preserveWhiteSpace := .T.
oDOMDoc:LoadXML(cXML)
IF oDOMDoc:parseError:errorCode <> 0 // XML não carregado
cMsgErro := "Não foi possível carregar o documento pois ele não corresponde ao seu Schema"+HB_OsNewLine() +;
" Linha: " + STR(oDOMDoc:parseError:line)+HB_OsNewLine() +;
" Caractere na linha: " + STR(oDOMDoc:parseError:linepos)+HB_OsNewLine() +;
" Causa do erro: " + oDOMDoc:parseError:reason+HB_OsNewLine() +;
"code: "+STR(oDOMDoc:parseError:errorCode)
aRetorno['OK'] := .F.
aRetorno['MsgErro'] := cMsgErro
RETURN(aRetorno)
ENDIF
IF cXml != oDomDoc:Xml
? "XML modificado por DomDOC"
? "original"
? cXml
? "Após DomDoc"
? oDomDoc:Xml
ENDIF
RETURN
À primeira vista, só faz uma validação básica do XML.
Mas é de se considerar que o XML chega aí correto e pronto pra uso.
Na hbnfe tem isso em toda comunicação, e acaba dando a impressão de que faz parte dela.