lib/pix_balance/pix_balance.ex

defmodule StarkInfra.PixBalance do
  alias __MODULE__, as: PixBalance
  alias StarkInfra.Utils.Rest
  alias StarkInfra.Utils.Check
  alias StarkInfra.User.Project
  alias StarkInfra.User.Organization
  alias StarkInfra.Error

  @moduledoc """
  Groups PixBalance related functions
  """

  @doc """
  The PixBalance struct displays the current balance of the Workspace, which
  is the result of the sum of all transactions within this Workspace.
  The balance is never generated by the user, but it can be retrieved to
  see the available information.

  ## Attributes (return-only):
    - `:id` [string]: unique id returned when Balance is created. ex: "5656565656565656"
    - `:amount` [integer]: current balance amount of the Workspace in cents. ex: 200 (= R$ 2.00)
    - `:currency` [string]: currency of the current Workspace. Expect others to be added eventually. ex: "BRL"
    - `:updated` [DateTime]: latest update DateTime for the PixBalance. ex: ~U[2020-3-10 10:30:0:0]
  """
  defstruct [:id, :amount, :currency, :updated]

  @type t() :: %__MODULE__{}

  @doc """
  Receive the PixBalance struct linked to your Workspace in the Stark Infra API

  ## Options:
    - `:user` [Organization/Project, default nil]: Organization or Project struct returned from StarkInfra.project(). Only necessary if default project or organization has not been set in configs.

  ## Return:
    - list of PixBalance struct with updated attributes
  """
  @spec get(
    user: Project.t() | Organization.t() | nil
  ) ::
    {:ok, PixBalance.t()} |
    {:error, [error: Error.t()]}
  def get(options \\ []) do
    case Rest.get_list(resource(), options) |> Enum.take(1) do
      [{:ok, balance}] -> {:ok, balance}
      [{:error, error}] -> {:error, error}
    end
  end

  @doc """
  Same as get(), but it will unwrap the error tuple and raise in case of errors.
  """
  @spec get!(
    user: Project.t() | Organization.t() | nil
  ) :: any
  def get!(options \\ []) do
    Rest.get_list!(resource(), options) |> Enum.take(1) |> hd()
  end

  @doc false
  def resource() do
    {
      "PixBalance",
      &resource_maker/1
    }
  end

  @doc false
  def resource_maker(json) do
    %PixBalance{
      id: json[:id],
      amount: json[:amount],
      currency: json[:currency],
      updated:  json[:updated] |> Check.datetime()
    }
  end
end