Hoje vou mostrar como consultar dados de um endereço diretamente do CEP usando o AdvPL e a função FWRest.
Pessoal, o grande Thiago Andrade (LinkedIn), fez uma integração recentemente com a API gratuita da ViaCEP, que retorna informações através de um CEP disponibilizado.
Essa integração usa o FWRest com GET, confira o exemplo abaixo desenvolvido buscando informações do CEP 03.062-010.
//=================================================================================
/*/{Protheus.doc} zViaCep
[API.VIACEP] [GET] Conecta na Api gratuita da ViaCep para retornar dados de um Endereço
a partir do CEP.
Documentação: https://viacep.com.br/
Campos Disponiveis na API:
BAIRRO, CEP, COMPLEMENTO, GIA, IBGE, LOCALIDADE, LOGRADOURO, UF, UNIDADE
Uso: Incluir/Atualizar CC2 quando necessário
@author Thiago.Andrrade
@since 24/07/2020
/*/
//=================================================================================
User Function zViaCep()
Local aArea := GetArea()
Local aHeader := {}
Local cCep := '03062010'
Local cCodMun := ''
Local oRestClient := FWRest():New("https://viacep.com.br/ws")
Local oJsObj
aadd(aHeader,'User-Agent: Mozilla/4.0 (compatible; Protheus '+GetBuild()+')')
aAdd(aHeader,'Content-Type: application/json; charset=utf-8')
////////////////////////////////////////////////////////////////
//[GET] Consulta Dados na Api
oRestClient:setPath("/"+cCep+"/json/")
If oRestClient:Get(aHeader)
//Deserealiza o Json
FWJsonDeserialize(oRestClient:CRESULT,@oJsObj)
//Recebe Dados do Json
cCodMun := SubStr(oJsObj:IBGE,3,5)
/*oJsObj:BAIRRO
oJsObj:CEP
oJsObj:COMPLEMENTO
oJsObj:GIA
oJsObj:IBGE
oJsObj:LOCALIDADE
oJsObj:LOGRADOURO
oJsObj:UF
oJsObj:UNIDADE*/
FreeObj(oJsObj)
Else
ConOut("Erro Api ViaCep: "+oRestClient:GetLastError())
Endif
RestArea(aArea)
Return
Update – Janeiro de 2022
Pessoal, o grande Súlivan Simões ( LinkedIn ), fez uma adaptação na rotina, para utilizar JsonObject, e já retornando todos os campos. Segue abaixo a função:
#Include 'Totvs.ch'
/*/{Protheus.doc} zViaCep
[API.VIACEP] [GET] Conecta na Api gratuita da ViaCep para retornar dados de um Endereço
a partir do CEP.
Documentação: https://viacep.com.br/
Campos Disponiveis na API:
BAIRRO, CEP, COMPLEMENTO, GIA, IBGE, LOCALIDADE, LOGRADOURO, UF, UNIDADE
@type function
@author Thiago.Andrrade (autor da funcionalidade original)
@author Súlivan (resposável por adaptar o fonte)
@since 24/07/2020 [data da criação da rotina]
@example
u_zViaCep('37600000')
u_zViaCep('31015-104')
u_zViaCep('31015.025')
u_zViaCep('31010 514')
u_zViaCep(FwFldGet('A1_CEP'))
Exemplo para chamar em gatilhos do Protheus para preencher o código do municipio por exemplo
Regra: u_zViaCep(FwFldGet('A1_CEP'))['ibge']
@obs : MANUTENÇÕES FEITAS NO CÓDIGO:
--------------------------------------------------------------------------------------------
Data: 26/01/2021
Responsável: Súlivan
Log: * Retirado o uso da função FWJsonDeserialize que está em deprecate
* Rotina adaptada para receber parametros
* Adicionado return para retornar as informações concedidas pela API
* Incluso mais logs na rotina.
--------------------------------------------------------------------------------------------
/*/
User Function zViaCep(cCep)
Local aArea := GetArea()
Local aHeader := {}
Local oRestClient := FWRest():New("https://viacep.com.br/ws")
Local jJson := JsonObject():New()
Default cCep := ''
fConOut("[U_zViaCep] - Entrou na função que consulta as informações do endereco pelo CEP")
//Retira espaços,traços e pontos caso receba assim dos parametros
cCep := StrTran(StrTran(StrTran(cCep," ",""),"-",""),".","")
aadd(aHeader,'User-Agent: Mozilla/4.0 (compatible; Protheus '+GetBuild()+')')
aAdd(aHeader,'Content-Type: application/json; charset=utf-8')
//[GET] Consulta Dados na Api
oRestClient:setPath("/"+cCep+"/json/")
If oRestClient:Get(aHeader)
jJson:FromJson(oRestClient:CRESULT)
//Se as keys não existirem, cria elas com conteudo vazio.
jJson['cep'] := Iif( ValType(jJson['cep']) != "U", jJson['cep'] , "")
jJson['logradouro'] := Iif( ValType(jJson['logradouro']) != "U", jJson['logradouro'] , "")
jJson['complemento']:= Iif( ValType(jJson['complemento']) != "U", jJson['complemento'], "")
jJson['bairro'] := Iif( ValType(jJson['bairro']) != "U", jJson['bairro'] , "")
jJson['localidade'] := Iif( ValType(jJson['localidade']) != "U", jJson['localidade'] , "")
jJson['uf'] := Iif( ValType(jJson['uf']) != "U", jJson['uf'] , "")
jJson['ibge'] := Iif( ValType(jJson['ibge']) != "U", SubStr(jJson['ibge'],3,5), "")
jJson['gia'] := Iif( ValType(jJson['gia']) != "U", jJson['gia'] , "")
jJson['ddd'] := Iif( ValType(jJson['ddd']) != "U", jJson['ddd'] , "")
jJson['siafi'] := Iif( ValType(jJson['siafi']) != "U", jJson['siafi'] , "")
VarInfo("[U_zViaCep] - Resultado da consulta ->",jJson)
Else
fConOut("[U_zViaCep] - ** Erro Api ViaCep: "+oRestClient:GetLastError())
Endif
jJson['erro']:= Iif( ValType(jJson['cep']) == "U", "Api não retornou dados do cep: "+cValTochar(cCep) ,"")
fConOut("[U_zViaCep] - Finalizou na função que consulta as informações do endereco pelo CEP")
FreeObj(oRestClient)
RestArea(aArea)
Return jJson
Static Function fConOut(cLog)
Default cLog := "Log empty"
FwLogMsg("INFO", /*cTransactionId*/, "fConOut", FunName(), "", "01", cLog, 0, 0, {})
Return
Update – Junho de 2023
Recentemente um aluno ficou com uma dúvida de como aplicar o fonte acima em uma validação de campo, então detalhamos no procedimento abaixo:
1. Criar uma função, por exemplo u_zTeste()
2. Colocar essa função na validação de usuário (X3_VLDUSER) do campo cep (como no A1_CEP)
3. Dentro dessa função, acione a busca do cep do exemplo de Janeiro de 2022
4. Ai você atualiza os campos conforme o retorno da função
Abaixo um exemplo dos passos acima:
User Function zTeste()
Local aArea := FWGetArea()
Local lOk := .T.
//Busca o CEP conforme o campo informado
jJson := u_zViaCep(M->A1_CEP)
//Se não veio erro, atualiza os outros campos
If Type("jJson[erro]") == "U"
M->A1_END := jJson['logradouro']
//... Se for MVC, utilizar FWFldPut ou SetValue no Model
EndIf
FWRestArea(aArea)
Return lOk
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Como atualizo o campo de CLientes na SA1 ?
Direto na tela, você pode usar os Mashups – https://centraldeatendimento.totvs.com/hc/pt-br/articles/360025045012-MP-FRAME-Configura%C3%A7%C3%A3o-do-Mashups
Agora se for usar uma User Function que atualize, dentro do trecho do if (onde tem o comentário Recebe Dados do Json), ali você poderia alterar o campo da SA1.
Grande artigo.
Top!
Obrigado pelo feedback grande Súlivan.
Aquele abraço.
Olá pessoal, boa noite!! Fiz a consulta porém quando retorna letras com acento é como se o protheus trocasse o caracter.
Bom dia Renato.
Provavelmente é o encoding, tente converter a string com EncodeUTF8 / DecodeUTF8.
Abraços.