ukraine-taxid-ex/lib/ukraine_taxid_ex/edrpou/validator.ex

61 lines
2.1 KiB
Elixir

defmodule UkraineTaxidEx.Edrpou.Validator do
@moduledoc """
Functions for validating EDRPOU number format and checksum.
This module provides validation functions to verify if an EDRPOU number meets the standard requirements including length and checksum validation.
"""
import UkraineTaxidEx.Commons, only: [digits: 1, digits_and_check_digit: 1, error: 1, ok: 1]
import UkraineTaxidEx.Edrpou, only: [length: 0]
import UkraineTaxidEx.Edrpou.CheckSum, only: [check_sum: 1]
@doc """
Validates an EDRPOU number to check if it meets length requirements and has a valid checksum.
Returns:
* `{:ok, edrpou}` if validation successful
* `{:error, :length_too_short}` if shorter than required length
* `{:error, :length_too_long}` if longer than required length
* `{:error, :invalid_checksum}` if checksum is invalid
"""
@spec validate(String.t()) ::
{:ok, String.t()}
| {:error, :length_too_short | :length_too_long | :invalid_length | :invalid_checksum}
def validate(edrpou) do
cond do
violates_length_too_short?(edrpou) -> error(:length_too_short)
violates_length_too_long?(edrpou) -> error(:length_too_long)
violates_checksum?(edrpou) -> error(:invalid_checksum)
true -> ok(edrpou)
end
end
@doc "Check whether a given EDRPOU violates the required length"
@spec violates_length?(String.t()) :: boolean
def violates_length?(edrpou),
do: String.length(edrpou) != length()
@doc "Check whether a given EDRPOU too short"
@spec violates_length_too_short?(String.t()) :: boolean
def violates_length_too_short?(edrpou),
do: String.length(edrpou) < length()
@doc "Check whether a given EDRPOU too long"
@spec violates_length_too_long?(String.t()) :: boolean
def violates_length_too_long?(edrpou),
do: String.length(edrpou) > length()
@doc "Check whether a given EDRPOU has correct checksum"
@spec violates_checksum?(String.t()) :: boolean
def violates_checksum?(edrpou) do
{digits, check_digit} =
edrpou
|> digits()
|> digits_and_check_digit()
check_sum = check_sum(digits)
check_sum != check_digit
end
end