Função que retorna o xml de uma nota em AdvPL

Olá pessoal…

Hoje vou mostrar uma função que desenvolvi, que retorna o xml de uma nota transmitida ou cancelada via AdvPL.

AdvPL

AdvPL

A função utiliza recursos do TSS para carregar e criar o arquivo xml, é necessário apenas informar, o número da nota, a série, e o caminho para geração do arquivo xml.

Abaixo a função desenvolvida:

//Bibliotecas
#Include "Protheus.ch"

/*/{Protheus.doc} zSpedXML
Função que gera o arquivo xml da nota (normal ou cancelada) através do documento e da série disponibilizados
@author Atilio
@since 25/07/2017
@version 1.0
@param cDocumento, characters, Código do documento (F2_DOC)
@param cSerie, characters, Série do documento (F2_SERIE)
@param cArqXML, characters, Caminho do arquivo que será gerado (por exemplo, C:\TOTVS\arquivo.xml)
@param lMostra, logical, Se será mostrado mensagens com os dados (erros ou a mensagem com o xml na tela)
@type function
@example Segue exemplo abaixo
	u_zSpedXML("000000001", "1", "C:\TOTVS\arquivo1.xml", .F.) //Não mostra mensagem com o XML
	
	u_zSpedXML("000000001", "1", "C:\TOTVS\arquivo2.xml", .T.) //Mostra mensagem com o XML
/*/

User Function zSpedXML(cDocumento, cSerie, cArqXML, lMostra)
	Local aArea        := GetArea()
	Local cURLTss      := PadR(GetNewPar("MV_SPEDURL","http://"),250)  
	Local oWebServ
	Local cIdEnt       := StaticCall(SPEDNFE, GetIdEnt)
	Local cTextoXML    := ""
	Default cDocumento := ""
	Default cSerie     := ""
	Default cArqXML    := GetTempPath()+"arquivo_"+cSerie+cDocumento+".xml"
	Default lMostra    := .F.
	
	//Se tiver documento
	If !Empty(cDocumento)
		cDocumento := PadR(cDocumento, TamSX3('F2_DOC')[1])
		cSerie     := PadR(cSerie,     TamSX3('F2_SERIE')[1])
		
		//Instancia a conexão com o WebService do TSS	
		oWebServ:= WSNFeSBRA():New()
		oWebServ:cUSERTOKEN        := "TOTVS"
		oWebServ:cID_ENT           := cIdEnt
		oWebServ:oWSNFEID          := NFESBRA_NFES2():New()
		oWebServ:oWSNFEID:oWSNotas := NFESBRA_ARRAYOFNFESID2():New()
		aAdd(oWebServ:oWSNFEID:oWSNotas:oWSNFESID2,NFESBRA_NFESID2():New())
		aTail(oWebServ:oWSNFEID:oWSNotas:oWSNFESID2):cID := (cSerie+cDocumento)
		oWebServ:nDIASPARAEXCLUSAO := 0
		oWebServ:_URL              := AllTrim(cURLTss)+"/NFeSBRA.apw"	
		
		//Se tiver notas
		If oWebServ:RetornaNotas()
		
			//Se tiver dados
			If Len(oWebServ:oWsRetornaNotasResult:OWSNOTAS:oWSNFES3) > 0
			
				//Se tiver sido cancelada
				If oWebServ:oWsRetornaNotasResult:OWSNOTAS:oWSNFES3[1]:oWSNFECANCELADA != Nil
					cTextoXML := oWebServ:oWsRetornaNotasResult:OWSNOTAS:oWSNFES3[1]:oWSNFECANCELADA:cXML
					
				//Senão, pega o xml normal
				Else
					cTextoXML := oWebServ:oWsRetornaNotasResult:OWSNOTAS:oWSNFES3[1]:oWSNFE:cXML
				EndIf
				
				//Gera o arquivo
				MemoWrite(cArqXML, cTextoXML)
				
				//Se for para mostrar, será mostrado um aviso com o conteúdo
				If lMostra
					Aviso("zSpedXML", cTextoXML, {"Ok"}, 3)
				EndIf
				
			//Caso não encontre as notas, mostra mensagem
			Else
				ConOut("zSpedXML > Verificar parâmetros, documento e série não encontrados ("+cDocumento+"/"+cSerie+")...")
				
				If lMostra
					Aviso("zSpedXML", "Verificar parâmetros, documento e série não encontrados ("+cDocumento+"/"+cSerie+")...", {"Ok"}, 3)
				EndIf
			EndIf
		
		//Senão, houve erros na classe
		Else
			ConOut("zSpedXML > "+IIf(Empty(GetWscError(3)), GetWscError(1), GetWscError(3))+"...")
			
			If lMostra
				Aviso("zSpedXML", IIf(Empty(GetWscError(3)), GetWscError(1), GetWscError(3)), {"Ok"}, 3)
			EndIf
		EndIf
	EndIf
	RestArea(aArea)
