E quem quiser ajuda pra usar Sefazclass no Harbour.... é só pedir.
Tamo junto, ja uso a bastante tempo, o Quintas deu as dicas de uso e hoje ajudo em algumas alterações
muito fácil a utilização, e não precisa daquelas parafernálias da ACBr
Com o uso do MariaDB ja trago os dados no formato que vou gerar o XML e fica facil de montar tudo ex:
************************************************************************************************************************************************************************************************************************
METHOD EMITENTE( oQuery3 ) CLASS DANFECLASS
************************************************************************************************************************************************************************************************************************
LOCAL cXml;
IF ! oQuery3:Eof()
cXml := '<emit>'
cXml += XmlTag( 'CNPJ', ALLTRIM(oQuery3:Fields( "n_CNPJ" ):Value) )
cXml += XmlTag( 'xNome', rtrim(TIRACENTO(oQuery3:Fields( "n_xNome" ):Value)) )
cXml += XmlTag( 'xFant', RTRIM(TIRACENTO(oQuery3:Fields( "n_xFant" ):Value)) )
cXml += '<enderEmit>'
cXml += XmlTag( 'xLgr', rtrim(TIRACENTO(oQuery3:Fields( "n_xLgr" ):Value)) )
cXml += XmlTag( 'nro', rtrim(oQuery3:Fields( "n_nro" ):Value) )
IF ! EMPTY(oQuery3:Fields( "n_xCpl" ):Value)
cXml += XmlTag( 'xCpl', rtrim(oQuery3:Fields( "n_xCpl" ):Value) )
ENDIF
cXml += XmlTag( 'xBairro', rtrim(oQuery3:Fields( "n_xBairro" ):Value) )
cXml += XmlTag( 'cMun', oQuery3:Fields( "n_cMun" ):Value )
cXml += XmlTag( 'xMun', rtrim(oQuery3:Fields( "n_xMun" ):Value) )
cXml += XmlTag( 'UF', oQuery3:Fields( "n_xUF" ):Value )
cXml += XmlTag( 'CEP', oQuery3:Fields( "n_CEP" ):Value )
cXml += XmlTag( 'cPais', oQuery3:Fields( "n_cPais" ):Value )
cXml += XmlTag( 'xPais', rtrim(oQuery3:Fields( "n_xPais" ):Value) )
cXml += XmlTag( 'fone', rtrim(oQuery3:Fields( "n_fone" ):Value) )
cXml += '</enderEmit>'
cXml += XmlTag( 'IE', rtrim(oQuery3:Fields( "n_IE" ):Value) )
cXml += XmlTag( 'CRT', oQuery3:Fields( "n_CRT" ):Value )
cXml += '</emit>'
else
RETURN "ERRO"
ENDIF
RETURN cXml
************************************************************************************************************************************************************************************************************************
METHOD DESTINATARIO( oQuery1 ) CLASS DANFECLASS
************************************************************************************************************************************************************************************************************************
LOCAL cXml;
IF ! oQuery1:Eof()
cXml := '<dest>'
IF LEN(ALLTRIM(oQuery1:Fields( "e_cnpj" ):Value)) > 11
cXml += XmlTag( 'CNPJ', ALLTRIM(oQuery1:Fields( "e_cnpj" ):Value) )
ELSE
cXml += XmlTag( 'CPF', ALLTRIM(oQuery1:Fields( "e_cnpj" ):Value) )
ENDIF
cXml += XmlTag( 'xNome', rtrim(TIRACENTO(oQuery1:Fields( "e_xnome" ):Value)) )
cXml += '<enderDest>'
cXml += XmlTag( 'xLgr', rtrim(TIRACENTO(oQuery1:Fields( "e_xlgr" ):Value)) )
cXml += XmlTag( 'nro', rtrim(oQuery1:Fields( "e_nro" ):Value) )
IF ! EMPTY(oQuery1:Fields( "e_xcpl" ):Value)
cXml += XmlTag( 'xCpl', rtrim(oQuery1:Fields( "e_xcpl" ):Value) )
ENDIF
cXml += XmlTag( 'xBairro', rtrim(oQuery1:Fields( "e_xbairr" ):Value) )
cXml += XmlTag( 'cMun', rtrim(oQuery1:Fields( "e_cmun" ):Value) )
cXml += XmlTag( 'xMun', rtrim(oQuery1:Fields( "e_xmun" ):Value) )
cXml += XmlTag( 'UF', oQuery1:Fields( "e_UF" ):Value )
IF ! EMPTY(SoNumeros( oQuery1:Fields( "e_CEP" ):Value ))
cXml += XmlTag( 'CEP', SoNumeros( oQuery1:Fields( "e_CEP" ):Value ) )
ENDIF
cXml += XmlTag( 'cPais', oQuery1:Fields( "e_cpais" ):Value )
cXml += XmlTag( 'xPais', rtrim(oQuery1:Fields( "e_xpais" ):Value) )
if ! EMPTY(oQuery1:Fields( "e_fone" ):Value)
cXml += XmlTag( 'fone', rtrim(oQuery1:Fields( "e_fone" ):Value) )
// else
// cXml += XmlTag( 'fone', "" )
ENDIF
cXml += '</enderDest>'
cXml += XmlTag( 'indIEDest', oQuery1:Fields( "e_indie" ):Value )
if ! EMPTY(oQuery1:Fields( "e_IE" ):Value)
cXml += XmlTag( 'IE', rtrim(oQuery1:Fields( "e_IE" ):Value) )
ENDIF
if ! EMPTY(oQuery1:Fields( "e_ISUF" ):Value)
cXml += XmlTag( 'ISUF', rtrim(oQuery1:Fields( "e_ISUF" ):Value) )
ENDIF
if ! EMPTY(oQuery1:Fields( "e_IM" ):Value)
cXml += XmlTag( 'IM', rtrim(oQuery1:Fields( "e_IM" ):Value) )
ENDIF
if ! EMPTY(oQuery1:Fields( "e_EMAIL" ):Value)
cXml += XmlTag( 'email', rtrim(oQuery1:Fields( "e_EMAIL" ):Value) )
ENDIF
cXml += '</dest>'
else
RETURN "ERRO"
ENDIF
RETURN cXml
criei um metodo para cada parte e depois se nao tiver nenhum ERRO junto os pedaços assino e envio e testo se o retorno foi ok ou nao
cXmlDocumento := ( cIDENTIFICACAO + cEMITENTE + cDESTINATARIO;
+ cITENS_TRIBUTACAO + cTRANSPORTE;
+ cPAGAMENTO + cINF_ADICIONAIS)
oDlg:oProgressbar1:Set(,60)
oDlg:oLabel25:SetText("Assinando NF-e ")
oSefaz := SefazClass():New()
oSefaz:cUF := oQuery3:Fields( "n_xUF" ):Value
oSefaz:cAmbiente := oQuery3:Fields( "n_tpAmb" ):Value
oSefaz:cCertificado := cCertificado
oDlg:oProgressbar1:Set(,80)
oDlg:oLabel25:SetText("Aguardando Retorno ")
oSefaz:NFEloteenvia( cXmlDocumento )
IF ! oSefaz:cStatus $ "100,101,150,301,302"
oDlg:oLabel25:SetText(oSefaz:cMotivo)
hwg_MsgInfo(oSefaz:cStatus + oSefaz:cMotivo)
cQuery1:="SELECT arquivoxml.ARQUIVOXML_ID, arquivoxml.NOME, arquivoxml.FICHEIRO FROM arquivoxml WHERE arquivoxml.NOME = '" + ::a_Id + ".xml'"
oQuery2:= CONECCOESCLASS():ExecuteSQL(::oServer, cQuery1)
IF oQuery2:Eof()
cQuery1 :="INSERT INTO ARQUIVOXML ( "
cQuery2 :=" VALUES ("
cQuery1 += "arquivoxml.NOME, "
cQuery2 += "'" + ::a_Id + ".XML', "
cQuery1 += "arquivoxml.FICHEIRO) "
cQuery2 += "'" + oSefaz:cXmlDocumento + "') "
CONECCOESCLASS():ExecuteSQL(::oServer, cQuery1 + cQuery2 )
else
cQuery1:="UPDATE ARQUIVOXML SET "
cQuery1+="arquivoxml.FICHEIRO = '" + oSefaz:cXmlDocumento + "' "
cQuery1+="WHERE arquivoxml.ARQUIVOXML_ID = '" + STRZERO(oQuery2:Fields( "ARQUIVOXML_ID" ):Value,11,0) + "' "
CONECCOESCLASS():ExecuteSQL(::oServer, cQuery1)
ENDIF
ELSE
oDlg:oLabel25:SetText(oSefaz:cStatus + oSefaz:cMotivo)
cQuery1:="UPDATE DANFE SET "
cQuery1+="danfe.B_DHEMI = '" + XmlNode(oSefaz:cXmlAutorizado, "dhEmi") + "', "
cQuery1+="danfe.FL_SITUAC = '" + XmlNode(oSefaz:cXmlAutorizado, "cStat") + "', "
cQuery1+="danfe.FL_MOTIVO = '" + XmlNode(oSefaz:cXmlAutorizado, "xMotivo") + "' "
cQuery1+="WHERE danfe.PEDIDOS_ID = '" + STRZERO(NUMNOT,11,0) + "'"
CONECCOESCLASS():ExecuteSQL(::oServer, cQuery1)
cQuery1:="SELECT arquivoxml.ARQUIVOXML_ID, arquivoxml.NOME, arquivoxml.FICHEIRO FROM arquivoxml WHERE arquivoxml.NOME = '" + ::a_Id + ".xml'"
oQuery2:= CONECCOESCLASS():ExecuteSQL(::oServer, cQuery1)
IF oQuery2:Eof()
cQuery1 :="INSERT INTO ARQUIVOXML ( "
cQuery2 :=" VALUES ("
cQuery1 += "arquivoxml.NOME, "
cQuery2 += "'" + ::a_Id + ".XML', "
cQuery1 += "arquivoxml.FICHEIRO) "
cQuery2 += "'" + oSefaz:cXmlAutorizado + "') "
CONECCOESCLASS():ExecuteSQL(::oServer, cQuery1 + cQuery2 )
else
cQuery1:="UPDATE ARQUIVOXML SET "
cQuery1+="arquivoxml.FICHEIRO = '" + oSefaz:cXmlAutorizado + "' "
cQuery1+="WHERE arquivoxml.ARQUIVOXML_ID = '" + STRZERO(oQuery2:Fields( "ARQUIVOXML_ID" ):Value,11,0) + "' "
CONECCOESCLASS():ExecuteSQL(::oServer, cQuery1)
ENDIF
oDlg:oProgressbar1:Set(,90)
oDlg:oLabel25:SetText("Gerando DANFE em PDF ")
oSpedDa := hbNfeDaGeral():New()
oSpedDa:ToPdf( oSefaz:cXmlAutorizado, "C:\TEMP\" + ::a_Id + ".PDF" )
oDlg:oProgressbar1:Set(,100)
oDlg:oLabel25:SetText("NF-e Concluida com sucesso ")
IF .NOT. EMPTY(oQuery1:Fields( "e_eMAIL" ):Value)
::EMAIL_ENVIA( oQuery1, oQuery3, oSefaz)
ENDIF
WAPI_ShellExecute( NIL, "OPEN", "C:\TEMP\" + ::a_Id + ".PDF" ,"",NIL,5 )
ENDIF
se der ou nao erro eu guardo o XML para verificar ele no site do validador para caso de erro