Current section
Files
Jump to
Current section
Files
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