E a que lê o XML de nota emitida.
Dá-lhe ler um "node" de cada vez, com XmlNode()
O resultado é a nota inteira numa variável, que pode ser usada pra importar o XML, cadastrar cliente, cadastrar produtos, etc.
FUNCTION XmlToDocNfeEmi( cXmlInput, oNfe )
LOCAL nCont
LOCAL cBlocoInfNfeComTag, cBlocoChave, cBlocoIde, cBlocoInfAdic
LOCAL cBlocoEmit, cBlocoEndereco, cBlocoDest, cBlocoTransporte, cBlocoTransp, cBlocoVeiculo, cBlocoVol, cBlocoTotal
LOCAL cBlocoDetalhe, cBlocoItem, cBlocoProd, cBlocoIpi, cBlocoIcms, cBlocoPis, cBlocoCofins
LOCAL cBlocoComb, cBlocoCobranca, cBlocoDup
cBlocoInfNfeComTag := XmlNode( cXmlInput, "infNFe", .T. )
cBlocoChave := XmlElement( cBlocoInfNfeComTag, "Id" )
cBlocoChave := Substr( cBlocoChave, 4 )
cBlocoChave := AllTrim( cBlocoChave )
IF Len( cBlocoChave ) <> 44
oNfe:cErro := "Chave de Acesso Inválida"
RETURN NIL
ENDIF
oNfe:ChaveAcesso := cBlocoChave
oNfe:cAssinatura := XmlNode( cXmlInput, "Signature" )
cBlocoIde := XmlNode( cXmlInput, "ide" )
oNfe:cNumDoc := XmlNode( cBlocoIde, "nNF" )
IF Len( Trim( oNfe:cNumDoc ) ) = 0
oNfe:cErro := "Sem número de documento"
RETURN NIL
ENDIF
oNfe:cNumDoc := StrZero( Val( oNfe:cNumDoc ), 9 )
IF .NOT. Empty( XmlDate( XmlNode( cBlocoIde, "dhEmi" ) ) )
oNfe:DataEmissao := XmlDate( XmlNode( cBlocoIde, "dhEmi" ) )
oNfe:DataSaida := XmlDate( XmlNode( cBlocoIde, "dhSaiEnt" ) )
ELSE
oNfe:DataEmissao := XmlDate( XmlNode( cBlocoIde, "dEmi" ) )
oNfe:DataSaida := XmlDate( XmlNode( cBlocoIde, "dSaiEnt" ) )
ENDIF
IF Empty( oNfe:DataSaida )
oNfe:DataSaida := oNfe:DataEmissao
ENDIF
oNfe:cAmbiente := XmlNode( cBlocoIde, "tpAmb" )
cBlocoInfAdic := XmlNode( cXmlInput, "InfAdic" )
oNfe:InfAdicionais := XmlNode( cBlocoInfAdic, "InfCpl" )
cBlocoEmit := XmlNode( cXmlInput, "emit" )
oNfe:Emitente:Cnpj := Transform( Substr( oNfe:ChaveAcesso, 7, 14 ), "@R 99.999.999/9999-99" )
oNfe:Emitente:Nome := Upper( XmlNode( cBlocoEmit, "xNome" ) )
oNfe:Emitente:InscricaoEstadual := XmlNode( cBlocoEmit, "IE" )
cBlocoEndereco := XmlNode( cBlocoEmit, "enderEmit" )
oNfe:Emitente:Endereco := Upper( XmlNode( cBlocoEndereco, "xLgr" ) )
oNfe:Emitente:Numero := XmlNode( cBlocoEndereco, "nro" )
oNfe:Emitente:Compl := XmlNode( cBlocoEndereco, "xCpl" )
oNfe:Emitente:Bairro := Upper( XmlNode( cBlocoEndereco, "xBairro" ) )
oNfe:Emitente:CidadeIbge := XmlNode( cBlocoEndereco, "cMun" )
oNfe:Emitente:Cidade := Upper( XmlNode( cBlocoEndereco, "xMun" ) )
oNfe:Emitente:Uf := Upper( XmlNode( cBlocoEndereco, "UF" ) )
oNfe:Emitente:Cep := Transform( XmlNode( cBlocoEndereco, "CEP" ), "@R 99999-999" )
oNfe:Emitente:Telefone := XmlNode( cBlocoEndereco, "fone" )
cBlocoDest := XmlNode( cXmlInput, "dest" )
oNfe:Destinatario:Cnpj := Trim( XmlNode( cBlocoDest, "CNPJ" ) )
IF Len( Trim( oNfe:Destinatario:Cnpj ) ) = 0
oNfe:Destinatario:Cnpj := XmlNode( cBlocoDest, "CPF" )
oNfe:Destinatario:Cnpj := Transform( oNfe:Destinatario:Cnpj, "@R 999.999.999-99" )
ELSE
oNfe:Destinatario:Cnpj := Transform( oNfe:Destinatario:Cnpj, "@R 99.999.999/9999-99" )
ENDIF
oNfe:Destinatario:Nome := Upper( XmlNode( cBlocoDest, "xNome" ) )
oNfe:Destinatario:InscricaoEstadual := XmlNode( cBlocoDest, "IE" )
cBlocoEndereco := XmlNode( cBlocoDest, "enderDest" )
oNfe:Destinatario:Endereco := Upper( XmlNode( cBlocoEndereco, "xLgr" ) )
oNfe:Destinatario:Numero := XmlNode( cBlocoEndereco, "nro" )
oNfe:Destinatario:Compl := XmlNode( cBlocoEndereco, "xCpl" )
oNfe:Destinatario:Bairro := Upper( XmlNode( cBlocoEndereco, "xBairro" ) )
oNfe:Destinatario:CidadeIbge := XmlNode( cBlocoEndereco, "cMun" )
oNfe:Destinatario:Cidade := Upper( XmlNode( cBlocoEndereco, "xMun" ) )
oNfe:Destinatario:Uf := Upper( XmlNode( cBlocoEndereco, "UF" ) )
oNfe:Destinatario:Cep := Transform( XmlNode( cBlocoEndereco, "CEP" ), "@R 99999-999" )
oNfe:Destinatario:Telefone := XmlNode( cBlocoEndereco, "fone" )
cBlocoTransporte := XmlNode( cXmlInput, "transp" )
cBlocoTransp := XmlNode( cBlocoTransporte, "transporta" )
oNfe:Transporte:Cnpj := Transform( XmlNode( cBlocoTransp, "CNPJ" ), "@R 99.999.999/9999-99" )
oNfe:Transporte:Nome := Upper( XmlNode( cBlocoTransp, "xNome" ) )
oNfe:Transporte:InscricaoEstadual := XmlNode( cBlocoTransp, "IE" )
oNfe:Transporte:Endereco := Upper( XmlNode( cBlocoTransp, "xEnder" ) )
oNfe:Transporte:Cidade := Upper( XmlNode( cBlocoTransp, "xMun" ) )
oNfe:Transporte:Uf := Upper( XmlNode( cBlocoTransp, "UF" ) )
cBlocoVol := XmlNode( cBlocoTransporte, "vol" )
oNfe:Transporte:Volumes:Qtde := Val( XmlNode( cBlocoVol, "qVol" ) )
oNfe:Transporte:Volumes:Especie := Upper( XmlNode( cBlocoVol, "esp" ) )
oNfe:Transporte:Volumes:Marca := Upper( XmlNode( cBlocoVol, "marca" ) )
oNfe:Transporte:Volumes:PesoLiquido := Val( XmlNode( cBlocoVol, "pesoL" ) )
oNfe:Transporte:Volumes:PesoBruto := Val( XmlNode( cBlocoVol, "pesoB" ) )
cBlocoVeiculo := XmlNode( cBlocoTransporte, "veicTransp" )
oNfe:Transporte:PlacaUf := Upper( XmlNode( cBlocoVeiculo, "UF" ) )
oNfe:Transporte:Placa := Upper( XmlNode( cBlocoVeiculo, "placa" ) )
cBlocoTotal := XmlNode( cXmlInput, "total" )
oNfe:Totais:IpiVal := Val( XmlNode( cBlocoTotal, "vIPI" ) )
oNfe:Totais:IIVal := Val( XmlNode( cBlocoTotal, "vII" ) )
oNfe:Totais:IcmBas := Val( XmlNode( cBlocoTotal, "vBC" ) )
oNfe:Totais:IcmVal := Val( XmlNode( cBlocoTotal, "vICMS" ) )
oNfe:Totais:SubBas := Val( XmlNode( cBlocoTotal, "vBCST" ) )
oNfe:Totais:SubVal := Val( XmlNode( cBlocoTotal, "vST" ) )
oNfe:Totais:PisVal := Val( XmlNode( cBlocoTotal, "vPIS" ) )
oNfe:Totais:CofVal := Val( XmlNode( cBlocoTotal, "vCOFINS" ) )
oNfe:Totais:ValPro := Val( XmlNode( cBlocoTotal, "vProd" ) )
oNfe:Totais:ValSeg := Val( XmlNode( cBlocoTotal, "vSeg" ) )
oNfe:Totais:ValFre := Val( XmlNode( cBlocoTotal, "vFrete" ) )
oNfe:Totais:ValOut := Val( XmlNode( cBlocoTotal, "vOutro" ) )
oNfe:Totais:ValNot := Val( XmlNode( cBlocoTotal, "vNF" ) )
cBlocoDetalhe := ""
IF "<det" $ cXmlInput
cBlocoDetalhe := Substr( cXmlInput, At( "<det", cXmlInput ) - 1 )
ENDIF
FOR nCont = 1 TO 1000
cBlocoItem := XmlNode( cBlocoDetalhe, [det nItem="] + LTrim( Str( nCont ) ) + ["])
IF Len( Trim( cBlocoItem ) ) = 0 // Se acabaram os itens
EXIT
ENDIF
AAdd( oNFE:Produto, NFEProdutoClass():New() )
cBlocoProd := XmlNode( cBlocoItem, "prod" )
oNfe:Produto[ nCont ]:Codigo := XmlNode( cBlocoProd, "cProd" )
oNfe:Produto[ nCont ]:Nome := Upper( XmlNode( cBlocoProd, "xProd" ) )
oNfe:Produto[ nCont ]:CFOP := Transform( XmlNode( cBlocoProd, "CFOP" ), "@R 9.9999" )
oNfe:Produto[ nCont ]:NCM := XmlNode( cBlocoProd, "NCM" )
oNfe:Produto[ nCont ]:GTIN := XmlNode( cBlocoProd, "cEAN" )
oNfe:Produto[ nCont ]:Unidade := Upper( XmlNode( cBlocoProd, "uCom" ) )
oNfe:Produto[ nCont ]:Qtde := Val( XmlNode( cBlocoProd, "qCom" ) )
oNfe:Produto[ nCont ]:ValorUnitario := Val( XmlNode( cBlocoProd, "vUnCom" ) )
oNfe:Produto[ nCont ]:ValorTotal := Val( XmlNode( cBlocoProd, "vProd" ) )
cBlocoIpi := XmlNode( cBlocoItem, "IPI" )
oNfe:Produto[ nCont ]:Ipi:Base := Val( XmlNode( cBlocoIpi, "vBC" ) )
oNfe:Produto[ nCont ]:Ipi:Aliquota := Val( XmlNode( cBlocoIpi, "pIPI" ) )
oNfe:Produto[ nCont ]:Ipi:Valor := Val( XmlNode( cBlocoIpi, "vIPI" ) )
cBlocoIcms := XmlNode( cBlocoItem, "ICMS" )
oNfe:Produto[ nCont ]:Icms:Cst := XmlNode( cBlocoIcms, "orig" ) + XmlNode( cBlocoIcms, "CST" )
oNfe:Produto[ nCont ]:Icms:Base := Val( XmlNode( cBlocoIcms, "vBC" ) )
oNfe:Produto[ nCont ]:Icms:Reducao := Val( XmlNode( cBlocoIcms, "vRedBC" ) )
oNfe:Produto[ nCont ]:Icms:Aliquota := Val( XmlNode( cBlocoIcms, "pICMS" ) )
oNfe:Produto[ nCont ]:Icms:Valor := Val( XmlNode( cBlocoIcms, "vICMS" ) )
oNfe:Produto[ nCont ]:IcmsSt:Base := Val( XmlNode( cBlocoIcms, "vBCST" ) )
oNfe:Produto[ nCont ]:IcmsSt:Iva := Val( XmlNode( cBlocoIcms, "pMVAST" ) )
oNfe:Produto[ nCont ]:IcmsSt:Reducao := Val( XmlNode( cBlocoIcms, "pRedBCST" ) )
oNfe:Produto[ nCont ]:IcmsSt:Aliquota := Val( XmlNode( cBlocoIcms, "pICMSST" ) )
oNfe:Produto[ nCont ]:IcmsSt:Valor := Val( XmlNode( cBlocoIcms, "vICMSST" ) )
cBlocoPis := XmlNode( cBlocoItem, "PIS" )
oNfe:Produto[ nCont ]:Pis:Cst := XmlNode( cBlocoPis, "CST" )
oNfe:Produto[ nCont ]:Pis:Base := Val( XmlNode( cBlocoPis, "vBC" ) )
oNfe:Produto[ nCont ]:Pis:Aliquota := Val( XmlNode( cBlocoPis, "pPIS" ) )
oNfe:Produto[ nCont ]:Pis:Valor := Val( XmlNode( cBlocoPis, "vPIS" ) )
cBlocoCofins := XmlNode( cBlocoItem, "COFINS" )
oNfe:Produto[ nCont ]:Cofins:Cst := XmlNode( cBlocoCofins, "CST" )
oNfe:Produto[ nCont ]:Cofins:Base := Val( XmlNode( cBlocoCofins, "vBC" ) )
oNfe:Produto[ nCont ]:Cofins:Aliquota := Val( XmlNode( cBlocoCofins, "pCOFINS" ) )
oNfe:Produto[ nCont ]:Cofins:Valor := Val( XmlNode( cBlocoCofins, "vCOFINS" ) )
cBlocoComb := XmlNode( cBlocoItem, "comb" )
oNfe:Produto[ nCont ]:Anp := XmlNode( cBlocoComb, "cProdANP" )
cBlocoDetalhe := Substr( cBlocoDetalhe, At( "</det", cBlocoDetalhe ) + 4 )
NEXT
cBlocoCobranca := XmlNode( cXmlInput, "cobr" )
FOR nCont = 1 TO 500
cBlocoDup := XmlNode( cBlocoCobranca, "dup" )
IF Len( Trim( cBlocoDup ) ) = 0
EXIT
ENDIF
AAdd( oNfe:Duplicata, NFEDuplicataClass():New() )
oNfe:Duplicata[ nCont ]:Vencimento := XmlDate( XmlNode( cBlocoDup, "dVenc" ) )
oNfe:Duplicata[ nCont ]:Valor := Val( XmlNode( cBlocoDup, "vDup" ) )
cBlocoCobranca := Substr( cBlocoCobranca, At( "</dup>", cBlocoCobranca ) + 3 )
NEXT
oNfe:Protocolo := XmlNode( cXmlInput, "nProt" )
oNFE:Status := XmlNode( cXmlInput, "cStat" )
RETURN NIL