Return

Bom pessoal, por hoje é só.
Abraços e até a próxima.

Dan Atilio (Daniel Atilio)
Especialista em Engenharia de Software pela FIB. Entusiasta de soluções Open Source. E blogueiro nas horas vagas.

18 Responses

  1. William Correia disse:

    Muito bom, obrigado por compartilhar seu conhecimento, estou aprendendo muito aqui no seu site.
    Tem uma documentação completa sobre a WSNFeSBRA? ou como faço pra ver todos os Metodos dela?

    • Dan_Atilio disse:

      Bom dia William, tudo bem?
      Por ser uma classe padrão, apenas a TOTVS possui a documentação dela, se você for um cliente, você pode solicitar por chamado. Mas não sei se passariam isso.
      Agora, se você for um analista da TOTVS, se tiver a chave de ouro, procure pelo .prx e no fonte padrão estará os métodos dela.
      Um grande abraço.

  2. Emerson Nascimento disse:

    Não testei, mas achei sensacional pela simplicidade do código, pelo uso dos recursos da linguagem, sem reinvenção da “roda”. Obrigado por compartilhar.

  3. André Felipe Loos disse:

    Boa tarde!
    Estou precisando de uma função parecida, mas já tenho o XML e preciso gerar o PDF. Teria alguma opinião para o que pode ser feito?

    • Dan_Atilio disse:

      Bom dia André, tudo bem?
      Claro, o que você pode fazer, seria +- assim:
      1 – Criar uma tela de parâmetros com o caminho do xml de origem
      2 – No seu fonte, usar XMLParser / XMLParserFile para converter o texto em um objeto
      3 – Instanciar um FWMSPrinter em um objeto
      4 – Percorrer os nós do XML no objeto e imprimir no objeto de impressão

  4. GERALDO disse:

    Consigo gerar o XML mas vem sem PROTOCOLO DE AUTORIZAÇÃO DE USO ? Alguem com este problema nao consigo acertar o codigo…

  5. GERALDO disse:

    SIGAMDI , VOU TESTAR PELO SIGAADV e sim ja trasmitida e autorizada quando uso o exportar padrao do TSS ele exporta correto … estava subindo novo release mas vou retomar este assunte mas por enquanto muito obrigado todos os posts aqui so Fera … Vlw

  6. Vitor Saito disse:

    Bom dia Dan_Atilio! Utilizei seu fonte para efetuar o download do XML, porém, alguns XML’s não vem no padrão correto. Alguns ele baixa normalmente, mas outros vem com informações ‘cortadas’ e vem tudo em uma mesma linha. Quando abro em .TXT ele traz normalmente as informações. Pode me dizer o porquê? Obrigado.

    • Dan_Atilio disse:

      Bom dia Vitor.
      O de trazer na mesma linha, é similar a você ir no Protheus, na tela de monitorar, pegar o schema e colar.
      Ai para quebrar as linhas, você pode usar um plugin no Notepad++, o XML Tools (opção Pretty Print XML With Line Breaks).
      Quanto ao conteúdo vir cortado, não sei te dizer, não peguei casos assim. Sempre corta com um número exato de caracteres?

  7. Thiago disse:

    Olá Danilo.

    Teria alguma função para emitir NFs de entrada?
    Essa só gera de NFs de saída.

  8. WILKER MARCAL FARIA COSTA disse:

    Bom dia Dan_Atilio
    Estou usando em um cliente a funcao que retorna o xml
    e no meu caso esta gerando sem o protoloco de autorizacao.
    debugando o fonte na classe que carrega o gera o xml, nao esta gerando com o protocolo mesmo
    Tem ideia do que pode ser ?

    • Dan_Atilio disse:

      Bom dia Wilker.
      Se você fizer o processo manualmente funciona?
      Por exemplo, abrir o SIGAMDI, ir em Faturamento, Nfe Sefaz, Outras Ações, Monitorar, Inserir o número da Nota, clicar em outras ações, e depois clicar em Schema e salvar o XML. Dessa forma traz o protocolo?
      Abraços.

  9. Miziara disse:

    Aos colegas que estão com o problema do xml ser gerado sem o protocolo de uso, substitua a linha 59 pelo trecho abaixo:

    //Senão, pega o xml normal
                    Else
                        cTextoXML := '<?xml version="1.0" encoding="UTF-8"?> <nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">'
                        cTextoXML += oWebServ:oWsRetornaNotasResult:OWSNOTAS:oWSNFES3[1]:oWSNFE:cXML
                        cTextoXML += oWebServ:oWsRetornaNotasResult:OWSNOTAS:oWSNFES3[1]:oWSNFE:cXMLPROT
                        cTextoXML += '</nfeProc>'
                    EndIf
    
  10. Guilherme Lopes disse:

    Queria saber se tem algum parâmetro que pode ser informado para pesquisar no ambiente de de produção ou homologação

Deixe uma resposta