Packages

Elixir client for Polish GUS BIR (Baza Internetowa Regon) service. Search and retrieve business entity data from CEIDG, KRS, and RSPO registries.

Current section

Files

Jump to
gusex lib gusex validators nip.ex
Raw

lib/gusex/validators/nip.ex

defmodule Gusex.Validators.Nip do
@moduledoc """
Module for handling Polish NIP (Tax Identification Number) validation. This
module provides functions to validate NIP numbers according to the official
rules. NIP is a 10-digit number where the last digit is a checksum calculated
from the first nine digits. The checksum is calculated using a specific set of
factors applied to the first nine digits.
"""
@factors [6, 5, 7, 2, 3, 4, 5, 6, 7]
@doc """
Validates a NIP number.
Accepts a string representation of the NIP.
Returns `true` if valid, `false` otherwise.
"""
@spec valid?(String.t()) :: boolean()
def valid?(nip) when is_binary(nip) do
digits = Regex.replace(~r/[\s\-−‒–—‒—―]/u, nip, "")
cond do
String.length(digits) != 10 -> false
not String.match?(digits, ~r/^\d{10}$/) -> false
true -> check(digits)
end
end
# def valid?(nip) when is_integer(nip), do: valid?(String.pad_leading(Integer.to_string(nip), 10, "0"))
def valid?(_), do: false
defp check(<<nip::binary-size(10)>>) do
sum = @factors
|> Enum.with_index()
|> Enum.reduce(0, fn {factor, idx}, acc ->
acc + factor * (String.at(nip, idx) |> String.to_integer())
end)
checksum = rem(sum, 11)
checksum != 10 and checksum == String.at(nip, 9) |> String.to_integer()
end
end