lib/customers/account_holder.ex

defmodule Customers.AccountHolder do
    @moduledoc false

  alias Customers.{BillingAddress, Phone}

  import Utilities, only: [atomize_keys: 1]

  @derive Jason.Encoder

  @type t() :: %__MODULE__{
          type: String.t(),
          first_name: String.t(),
          last_name: String.t(),
          company_name: String.t(),
          tax_id: String.t(),
          date_of_birth: String.t(),
          country_of_birth: <<_::2>>,
          residential_status: String.t(),
          billing_address: BillingAddress.t(),
          phone: Phone.t(),
          identification: %{
            type: String.t(),
            number: String.t(),
            issuing_country: <<_::2>>
          },
          email: String.t()
        }

  defstruct [
    :type,
    :first_name,
    :last_name,
    :company_name,
    :tax_id,
    :date_of_birth,
    :country_of_birth,
    :residential_status,
    :billing_address,
    :phone,
    :identification,
    :email
  ]

  def build(raw_params) when is_map(raw_params) do
    params = atomize_keys(raw_params)

    %__MODULE__{
      type: params[:type],
      first_name: params[:first_name],
      last_name: params[:last_name],
      company_name: params[:company_name],
      tax_id: params[:tax_id],
      date_of_birth: params[:date_of_birth],
      country_of_birth: params[:country_of_birth],
      residential_status: params[:residential_status],
      billing_address: BillingAddress.build(params[:billing_address]),
      phone: Phone.build(params[:phone]),
      identification: build_identification(params[:identification]),
      email: params[:email]
    }
  end

  def build(nil), do: nil

  defp build_identification(raw_params) when is_map(raw_params) do
    params = atomize_keys(raw_params)

    %{
      type: params[:type],
      number: params[:number],
      issuing_country: params[:issuing_country]
    }
  end

  defp build_identification(_), do: nil
end