BlackTDN Search

terça-feira, 27 de julho de 2010

Protheus :: Retornando o XML do Documento de Saida (Nota Fiscal Eletrônica) usando WebService

Mais uma vez, e a pedido de minha querida amiga Carla Soneta, vou publicar hoje um exemplo de programa em Advpl que gera um WebService para retornar o Xml do Documento de Saída ( Nota Fiscal de Saída). Esse WebService faz uso do serviço WSNFeBra do padrão para obter o XML. Obs.: O Xml retornado é o mesmo encaminhado para a SEFAZ. É denominado u_wsGetXmlNFSe e possui o método GetXmlNFSe que recebe, como parâmetros: CodEmp (Código da Empresa), CodFil (Código da Filial), CNPJ (CNPJ do Favorecido ), NumeroDaNFS (Número da Nota Fiscal de Saída ) e retorna XMLNFe (XML com as informações da NFe).


#INCLUDE "APWEBSRV.CH"
#INCLUDE "PROTHEUS.CH"
#INCLUDE "TBICONN.CH"
#INCLUDE "TRYEXCEPTION.CH"

#IFNDEF CRLF
 #DEFINE CRLF Chr(13)+Chr(10)
#EndIF 

#DEFINE STR0001 "Serviço de consulta aos Documentos de Saída (NFSe)"
#DEFINE STR0002 "Método de consulta as informações do documento saida (NFSe)"
#DEFINE STR0003 "Cliente invalido"
#DEFINE STR0004 "CNPJ invalido"
#DEFINE STR0005 "Documento nao encontrado"
#DEFINE STR0006 "A Especie dessa nota nao e 'SPED'"
#DEFINE STR0007 "Problema na conexao com Totvs Sped Services"
#DEFINE STR0008 "Problema no Retorno da Nota Fiscal"
#DEFINE STR0009 "Nao foi Possivel Obter o Codigo da Entidade. Verifique a sua Configuracao do SPED"

/*/
WSSERVICE: u_wsGetXmlNFSe
Autor: Marinaldo de Jesus
Data: 01/07/2010
Descrição: Serviço de Constulta a Nota Fiscal de Saida ( Eletrônica )
/*/
WSSERVICE u_wsGetXmlNFSe DESCRIPTION STR0001 NAMESPACE "http://localhost/naldo/ws/u_wsgetxmlnfse.apw" //"Serviço de consulta aos Documentos de Saída (NFSe)"

 WSDATA CodEmp   AS String OPTIONAL
 WSDATA CodFil   AS String OPTIONAL
 WSDATA CNPJ   AS String
 WSDATA NumeroDaNFS AS String
 WSDATA XMLNFe   AS String OPTIONAL
 
 WSMETHOD GetXmlNFSe DESCRIPTION STR0002 //"Método de consulta as informações do documento saida (NFSe)"


ENDWSSERVICE

