Current section
Files
Jump to
Current section
Files
lib/api_brasil/consulta.ex
defmodule ApiBrasil.Consulta do
@moduledoc """
Monta o body das consultas por crédito (`POST /consulta/{servico}/credits`).
O campo `tipo` define o produto consultado — os tipos conhecidos estão em
`ApiBrasil.Generated.Catalog.consulta_tipos/0`.
alias ApiBrasil.{Consulta, Data}
"lista-socios"
|> Consulta.new()
|> Consulta.field("cnpj", "00000000000000")
|> then(&Data.Consulta.cnpj(client, &1))
# modo homologação (sandbox, sem cobrança)
"serasa-score-pj"
|> Consulta.new()
|> Consulta.homolog(true)
|> Consulta.field("cnpj", "00000000000000")
Qualquer função de serviço aceita a struct diretamente no lugar do mapa.
"""
@type t :: %__MODULE__{
tipo: String.t() | nil,
homolog: boolean(),
lite: boolean(),
agrupados: [String.t()],
extra: [String.t()],
fields: map()
}
@doc """
Body de uma consulta por crédito.
- `:tipo` — tipo/serviço da consulta (ex: `"lista-socios"`, `"serasa-score-pf"`);
- `:homolog` — modo homologação (sandbox, sem cobrança), quando suportado;
- `:lite` — versão reduzida da consulta, quando suportada;
- `:agrupados` — consultas agrupadas;
- `:extra` — serviços extras;
- `:fields` — campos específicos do produto (ex: `%{"cnpj" => "..."}`).
"""
defstruct tipo: nil,
homolog: false,
lite: false,
agrupados: [],
extra: [],
fields: %{}
@doc "Cria uma consulta do `tipo` informado."
@spec new(String.t() | nil, keyword()) :: t()
def new(tipo \\ nil, fields \\ []) do
struct!(%__MODULE__{tipo: tipo}, fields)
end
@doc "Ativa/desativa o modo homologação."
@spec homolog(t(), boolean()) :: t()
def homolog(%__MODULE__{} = consulta, homolog \\ true), do: %{consulta | homolog: homolog}
@doc "Ativa/desativa a versão reduzida da consulta."
@spec lite(t(), boolean()) :: t()
def lite(%__MODULE__{} = consulta, lite \\ true), do: %{consulta | lite: lite}
@doc "Define as consultas agrupadas."
@spec agrupados(t(), [String.t()]) :: t()
def agrupados(%__MODULE__{} = consulta, agrupados) when is_list(agrupados) do
%{consulta | agrupados: Enum.map(agrupados, &to_string/1)}
end
@doc "Define os serviços extras."
@spec extra(t(), [String.t()]) :: t()
def extra(%__MODULE__{} = consulta, extra) when is_list(extra) do
%{consulta | extra: Enum.map(extra, &to_string/1)}
end
@doc "Adiciona um campo do produto."
@spec field(t(), String.t() | atom(), term()) :: t()
def field(%__MODULE__{} = consulta, key, value) do
%{consulta | fields: Map.put(consulta.fields, to_string(key), value)}
end
@doc "Mescla um mapa/keyword nos campos do produto."
@spec fields(t(), map() | keyword()) :: t()
def fields(%__MODULE__{} = consulta, fields) when is_map(fields) or is_list(fields) do
extra = Map.new(fields, fn {key, value} -> {to_string(key), value} end)
%{consulta | fields: Map.merge(consulta.fields, extra)}
end
@doc "Monta o body da consulta."
@spec to_map(t()) :: map()
def to_map(%__MODULE__{} = consulta) do
%{}
|> put_unless_nil("tipo", consulta.tipo)
|> put_when(consulta.homolog, "homolog", true)
|> put_when(consulta.lite, "lite", true)
|> put_when(consulta.agrupados != [], "agrupados", consulta.agrupados)
|> put_when(consulta.extra != [], "extra", consulta.extra)
|> Map.merge(consulta.fields)
end
defp put_unless_nil(map, _key, nil), do: map
defp put_unless_nil(map, key, value), do: Map.put(map, key, value)
defp put_when(map, false, _key, _value), do: map
defp put_when(map, true, key, value), do: Map.put(map, key, value)
end