defmodule AccessGrid.LedgerItem do @moduledoc """ A line item from the account's billing ledger. Returned by `AccessGrid.Console.list_ledger_items/1`. `access_pass` is populated when the ledger item is tied to a specific access pass — typically credit/debit lines for issuance, renewals, etc. It is `nil` for line items that aren't pass-scoped. The API returns both `id` and `ex_id` for ledger items (same value); `ex_id` is deprecated. This struct reads from `id`. """ alias AccessGrid.LedgerItem.AccessPass @type t :: %__MODULE__{ id: String.t() | nil, created_at: String.t() | nil, amount: number() | nil, kind: String.t() | nil, event: String.t() | nil, metadata: map(), access_pass: AccessPass.t() | nil } defstruct [ :id, :created_at, :amount, :kind, :event, :access_pass, metadata: %{} ] @doc """ Creates a LedgerItem struct from an API response map. """ @spec from_response(map()) :: t() def from_response(data) when is_map(data) do %__MODULE__{ id: data["id"], created_at: data["created_at"], amount: data["amount"], kind: data["kind"], event: data["event"], metadata: data["metadata"] || %{}, access_pass: AccessPass.from_response(data["access_pass"]) } end end defmodule AccessGrid.LedgerItem.AccessPass do @moduledoc """ Narrow access-pass representation embedded in `AccessGrid.LedgerItem`. Returned with just enough fields to identify the pass behind a ledger line; for the full access-pass shape, use `AccessGrid.AccessPasses.get/2`. The field is named `pass_template` here (matching the wire key the server returns) but its value is a `%AccessGrid.LedgerItem.CardTemplate{}`. """ alias AccessGrid.LedgerItem.CardTemplate @type t :: %__MODULE__{ id: String.t() | nil, full_name: String.t() | nil, state: String.t() | nil, metadata: map(), unified_access_pass_id: String.t() | nil, pass_template: CardTemplate.t() | nil } defstruct [ :id, :full_name, :state, :unified_access_pass_id, :pass_template, metadata: %{} ] @doc """ Creates a LedgerItem.AccessPass struct from an API response map. """ @spec from_response(map() | nil) :: t() | nil def from_response(nil), do: nil def from_response(data) when is_map(data) do %__MODULE__{ id: data["id"], full_name: data["full_name"], state: data["state"], metadata: data["metadata"] || %{}, unified_access_pass_id: data["unified_access_pass_id"], pass_template: CardTemplate.from_response(data["pass_template"]) } end end defmodule AccessGrid.LedgerItem.CardTemplate do @moduledoc """ Narrow card-template representation embedded in `AccessGrid.LedgerItem.AccessPass`. Returned with just enough fields to identify the template behind a ledger line; for the full template shape, use `AccessGrid.Console.read_template/2`. """ @type t :: %__MODULE__{ id: String.t() | nil, name: String.t() | nil, protocol: String.t() | nil, platform: String.t() | nil, use_case: String.t() | nil } defstruct [:id, :name, :protocol, :platform, :use_case] @doc """ Creates a LedgerItem.CardTemplate struct from an API response map. """ @spec from_response(map() | nil) :: t() | nil def from_response(nil), do: nil def from_response(data) when is_map(data) do %__MODULE__{ id: data["id"], name: data["name"], protocol: data["protocol"], platform: data["platform"], use_case: data["use_case"] } end end