/*/
WSMETHOD: GetXmlNFSe
Autor: Marinaldo de Jesus
Data:16/07/2010
Descrição: Obter e retornar a Nota Fiscal de Saida Eletrônica
/*/
WSMETHOD GetXmlNFSe WSRECEIVE CodEmp,CodFil,CNPJ,NumeroDaNFS WSSEND XMLNFe WSSERVICE u_wsGetXmlNFSe

 Local cUrl    := ""
 Local cDoc    := ""
 Local cSerie   := ""
 Local cIdEnt   := "" 
 Local cCliente   := ""
 Local cLojaCli   := ""
 Local cSA1Filial  := ""
 Local cSF2Filial  := ""
 Local cGetIdEntErr  := ""
 Local cMsgSoapFault := ""

 Local lReturn   := .T.
 Local lRetornaFxOk := .F.

 Local oException
 Local oWsNFeSBRA
 
 TRYEXCEPTION
 
  DEFAULT Self:CodEmp := "01"
  DEFAULT Self:CodFil := "01"
  
  RpcSetType(3)

  
  IF FindFunction("WfPrepEnv")
  
   WfPrepEnv( Self:CodEmp , Self:CodFil )

  
  Else
  
   PREPARE ENVIRONMENT EMPRESA Self:CodEmp FILIAL Self:CodFil
  
  EndIF
  
  TRYEXCEPTION
  
   IF Empty(Self:CNPJ)

    cMsgSoapFault := STR0003 //"Cliente invalido"
    BREAK
   EndIF
   
   Self:CNPJ := UnMaskCNPJ( Self:CNPJ )

   
   cSA1Filial := xFilial( "SA1" )
   cSF2Filial := xFilial( "SF2" )

   
   SA1->( dbSetOrder( RetOrder( "SA1" , "A1_FILIAL+A1_CGC" ) ) )

   
   IF SA1->( !dbSeek( cSA1Filial + Self:CNPJ , .F. ) )

    cMsgSoapFault := STR0004 + " :: " + TransForm( Self:CNPJ , GetSx3Cache( "A1_CGC" , "X3_PICTURE" ) ) //"CNPJ invalido"

    BREAK
   EndIF
   
   SA1->( dbSetOrder( RetOrder( "SA1" , "A1_FILIAL+A1_COD+A1_LOJA" ) ) )

   
   cCliente := SA1->A1_COD 
   
   cLojaCli := SA1->A1_LOJA
   
   cDoc := Padr( AllTrim( Self:NumeroDaNFS ) , GetSx3Cache( "D2_DOC" , "X3_TAMANHO" ) )

   
   SF2->( dbSetOrder( RetOrder( "SF2" , "F2_FILIAL+F2_CLIENTE+F2_LOJA+F2_DOC+F2_SERIE" ) ) )

   
   IF SF2->( !dbSeek( cSF2Filial + cCliente + cLojaCli + cDoc , .F.) )

    cMsgSoapFault := STR0005 + " :: " + TransForm( Self:CNPJ , GetSx3Cache( "A1_CGC" , "X3_PICTURE" ) ) + "Self:" + cSF2Filial+cCliente+cLojaCli+cDoc //"Documento nao encontrado"

    BREAK
   EndIF
   
   IF !( "SPED" $ SF2->F2_ESPECIE )

    cMsgSoapFault := STR0006 + " :: " + TransForm( Self:CNPJ , GetSx3Cache( "A1_CGC" , "X3_PICTURE" ) ) + "Self:" + cSF2Filial+cCliente+cLojaCli+cDoc //"A Especie dessa nota nao e 'SPED'"

    BREAK
   EndIF
   
   cSerie := SF2->F2_SERIE
   
   SF2->( dbSetOrder(1) )

   
   IF SF2->( !dbSeek(cSF2Filial+cDoc+cSerie+cCliente+cLojaCli,.F.) )

    cMsgSoapFault := STR0005 + "Self:" + cSF2Filial+cDoc+cSerie+cCliente+cLojaCli //"Documento nao encontrado"

    BREAK
   EndIF
   
   cURL := PadR(GetNewPar("MV_SPEDURL","http://"),250)

   
   IF !( CTIsReady(cURL) )
    cMsgSoapFault := STR0007 + " :: " + cURL //"Problema na conexao com Totvs Sped Services"

    BREAK
   EndIF
   
   cURL := AllTrim(cURL)+"/NFeSBRA.apw"
   
   IF !( CTIsReady(cURL) )

    cMsgSoapFault := STR0007 + " :: " + cURL //"Problema na conexao com Totvs Sped Services"
    BREAK
   EndIF

   
   cIdEnt := GetIdEnt( @cGetIdEntErr )
   
   IF Empty( cIdEnt )

    IF Empty( cGetIdEntErr )
     cGetIdEntErr := STR0009 //"Nao foi Possivel Obter o Codigo da Entidade. Verifique a sua Configuracao do SPED"
    EndIF

    cMsgSoapFault := cGetIdEntErr
    BREAK
   EndIF
   
   oWsNFeSBRA       := WSNFeSBRA():New()

   oWsNFeSBRA:cUSERTOKEN   := "TOTVS"
   oWsNFeSBRA:cID_ENT     := cIdEnt 
   oWsNFeSBRA:_URL     := cURL
   oWsNFeSBRA:cIdInicial    := cSerie+cDoc
   oWsNFeSBRA:cIdFinal    := cSerie+cDoc
   oWsNFeSBRA:dDataDe     := Stod("19701512") //SF2->F2_EMISSAO

   oWsNFeSBRA:dDataAte    := Stod("20701512") //SF2->F2_EMISSAO
   oWsNFeSBRA:cCNPJDESTInicial  := Self:CNPJ
   oWsNFeSBRA:cCNPJDESTFinal   := Self:CNPJ
   oWsNFeSBRA:nDiasparaExclusao := 0

   
   lRetornaFxOk      := oWsNFeSBRA:RetornaFX()
   
   DEFAULT lRetornaFxOk := .F.
   
   IF !( lRetornaFxOk )

    cMsgSoapFault := STR0008 //"Problema no Retorno da Nota Fiscal"
    BREAK
   EndIF
   
   nItens := Len( oWsNFeSBRA:oWsRetornaFxResult:oWsNotas:oWsNFES3 )

   
   For nItem := 1 To nItens
    Self:XMLNFe := oWsNFeSBRA:oWsRetornaFxResult:oWsNotas:oWsNFES3[nItem]:oWsNFE:cXML
    Exit

   Next nItem
  
  CATCHEXCEPTION USING oException 
  
   lReturn := .F.
  
   IF ( ValType( oException ) == "O" )

  
   cMsgSoapFault += IF( !Empty( oException:Description ) , oException:Description , "" )

   cMsgSoapFault += IF( !Empty( oException:ErrorStack ) , oException:ErrorStack , "" )

  
   EndIF 
  
   SetSoapFault( "GetXmlNFSe" , cMsgSoapFault )
  
  ENDEXCEPTION
 
 CATCHEXCEPTION USING oException
 
  lReturn := .F.
 
  IF ( ValType( oException ) == "O" )

   cMsgSoapFault += IF( !Empty( oException:Description ) , oException:Description , "" )

   cMsgSoapFault += IF( !Empty( oException:ErrorStack ) , oException:ErrorStack , "" )

  EndIF 
 
  SetSoapFault( "GetXmlNFSe" , cMsgSoapFault )
 
 ENDEXCEPTION
 
 RESET ENVIRONMENT

