Packages

GraphQL API used at enderecify.com

Current section

Files

Jump to
enderecify_api lib resolver logradouro.ex
Raw

lib/resolver/logradouro.ex

defmodule EnderecifyApi.Resolver.Logradouro do
use EnderecifyApi, :graphql_resolver
alias EnderecifyApi.Schema.{Logradouro, LogradouroSearch}
def handle(%{cep: cep}, _) do
{
:ok,
with_cep(cep) |> by_nome() |> repo().all()
}
end
def handle(%{busca: nil}, _), do: {:error, "Especifique uma busca"}
def handle(%{busca: ""}, _), do: {:error, "Especifique uma busca"}
def handle(%{busca: busca} = params, _) do
{
:ok,
normalize_address(busca)
|> matching_address()
|> with_localidade(params[:localidade_id])
|> all_logradouros_from_search()
}
end
def handle(_, _), do: {:error, "Especifique uma busca"}
# return Ex: Rua Nome Da Rua, Centro
def linha1(logradouro, _args, _ctx) do
bairro = bairro(logradouro).nome
street_name = [logradouro.tipo, logradouro.nome] |> join_address(" ")
{
:ok,
[street_name, bairro]
|> join_address()
}
end
# return Ex: 45678-910, Cidade, Estado
def linha2(logradouro, _args, _ctx) do
localidade = localidade(logradouro)
{
:ok,
[formatted_cep(logradouro.cep), localidade.nome, localidade.sigla_estado]
|> join_address()
}
end
def formatted_nome(%{tipo: tipo, nome: nome}, _args, _ctx) do
{:ok, "#{tipo} #{nome}"}
end
def formatted_cep(logradouro, _args, _ctx) do
{:ok, formatted_cep(logradouro.cep)}
end
defp formatted_cep(cep) do
cep
|> String.graphemes()
|> List.insert_at(5, "-")
|> Enum.join()
end
defp with_cep(query \\ Logradouro, cep) do
digits = cep |> String.replace(~r/[^\d]/, "")
query
|> where(cep: ^digits)
|> limit(6)
end
defp with_localidade(query, localidade_id) do
case localidade_id do
nil -> query
_ -> query |> where(localidade_id: ^localidade_id)
end
end
defp matching_address(text) do
LogradouroSearch
|> where(fragment("readings &^ ?", ^text))
|> order_by(fragment("pgroonga_score(tableoid, ctid) DESC"))
end
defp all_logradouros_with_ids(logradouros_ids) do
from(l0 in Logradouro, where: l0.id in ^logradouros_ids)
|> repo().all()
end
defp all_logradouros_from_search(query) do
query
|> limit(6)
|> repo().all()
|> Enum.map(&Map.get(&1, :record_id))
|> all_logradouros_with_ids()
end
defp by_nome(query) do
query
|> order_by(:nome)
end
defp bairro(logradouro) do
repo().preload(logradouro, :bairro).bairro
end
defp localidade(logradouro) do
repo().preload(logradouro, :localidade).localidade
end
defp join_address(array, join_with \\ ", ") do
array
|> Enum.reject(&is_nil(&1))
|> Enum.join(join_with)
end
def normalize_address(string) do
string
|> String.downcase()
|> String.normalize(:nfd)
|> String.replace(~r/[^A-Za-z\s\d]/u, "")
end
end