Current section
Files
Jump to
Current section
Files
lib/code/builder.ex
defmodule ExPIX.Code.Builder do
@moduledoc """
Functions to build the string code
"""
alias ExPIX.Data.{
Additional,
Static,
StaticAccount,
}
alias ExPIX.Code.{
Helpers,
Validation,
}
def build(%Static{} = info) do
Static.ids()
|> Enum.reduce_while({:ok, ""}, & do_build(&1, &2, info))
|> case do
{:error, _reason} = error -> error
{:ok, string_code} -> {:ok, add_crc(string_code)}
end
end
defp do_build({id, field}, previous_string, info) do
value = Map.get(info, field, "")
with true <- Validation.validate_field(field, value),
{:ok, new_code} <- build_reduce(id, previous_string, value)
do
{:cont, {:ok, new_code}}
else
false -> {:halt, {:error, "The #{Atom.to_string(field)} is invalid"}}
{:error, _reason} = error -> {:halt, error}
end
end
defp build_reduce("26" = id, {:ok, previous_string}, account_info_value) do
build_secondary_struct(StaticAccount.ids(), id, previous_string, account_info_value)
end
defp build_reduce("62" = id, {:ok, previous_string}, additional_info_value) do
build_secondary_struct(Additional.ids(), id, previous_string, additional_info_value)
end
defp build_reduce(id, {:ok, previous_string}, value) do
Helpers.build_new_line(id, previous_string, value, Helpers.build_length(value))
end
defp build_secondary_struct(ids, struct_id, previous_string, info) do
ids
|> Enum.reduce_while({:ok, ""}, & do_build(&1, &2, info))
|> case do
{:ok, value} ->
Helpers.build_new_line(struct_id, previous_string, value, Helpers.build_total_struct_length(info))
{:error, _reason} = error ->
error
end
end
defp add_crc(string) do
without_crc = string <> "6304"
without_crc <> (without_crc |> CRC.ccitt_16() |> Integer.to_string(16))
end
end