Return( lReturn )

/*/
Funcao: UnMaskCNPJ
Autor: Marinaldo de Jesus
Data: 16/07/2010

Descrição: Retirar a Máscara do CNPJ
/*/
Static Function UnMaskCNPJ( cCNPJ )

 Local cCNPJClear := CNPJ
 
 BEGIN SEQUENCE
 
  IF Empty( cCNPJClear )
   BREAK
  EndIF

  
  cCNPJClear := StrTran( cCNPJClear , "." , "" )

  cCNPJClear := StrTran( cCNPJClear , "/" , "" )

  cCNPJClear := StrTran( cCNPJClear , "-" , "" )

  cCNPJClear := AllTrim( cCNPJClear )
  
 END SEQUENCE

Return( cCNPJClear )

/*/
Funcao: GetIdEnt
Autor: Marinaldo de Jesus
Data: 06/07/2010

/*/
Static Function GetIdEnt( cError )

 Local aArea := GetArea()

 Local cIdEnt := ""
 Local cURL := PadR(GetNewPar("MV_SPEDURL","http://"),250)

 Local lMethodOk := .F.
 
 Local oWsSPEDAdm
 
 BEGIN SEQUENCE
 
  IF !( CTIsReady(cURL) )
   BREAK
  EndIF
  
  cURL := AllTrim(cURL)+"/SPEDADM.apw"
  
  IF !( CTIsReady(cURL) )
   BREAK
  EndIF
  
  oWsSPEDAdm          := WsSPEDAdm():New()

  oWsSPEDAdm:cUSERTOKEN       := "TOTVS"
  oWsSPEDAdm:oWsEmpresa:cCNPJ     := SM0->( IF(M0_TPINSC==2 .Or. Empty(M0_TPINSC),M0_CGC,"") )
  oWsSPEDAdm:oWsEmpresa:cCPF      := SM0->( IF(M0_TPINSC==3,M0_CGC,"") )
  oWsSPEDAdm:oWsEmpresa:cIE      := SM0->M0_INSC
  oWsSPEDAdm:oWsEmpresa:cIM      := SM0->M0_INSCM 
  oWsSPEDAdm:oWsEmpresa:cNOME     := SM0->M0_NOMECOM
  oWsSPEDAdm:oWsEmpresa:cFANTASIA    := SM0->M0_NOME
  oWsSPEDAdm:oWsEmpresa:cENDERECO    := FisGetEnd(SM0->M0_ENDENT)[1]
  oWsSPEDAdm:oWsEmpresa:cNUM      := FisGetEnd(SM0->M0_ENDENT)[3]
  oWsSPEDAdm:oWsEmpresa:cCOMPL     := FisGetEnd(SM0->M0_ENDENT)[4]
  oWsSPEDAdm:oWsEmpresa:cUF      := SM0->M0_ESTENT
  oWsSPEDAdm:oWsEmpresa:cCEP      := SM0->M0_CEPENT
  oWsSPEDAdm:oWsEmpresa:cCOD_MUN     := SM0->M0_CODMUN
  oWsSPEDAdm:oWsEmpresa:cCOD_PAIS    := "1058"
  oWsSPEDAdm:oWsEmpresa:cBAIRRO     := SM0->M0_BAIRENT
  oWsSPEDAdm:oWsEmpresa:cMUN      := SM0->M0_CIDENT
  oWsSPEDAdm:oWsEmpresa:cCEP_CP     := NIL
  oWsSPEDAdm:oWsEmpresa:cCP      := NIL
  oWsSPEDAdm:oWsEmpresa:cDDD      := Str(FisGetTel(SM0->M0_TEL)[2],3)
  oWsSPEDAdm:oWsEmpresa:cFONE     := AllTrim(Str(FisGetTel(SM0->M0_TEL)[3],15))
  oWsSPEDAdm:oWsEmpresa:cFAX      := AllTrim(Str(FisGetTel(SM0->M0_FAX)[3],15))
  oWsSPEDAdm:oWsEmpresa:cEMAIL     := UsrRetMail(RetCodUsr())
  oWsSPEDAdm:oWsEmpresa:cNIRE     := SM0->M0_NIRE
  oWsSPEDAdm:oWsEmpresa:dDTRE     := SM0->M0_DTRE
  oWsSPEDAdm:oWsEmpresa:cNIT      := SM0->( IF(M0_TPINSC==1,M0_CGC,"") )
  oWsSPEDAdm:oWsEmpresa:cINDSITESP    := ""
  oWsSPEDAdm:oWsEmpresa:cID_MATRIZ    := ""
  oWsSPEDAdm:oWsOutrasInscricoes:oWsInscricao := SPEDADM_ARRAYOFSPED_GENERICSTRUCT():New()
  oWsSPEDAdm:_URL        := cURL

  lMethodOk := oWsSPEDAdm:AdmEmpresas()

  DEFAULT lMethodOk := .F.
  
  IF !( lMethodOk )
   cError := IF( Empty( GetWscError(3) ) , GetWscError(1) , GetWscError(3) )
   BREAK
  EndIF
  
  cIdEnt := oWsSPEDAdm:cAdmEmpresasResult
  
 END SEQUENCE
 
 RestArea(aArea)

