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

87 lines
3.1 KiB
Elixir
Raw Normal View History

defmodule UkraineTaxidEx.Edrpou.Parser do
2024-12-12 06:32:31 +00:00
@moduledoc """
Parser module for EDRPOU (Unified State Register of Ukrainian Enterprises and Organizations) codes.
Handles validation and structure creation for EDRPOU codes with additional options for normalization and cleaning.
"""
alias UkraineTaxidEx.Edrpou
import UkraineTaxidEx.Edrpou, only: [length: 0]
import UkraineTaxidEx.Edrpou.CheckSum, only: [check_sum: 1]
2024-12-12 06:32:31 +00:00
import UkraineTaxidEx.Edrpou.Validator, only: [validate: 1]
import UkraineTaxidEx.Commons, only: [check_digit: 1, digits: 1, digits: 3, undigits: 1, ok: 1]
use UkraineTaxidEx.BaseParser
2024-12-12 06:32:31 +00:00
@type edrpou_string() :: String.t()
@type edrpou_string_or_ok() :: edrpou_string() | {:ok, edrpou_string()}
@type edrpou() :: Edrpou.t()
@type edrpou_or_error() ::
{:ok, Edrpou.t()}
| {:error,
:length_too_short
| :length_too_long
| :invalid_checksum}
@impl BaseParser
@doc """
2024-12-12 17:05:18 +00:00
Parses an EDRPOU code string into a structured format (clean and normalize, validate and decompose).
2024-12-12 06:32:31 +00:00
Options:
- normalize?: When true, pads string to full EDRPOU length. Defaults to false.
- clean?: When true, removes non-digit characters before processing. Defaults to false.
Returns {:ok, %Edrpou{}} for valid codes or {:error, reason} for invalid.
## Examples
iex> UkraineTaxidEx.Edrpou.Parser.parse("00032112")
{:ok, %UkraineTaxidEx.Edrpou{code: "00032112", check_digit: 2, check_sum: 2}}
iex> UkraineTaxidEx.Edrpou.Parser.parse({:ok, "00032112"})
{:ok, %UkraineTaxidEx.Edrpou{code: "00032112", check_digit: 2, check_sum: 2}}
iex> UkraineTaxidEx.Edrpou.Parser.parse("32129", normalize?: true)
{:ok, %UkraineTaxidEx.Edrpou{code: "00032129", check_digit: 9, check_sum: 9}}
iex> UkraineTaxidEx.Edrpou.Parser.parse("9 30test62 78", normalize?: true, clean?: true)
{:ok, %UkraineTaxidEx.Edrpou{code: "09306278", check_digit: 8, check_sum: 8}}
iex> UkraineTaxidEx.Edrpou.Parser.parse("123")
{:error, :length_too_short}
iex> UkraineTaxidEx.Edrpou.Parser.parse("123456789")
{:error, :length_too_long}
iex> UkraineTaxidEx.Edrpou.Parser.parse("123", normalize?: true)
{:error, :invalid_checksum}
"""
@spec parse(data :: edrpou_string_or_ok, options :: BaseParser.options()) ::
edrpou_or_error()
def parse(data, options \\ [normalize?: false, clean?: false])
def parse({:ok, edrpou_string}, options), do: parse(edrpou_string, options)
def parse({:error, error}, _options), do: {:error, error}
def parse(edrpou_string, options) do
length = (Keyword.get(options, :normalize?, false) && length()) || 0
clean? = Keyword.get(options, :clean?, false)
edrpou_string
|> digits(length, clean?)
|> undigits()
|> validate()
|> generate_edrpou()
end
defp generate_edrpou({:error, error}), do: {:error, error}
defp generate_edrpou({:ok, edrpou_string}) do
digits = digits(edrpou_string)
2024-12-12 06:32:31 +00:00
%{code: edrpou_string, check_sum: check_sum(digits), check_digit: check_digit(digits)}
|> create_struct()
|> ok()
end
defp create_struct(map), do: struct(Edrpou, map)
end