lib/requests/instruments/create_bank_account.ex

defmodule Requests.Instruments.CreateBankAccount do
    @moduledoc false
  alias Customers.{AccountHolder, Customer}
  alias Instruments.Bank

  @derive Jason.Encoder

  @account_types ["savings", "current", "cash"]

  @type t() :: %__MODULE__{
          type: String.t(),
          account_type: String.t(),
          account_number: String.t(),
          bank_code: String.t(),
          branch_code: String.t(),
          iban: String.t(),
          bban: String.t(),
          swift_bic: String.t(),
          currency: <<_::3>>,
          country: <<_::2>>,
          processing_channel_id: String.t(),
          account_holder: AccountHolder.t(),
          bank: Bank.t(),
          customer: Customer.t()
        }

  @enforce_keys [:type, :currency, :country, :bank_code]
  defstruct [
    :type,
    :account_type,
    :account_number,
    :bank_code,
    :branch_code,
    :iban,
    :bban,
    :swift_bic,
    :currency,
    :country,
    :processing_channel_id,
    :account_holder,
    :bank,
    :customer
  ]

  def build(%{type: type, currency: currency, country: country, bank_code: bank_code} = params)
      when is_binary(type) and is_binary(currency) and is_binary(country) and is_binary(bank_code) do
    case params[:account_type] in @account_types do
      true ->
        %__MODULE__{
          type: type,
          account_type: params[:account_type],
          account_number: params[:account_number],
          bank_code: bank_code,
          branch_code: params[:branch_code],
          iban: params[:iban],
          bban: params[:bban],
          swift_bic: params[:swift_bic],
          currency: currency,
          country: country,
          processing_channel_id: params[:processing_channel_id],
          account_holder: AccountHolder.build(params[:account_holder]),
          bank: Bank.build(params[:bank]),
          customer: Customer.build(params[:customer])
        }

      _ ->
        {:error, "Bank account type must be one of: #{Enum.join(@account_types, ", ")}"}
    end
  end

  def build(params) when is_map(params),
    do: {:error, "Bank account must have a type, currency, country, and bank_code"}

  def build(_), do: nil
end