Skip to main content

lib/treasury_prime/business_application.ex

defmodule TreasuryPrime.BusinessApplication do
  @moduledoc """
  Captures identifying/KYB information for a business as part of opening a
  business account, including its beneficial owners, control persons, and
  signers (each represented by a `TreasuryPrime.PersonApplication`). Once
  approved, `business_id` is populated with the resulting
  `TreasuryPrime.Business`.

  ## Creating one

      {:ok, business_app} =
        TreasuryPrime.BusinessApplication.create(client, %{
          name: "Acme Goods Inc",
          legal_structure: "llc",
          tin: "11-3344555",
          established_on: "2014-08-01",
          incorporation_state: "DE",
          description: "Buying and selling of goods",
          naics: "42",
          naics_description: "Wholesale Trade",
          phone_number: "4155551111",
          physical_address: %{
            street_line_1: "115 West St",
            city: "Benicia",
            state: "CA",
            postal_code: "94510"
          },
          person_applications: [
            %{id: ceo_person_app.id, roles: ["signer"], ownership_percentage: 60, title: "CEO"},
            %{id: cfo_person_app.id, roles: ["control_person", "signer"], ownership_percentage: 20, title: "CFO"}
          ]
        })

  At least one associated person application must carry the
  `"control_person"` role, per FinCEN Customer Due Diligence (CDD) rules
  for legal entity customers.
  """

  use TreasuryPrime.Resource

  alias TreasuryPrime.{Client, Error, Page, Resource}

  @resource_path "apply/business_application"

  @type person_application_ref :: %{
          id: String.t(),
          roles: [String.t()],
          ownership_percentage: number() | nil,
          title: String.t() | nil
        }

  @type t :: %__MODULE__{
          id: String.t() | nil,
          bank_id: String.t() | nil,
          bankdata: map() | nil,
          business_id: String.t() | nil,
          dba: String.t() | nil,
          description: String.t() | nil,
          established_on: String.t() | nil,
          incorporation_state: String.t() | nil,
          legal_structure: String.t() | nil,
          mailing_address: map() | nil,
          naics: String.t() | nil,
          naics_description: String.t() | nil,
          name: String.t() | nil,
          person_applications: [person_application_ref()] | nil,
          phone_number: String.t() | nil,
          physical_address: map() | nil,
          status: String.t() | nil,
          tin: String.t() | nil,
          userdata: map() | nil,
          created_at: String.t() | nil,
          updated_at: String.t() | nil
        }

  defstruct [
    :id,
    :bank_id,
    :bankdata,
    :business_id,
    :dba,
    :description,
    :established_on,
    :incorporation_state,
    :legal_structure,
    :mailing_address,
    :naics,
    :naics_description,
    :name,
    :person_applications,
    :phone_number,
    :physical_address,
    :status,
    :tin,
    :userdata,
    :created_at,
    :updated_at
  ]

  @fields ~w(
    id bank_id bankdata business_id dba description established_on incorporation_state
    legal_structure mailing_address naics naics_description name person_applications
    phone_number physical_address status tin userdata created_at updated_at
  )a
  def __fields__, do: @fields

  @doc """
  Lists business applications.

  ## Filterable params

  `status`, `tin`.
  """
  @spec list(Client.t(), map()) :: {:ok, Page.t()} | {:error, Error.t()}
  def list(client, params \\ %{}), do: Resource.list(client, @resource_path, __MODULE__, params)

  @spec list!(Client.t(), map()) :: Page.t()
  def list!(client, params \\ %{}), do: Resource.list!(client, @resource_path, __MODULE__, params)

  @doc "Fetches a single business application by id."
  @spec get(Client.t(), String.t()) :: {:ok, t()} | {:error, Error.t()}
  def get(client, id), do: Resource.get(client, @resource_path, __MODULE__, id)

  @spec get!(Client.t(), String.t()) :: t()
  def get!(client, id), do: Resource.get!(client, @resource_path, __MODULE__, id)

  @doc """
  Creates a business application. Required: `name`, `legal_structure`,
  `tin`, `physical_address`, `person_applications` (with at least one
  `"control_person"`).
  """
  @spec create(Client.t(), map(), keyword()) :: {:ok, t()} | {:error, Error.t()}
  def create(client, params, opts \\ []),
    do: Resource.create(client, @resource_path, __MODULE__, params, opts)

  @spec create!(Client.t(), map(), keyword()) :: t()
  def create!(client, params, opts \\ []),
    do: Resource.create!(client, @resource_path, __MODULE__, params, opts)

  @doc "Updates a business application (only possible before its account application is approved)."
  @spec update(Client.t(), String.t(), map()) :: {:ok, t()} | {:error, Error.t()}
  def update(client, id, params),
    do: Resource.update(client, @resource_path, __MODULE__, id, params)

  @spec update!(Client.t(), String.t(), map()) :: t()
  def update!(client, id, params),
    do: Resource.update!(client, @resource_path, __MODULE__, id, params)
end