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.