Return( cIdEnt )
      


Para obter o código completo, basta clicar aqui.
[]s
иαldσ

23 comentários:

  1. Saudações,

    Preciso recuperar alguns arquivos XML que não possuo.

    Se compreendi bem este webservice pode me ajudar a obter novamente os arquivos XML ?

    Grato e parabéns.

    ResponderExcluir
  2. Naldo, boa tarde!

    Parabéns pelo post e pelo ótimo blog! Sem parecer exagerado, o mercado precisa de mais consultores assim.

    Seu exeplo foi muito bom e já uso uma solução semelhante em alguns clientes. Estou precisando agora fazer com que o e-mail que é disparado para o cliente também contenha a DANFE em formato PDF. Você já fez isso? Tem uma idéia de qual caminho devo seguir?


    Um forte abraço!

    Douglas

    ResponderExcluir
  3. Boa Tarde,

    Primeiro, quero parabenizá-lo pelo conhecimento compartilhado. Realmente é de grande ajuda! Obrigado.

    Agora, minha dúvida. Neste programa, faz menção do include TRYEXCEPTION.CH. Não possuo esse arquivo. Vc teria como disponibilizá-lo?


    Cristiano

    ResponderExcluir
  4. Boa Tarde Naldo,

    Para chamar este WS, basta criar uma aplicação e chamar o seguinte método:
    u_wsGetXmlNFSe():New()
    E passar os parametros, seria isso?

    ResponderExcluir
  5. Cristiano,

    Você pode baixar o Header a partir desse link: https://docs.google.com/leaf?id=0BxUwnVt68UewY2JmMDZkMzQtYjZiMS00N2ZmLTg4ZjMtNzc3NTA1YTExZGI0&sort=name&layout=list&num=50

    []s
    иαldσ

    ResponderExcluir
  6. Boa Noite Naldo,

    Com respeito ao Ws da Nfe, consegui fazer. Está disponibilizando corretamente o xml.
    Agora, uma dúvida. Vc sabe se existe pelo menos um caminho das pedras para que se consiga imprimir uma pré-danfe, ou seja, gerar o xml antes de transmitir a nota para a sefaz?

    Obrigado!

    ResponderExcluir
  7. Boa Noite Naldo!

    Cara poderia me dar uma luz???

    Executei o exemplo citado só que ocorre erro no
    _cert e _privKey.



    Teria alguma sugestão?

    Segue a chamada.

    Find Function AttIsMemberOfNot Find Objects _CERT/_PRIVKEY

    Att.,

    ResponderExcluir
  8. O erro não é muito elucidativo. Pode fornecer + info?

    []s
    иαldσ

    ResponderExcluir
  9. Ola Naldo,

    voce tem um exemplo de client desse webservice?
    Preciso pegar esse XML e grava-lo em algum lugar.
    Criei um client atraves do IDE, mas nao estou sabendo como criar a user function para pegar esse XML e grava-lo em uma pasta qualquer.

    Poderia me ajudar

    Obrigado,

    Marcio

    ResponderExcluir
  10. Naldo,

    Da um help ai!!! Por favor!!!!!!!

    Obrigado,

    Marcio

    ResponderExcluir
  11. Mande um mail com sua necessidade que resolveremos juntos esse problema.

    []s
    иαldσ

    ResponderExcluir
  12. Bom dia Naldo,

    Consegui importar as XML's dos fornecedores para o Protheus, porém não consigo valida-las na SEFAZ, consigo somente recuperar xml entre outras coisas com as notas fiscais que emiti para um cliente. Tem jeito de validar a NFe dos fornecedores emitidas para mim atraves do AdvPL com WebService ?

    Abraços

    Daniel

    ResponderExcluir
  13. Bom dia pessoal;

    Alguem conseguiu desenvolver a ferramenta pra enviar o PDF por e-mail para os clientes.


    Abraços.
    Pedro Neto.

    ResponderExcluir
  14. Naldo, boa tarde....... como eu poderia chamar esse fonte... digo.. como chama-lo e na linha WSSERVICE u_wsGetXmlNFSe DESCRIPTION STR0001 NAMESPACE "http://localhost/naldo/ws/u_wsgetxmlnfse.apw" //"Serviço de consulta aos Documentos de Saída (NFSe)" pra onde aponta esse path? Poderia dar um exemplo?

    ResponderExcluir
  15. Alguns clientes estão retornando o método consultacontribuinte nil. porque isto?

    ResponderExcluir
  16. posso recuperar xml de nota fiscal de entrada também?

    ResponderExcluir
  17. posso recuperar xml de nota fiscal de entrada com este mesmo codigo?

    ResponderExcluir
  18. Prezados, boa tarde!
    Como faço para executa essa rotina?
    Tenho que criar um menu?

    ResponderExcluir
  19. Boa noite.
    é possível recuperar, com este mesmo fonte, os xml's de Documentos de Entrada e CT-e?

    ResponderExcluir
    Respostas
    1. bom dia Elias, vc conseguiu o algo sobre nota fiscal de entrada

      Excluir
    2. Alguém conseguiu algo para recuperar o xml de documentos de entrada? Se alguém conseguiu, poderia por gentileza entrar em contato pra me ajudar? marcelmuriae@hotmail.com
      Obrigado!

      Excluir
  20. Bom dia Naldo, e parabéns pelo seu ótimo trabalho.

    Eu desejo saber se existe uma forma de retornar os XML's de entradas emitidos contra um determinado CNPJ, ou seja, quero criar uma rotina que realize a baixa automática desses arquivos da SEFAZ passando como parâmetro o CNPJ da minha empresa. Se existir algo, pode compartilhar por favor!?

    Abraços.

    ResponderExcluir
  21. Bom dia

    Alguns já fez a impressão da danfe antes de transmitir?

    Tenho alguns fornecedor que não aceita a operação de garantia. Gerando o cancelamento e posterior fazendo em devolução.
    Abraços

    ResponderExcluir