if Code.ensure_compiled(Ecto) do defmodule Brcpfcnpj.Changeset do @moduledoc """ Define funções para serem utilizadas em conjunto com a API de changeset do Ecto. """ @type changeset :: Ecto.Changeset.t() @type error :: {atom, error_message} @type error_message :: String.t() | {String.t(), Keyword.t()} @doc """ Valida se essa mudança é um cnpj válido. Aceita um ou mais fields ## Options * `:message` - A mensagem em caso de erro, o default é "Invalid Cnpj" ## Examples validate_cnpj(changeset, :cnpj) validate_cnpj(changeset, [:cnpj, :other_cnpj]) """ @spec validate_cnpj(changeset(), atom() | list(), Keyword.t()) :: changeset() def validate_cnpj(changeset, field), do: validate_cnpj(changeset, field, []) def validate_cnpj(changeset, field, opts) when is_atom(field) do validate(changeset, field, fn value -> if Brcpfcnpj.cnpj_valid?(value) do [] else [{field, message(opts, {"Invalid Cnpj", validation: :cnpj})}] end end) end def validate_cnpj(changeset, fields, opts) when is_list(fields) do Enum.reduce(fields, changeset, fn field, acc_changeset -> validate_cnpj(acc_changeset, field, opts) end) end @doc """ Valida se essa mudança é um cpf válido. Aceita um ou mais fields ## Options * `:message` - A mensagem em caso de erro, o default é "Invalid Cpf" ## Examples validate_cpf(changeset, :cpf) validate_cpf(changeset, [:cpf, :cnpj]) """ @spec validate_cpf(changeset(), atom() | list(), Keyword.t()) :: changeset() def validate_cpf(changeset, field), do: validate_cpf(changeset, field, []) def validate_cpf(changeset, field, opts) when is_atom(field) do validate(changeset, field, fn value -> if Brcpfcnpj.cpf_valid?(value) do [] else [{field, message(opts, {"Invalid Cpf", validation: :cpf})}] end end) end def validate_cpf(changeset, fields, opts) when is_list(fields) do Enum.reduce(fields, changeset, fn field, acc_changeset -> validate_cpf(acc_changeset, field, opts) end) end defp validate(changeset, field, validator) do %{changes: changes, errors: errors} = changeset value = Map.get(changes, field) new = if is_nil(value), do: [], else: validator.(value) case new do [] -> changeset [_ | _] -> %{changeset | errors: new ++ errors, valid?: false} end end defp message(opts, default) do message = Keyword.get(opts, :message, default) format_message(message) end defp format_message(msg = {_, _}), do: msg defp format_message(msg) when is_binary(msg), do: {msg, []} end end