defmodule Requests.Payments.BankPayout do
@moduledoc false
alias Requests.Payments.{Destinations, Senders}
alias Requests.Payments.Destinations.{BankAccount, Id}
alias Requests.Payments.Senders.{Corporate, Government, Individual}
@derive Jason.Encoder
@type instruction :: %{
purpose: String.t(),
charge_bearer: String.t(),
repair: String.t(),
scheme: String.t(),
quote_id: String.t()
}
@type t :: %__MODULE__{
source: %{amount: String.t(), type: String.t(), id: String.t()},
destination: Id.t() | BankAccount.t(),
amount: integer(),
currency: String.t(),
reference: String.t(),
billing_descriptor: %{reference: String.t()},
sender: Corporate.t() | Government.t() | Individual.t(),
instruction: instruction(),
processing_channel_id: String.t()
}
@enforce_keys [
:destination,
:source,
:amount,
:currency,
:billing_descriptor,
:processing_channel_id
]
defstruct [
:source,
:destination,
:amount,
:currency,
:reference,
:billing_descriptor,
:sender,
:instruction,
:processing_channel_id
]
def build(
%{
destination: destination,
source: source,
amount: amount,
currency: currency,
billing_descriptor: %{reference: reference}
} = params
)
when is_map(destination) and is_map(source) and is_integer(amount) and is_binary(currency) and
is_binary(reference) do
%__MODULE__{
source: build_source(params[:source]),
destination: Destinations.build_bank_payout_destination(params[:destination]),
amount: params[:amount],
currency: params[:currency],
reference: params[:reference],
billing_descriptor: build_billing_descriptor(%{reference: reference}),
sender: Senders.build_bank_payout_sender(params[:sender]),
instruction: build_instruction(params[:instruction]),
processing_channel_id: params[:processing_channel_id]
}
end
def build(params) when is_map(params),
do:
{:error,
"Bank payout must have destination, source, amount, currency and billing_descriptor"}
def build(_), do: {:error, "params must be a map"}
defp build_billing_descriptor(%{reference: reference}) when reference not in [nil, ""],
do: %{reference: reference}
defp build_billing_descriptor(_), do: nil
defp build_instruction(params) when is_map(params) do
%{
purpose: params[:purpose],
charge_bearer: params[:charge_bearer],
repair: params[:repair],
scheme: params[:scheme],
quote_id: params[:quote_id]
}
end
defp build_instruction(_), do: nil
defp build_source(%{amount: _amount, type: _type, id: _id} = source), do: source
defp build_source(_), do: {:error, "BankPayout source must have amount, type, and id"}
end