Simplificando fontes - hbnfe (Harbour -w3 -es2)
Muito bom, acredito que exemplos de uso dessa nova forma ajudaria muito os usuários a entender como aplicar na pratica, mais uma vez parabéns pelo ótimo trabalho.
Em homenagem a Paulo Cesar Toledo
https://pctoledo.org/
Código: Selecionar todos
Xml := "texto"
MemoWrit( arquivo, Xml )
XmlEnvio := MemoRead( arquivo )
Código: Selecionar todos
XmlRetorno := "webservice"
MemoWrit( arquivo, XmlRetorno )
Xml := MemoRead( arquivo )
Código: Selecionar todos
XmlRetorno := Processo( XmlEnvio )
Código: Selecionar todos
DEMO.PRG(31) Warning W0032 Variable 'NPOS' is assigned but not used in function
'MAIN(23)'
Código: Selecionar todos
LOCAL nPos := 0
nPos := 5
Código: Selecionar todos
nOpcao := Achoice( ... )
Rotina()
RETURN
FUNCTION Rotina()
IF nOpcao == 1
...
ENDIF
Código: Selecionar todos
CREATE CLASS hbNFeSped
VAR cCertificadoCN
VAR cUFWS
VAR cVersaoDados
VAR cAmbiente
VAR cUF
VAR cXml
VAR cXmlRetorno
VAR cXmlEnvelope
VAR cUrlWs
VAR cSoapAction
VAR cServico
VAR lOk
VAR ohbNFe
ENDCLASS
Código: Selecionar todos
CREATE CLASS algumaclasse INHERIT hbNFeSped
Código: Selecionar todos
-w3
-es2
Código: Selecionar todos
#pragma /w2 //de 0 a 3
#pragma /es2 //de 0 a 2
Código: Selecionar todos
#pragma -w0
#pragma -es0
Código: Selecionar todos
METHOD CTeConsulta( cChave, cCertificado, cAmbiente )
METHOD NFeConsulta( cChave, cCertificado, cAmbiente )
METHOD MDFeConsulta( cChave, cCertificado, cAmbiente )
Código: Selecionar todos
oClasse := SpedSefazClass():New()
oClasse:CteConsulta( "351510.....", "certificado", "1" )
? oClasse:cXmlResposta
Código: Selecionar todos
CREATE CLASS SefazClass
VAR cAmbiente INIT WSPRODUCAO
VAR cVersao INIT "3.10" // Versão NFE
VAR cScan INIT "N"
VAR cUF INIT "SP"
VAR cCertificado INIT ""
VAR cXmlDados INIT ""
VAR cXmlRetorno INIT "Erro Desconhecido"
//---- Uso interno ----
VAR cVersaoXml INIT ""
VAR cServico INIT ""
VAR cSoapAction INIT ""
VAR cWebService INIT ""
VAR cXmlSoap INIT ""
VAR lIsDebugMode INIT .F.
//--- Uso em processo ---
VAR cProjeto INIT WSPROJETONFE
VAR cXmlRecibo INIT ""
VAR cXmlProtocolo INIT ""
VAR cXmlFinal INIT ""
Código: Selecionar todos
METHOD NFeLoteEnvia( cXml, cLote, cUF, cCertificado, cAmbiente )
Código: Selecionar todos
oSefaz := SpedSefazClass():New()
oSefaz:NfeLoteEnvia( cXml, "1", "SP", "nomecertificado", "1" )
Código: Selecionar todos
METHOD NFeLoteEnvia( cXml, cLote, cUF, cCertificado, cAmbiente ) CLASS SefazClass
cCertificado := iif( cCertificado == NIL, ::cCertificado, cCertificado )
cAmbiente := iif( cAmbiente == NIL, ::cAmbiente, cAmbiente )
cUF := iif( cUF == NIL, ::cUF, cUF )
::cXmlDados := ""
IF ::cVersao == "2.00"
::cVersaoXml := "2.00"
::cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NfeRecepcao2"
::cSoapAction := "nfeRecepcaoLote2"
::cWebService := ::GetWebService( cUF, WSNFERECEPCAO, cAmbiente, WSPROJETONFE )
ELSE
::cVersaoXml := "3.10"
::cServico := "http://www.portalfiscal.inf.br/nfe/wsdl/NfeAutorizacao"
::cSoapAction := "NfeAutorizacao"
::cWebService := ::GetWebService( cUF, WSNFEAUTORIZACAO, cAmbiente, WSPROJETONFE )
ENDIF
::cXmlDados += [<enviNFe versao="] + ::cVersaoXml + [" xmlns="http://www.portalfiscal.inf.br/nfe">]
// FOR nCont = 1 TO Len( Lotes )
::cXmlDados += XmlTag( "idLote", cLote )
::cXmlDados += cXml
// NEXT
::cXmlDados += [</enviNFe>]
::XmlSoapPost( cUF, cCertificado, WSPROJETONFE )
::cXmlRecibo := ::cXmlRetorno
RETURN ::cXmlRetorno
Código: Selecionar todos
METHOD XmlSoapPost( cUF, cCertificado, cProjeto ) CLASS SefazClass
cCertificado := iif( cCertificado == NIL, ::cCertificado, cCertificado )
cUF := iif( cUF == NIL, ::cUF, cUF )
cProjeto := iif( cProjeto == NIL, ::cProjeto, cProjeto )
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 )
::MicrosoftXmlSoapPost()
IF Upper( Left( ::cXmlRetorno, 4 ) ) == "ERRO"
RETURN NIL
ENDIF
IF "<soap:Body>" $ ::cXmlRetorno .AND. "</soap:Body>" $ ::cXmlRetorno
::cXmlRetorno := XmlNode( ::cXmlRetorno, "soap:Body" )
ELSEIF "<soapenv:Body>" $ ::cXmlRetorno .AND. "</soapenv:Body>" $ ::cXmlRetorno
::cXmlRetorno := XmlNode( ::cXmlRetorno, "soapenv:Body" )
ELSE
::cXmlRetorno := "Erro SOAP: XML retorno não está no padrão " + ::cXmlRetorno
ENDIF
RETURN NIL
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 += [<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>]
IF ::cSoapAction == "nfeDistDFeInteresse"
::cXmlSoap += [<nfeDistDFeInteresse xmlns="] + ::cServico + [">]
::cXmlSoap += [<] + cProjeto + [DadosMsg>]
ELSE
::cXmlSoap += [<] + cProjeto + [DadosMsg xmlns="] + ::cServico + [">]
ENDIF
::cXmlSoap += ::cXmlDados
::cXmlSoap += [</] + cProjeto + [DadosMsg>]
IF ::cSoapAction == "nfeDistDFeInteresse"
::cXmlSoap += [</nfeDistDFeInteresse>]
ENDIF
::cXmlSoap += [</soap12:Body>]
::cXmlSoap += [</soap12:Envelope>]
RETURN ::cXmlSoap
Código: Selecionar todos
METHOD MicrosoftXmlSoapPost() CLASS SefazClass
LOCAL oServer, nCont, cRetorno := "Erro: No componente para SOAP"
LOCAL cSoapAction
//IF ::cSoapAction == "nfeDistDFeInteresse" .OR. ::cSoapAction == "nfeConsultaNFDest"
//cSoapAction := ::cServico + "/" + ::cSoapAction
//ELSE
cSoapAction := ::cSoapAction
//ENDIF
BEGIN SEQUENCE WITH { | e | Break( e ) }
oServer := win_OleCreateObject( "MSXML2.ServerXMLHTTP" )
IF ::cCertificado != NIL
//oServer:setOption( 2, oServer:getOption( 2 ) - SXH_SERVER_CERT_IGNORE_CERT_DATE_INVALID )
oServer:setOption( 3, "CURRENT_USER\MY\" + ::cCertificado )
ENDIF
oServer:Open( "POST", ::cWebService, .F. )
oServer:SetRequestHeader( "SOAPAction", cSoapAction )
oServer:SetRequestHeader( "Content-Type", "application/soap+xml; charset=utf-8" )
oServer:Send( ::cXmlSoap )
oServer:WaitForResponse( 500 )
cRetorno := oServer:ResponseBody
ENDSEQUENCE
IF ::lIsDebugMode
hb_MemoWrit( "xml1-soap.xml", ::cXmlSoap )
hb_MemoWrit( "xml2-action.xml", cSoapAction )
hb_MemoWrit( "xml3-url.xml", ::cWebService )
hb_MemoWrit( "xml4-retorno.xml", cRetorno )
ENDIF
IF ValType( cRetorno ) == "C"
::cXmlRetorno := cRetorno
ELSEIF cRetorno == NIL
::cXmlRetorno := "Erro SOAP: na comunicação"
ELSE
::cXmlRetorno := ""
FOR nCont = 1 TO Len( cRetorno )
::cXmlRetorno += Chr( cRetorno[ nCont ] )
NEXT
ENDIF
// IF .NOT. "<cStat>" $ cRetorno
// cRetorno := "<cStat>ERRO NO RETORNO</cStat>" + cRetorno
// ENDIF
RETURN NIL
Código: Selecionar todos
METHOD NFeConsultaRecibo( cRecibo, cUF, cCertificado, cAmbiente )
Código: Selecionar todos
oSefaz := SefazClass():New()
oSefaz:NFeConsultaRecibo( "123", "SP", "nome do certificado", "1" )
? oSefaz:cXmlRetorno
Código: Selecionar todos
cXMl := ConverteTxtXml( cTxt )
Código: Selecionar todos
CREATE CLASS SpedPorHash INHERIT SpedSefazClass
METHOD NFeLoteEnvia( cXml, cLote, cUF, cCertificado, cAmbiente )
END CLASS
METHOD NFeLoteEnvia( cXml, cLote, cUF, cCertificado, cAmbiente ) CLASS SpedPorHash
::SUPER:NFeLoteEnvia( cXml, cLote, cUF, cCertificado, cAmbiente )
oRetorno := Hash()
// grava em oRetorno
RETURN oRetorno