Current section
Files
Jump to
Current section
Files
lib/bali.ex
defmodule Bali do
@moduledoc """
Módulo encargado de realizar las validaciones de identificadores personales
y fiscales de México, Colombia, España, Portugal, Italia y Brasil
"""
alias Bali.Validators.{
Portugal,
Brazil,
Colombia,
Italy,
Mexico,
Spain
}
@tax_documents %{
mx: ["rfc"],
co: ["nit"],
es: ["nif"],
it: ["cf"],
pt: ["nif"],
br: ["cnpj"]
}
@personal_documents %{
mx: ["curp"],
co: ["cc", "ce", "passport", "password"],
es: ["dni", "nie"],
it: ["cie", "cf"],
pt: ["nif"],
br: ["cpf"]
}
@doc """
Valida el identificador personal o fiscal segun el país(mx,co,es,pt,it,br) y tipo
## Ejemplos:
```elixir
# México
iex> Bali.validate(:mx, :curp, "ROCE000131HNLDNDA0")
{:ok, "ROCE000131HNLDNDA0"}
iex> Bali.validate(:mx, :curp, "BADD110313HCMLNS0Q")
{:error, "CURP inválido"}
iex> Bali.validate(:mx, :rfc, "AAFI7906296J1")
{:ok, "AAFI7906296J1"}
iex> Bali.validate(:mx, :rfc, "OIBD890101MQB")
{:error, "RFC inválido"}
# Colombia
iex> Bali.validate(:co, :cc, "123456789")
{:ok, "123456789"}
iex> Bali.validate(:co, :cc, "12345678912")
{:error, "CC inválida"}
iex> Bali.validate(:co, :ce, "123456")
{:ok, "123456"}
iex> Bali.validate(:co, :ce, "1234567")
{:error, "CE inválida"}
iex> Bali.validate(:co, :nit, "123456-1")
{:ok, "123456-1"}
iex> Bali.validate(:co, :nit, "123456-12")
{:error, "NIT inválido"}
# España
iex> Bali.validate(:es, :dni, "46324571H")
{:ok, "46324571H"}
iex> Bali.validate(:es, :dni, "46324571I")
{:error, "DNI inválido"}
iex> Bali.validate(:es, :nie, "Z1234567R")
{:ok, "Z1234567R"}
iex> Bali.validate(:es, :nie, "Z1234567I")
{:error, "NIE inválido"}
# Italia
iex> Bali.validate(:it, :cf, "VRDGPP13R10B293P")
{:ok, "VRDGPP13R10B293P"}
iex> Bali.validate(:it, :cf, "VRDGPP13R10B29BP")
{:error, "CF inválido"}
# Portugal
iex> Bali.validate(:pt, :nif, "123456789")
{:ok, "123456789"}
iex> Bali.validate(:pt, :nif, "12345678")
{:error, "NIF inválido"}
# Brasil
iex> Bali.validate(:br, :cpf, "000.000.000-00")
{:ok, "000.000.000-00"}
iex> Bali.validate(:br, :cpf, "000.000.000-000")
{:error, "CPF inválido"}
iex> Bali.validate(:br, :cnpj, "00.000.000/0000-00")
{:ok, "00.000.000/0000-00"}
iex> Bali.validate(:br, :cnpj, "00.000.000/0000-000")
{:error, "CNPJ inválido"}
```
"""
@spec validate(atom, atom, String.t()) :: {:ok, String.t()} | {:error, String.t()}
def validate(country, document_type, value) do
clean_value = clean_string(value)
do_validate(country, document_type, clean_value)
end
@spec do_validate(atom, atom, String.t()) :: {:ok, String.t()} | {:error, String.t()}
defp do_validate(:pt, document_type, value) do
Portugal.validate(document_type, value)
end
defp do_validate(:es, document_type, value) do
Spain.validate(document_type, value)
end
defp do_validate(:co, document_type, value) do
Colombia.validate(document_type, value)
end
defp do_validate(:mx, document_type, value) do
Mexico.validate(document_type, value)
end
defp do_validate(:it, document_type, value) do
Italy.validate(document_type, value)
end
defp do_validate(:br, document_type, value) do
Brazil.validate(document_type, value)
end
defp do_validate(country, _document_type, _value) do
{:error, "País #{country} no soportado"}
end
# Elimina los caracteres en blanco de la cadena de entrada
@spec clean_string(String.t()) :: String.t()
defp clean_string(value) do
String.replace(value, " ", "")
end
@doc """
Obtiene la lista de tipos de documentos soportados
"""
def get_document_types do
["DNI", "NIE", "NIF", "RFC", "CURP", "CC", "CE", "NIT", "CPF", "CNPJ", "PASSPORT", "PASSWORD"]
end
@doc """
Revisa si el tipo documento fiscal recibido se encuentra en la lista de documentos
válidos y verifica que su valor sea correcto
"""
@spec validate_fiscal_document(atom, atom, String.t()) ::
{:ok, String.t()} | {:error, String.t()}
def validate_fiscal_document(country, document_type, value) do
case Map.get(@tax_documents, country) do
nil ->
{:error, "País no soportado"}
tax_documents_per_country ->
if Enum.member?(tax_documents_per_country, Atom.to_string(document_type)) do
validate(country, document_type, value)
else
{:error, "Documento fiscal inválido para el país: #{country}"}
end
end
end
@doc """
Revisa si el tipo documento personal recibido se encuentra en la lista de documentos
válidos y verifica que su valor sea correcto
"""
@spec validate_personal_document(atom, atom, String.t()) ::
{:ok, String.t()} | {:error, String.t()}
def validate_personal_document(country, document_type, value) do
case Map.get(@personal_documents, country) do
nil ->
{:error, "País no soportado"}
personal_documents_per_country ->
if Enum.member?(personal_documents_per_country, Atom.to_string(document_type)) do
validate(country, document_type, value)
else
{:error, "Documento personal inválido para el país: #{country}"}
end
end
end
end