# `Logistiki.Ledger`
[🔗](https://github.com/thanos/logistiki/blob/v0.1.0/lib/logistiki/ledger.ex#L1)

The context for ledger backends.

The runtime calls the configured backend (see `config :logistiki,
:ledger_backend`) to execute journals, reverse them, and compute
projections. Backends implement `Logistiki.Ledger.Behaviour`.

# `backend`
*since 0.1.0* 

```elixir
@spec backend() :: module()
```

Returns the configured ledger backend module.

## Returns

  * `module()` — e.g. `Logistiki.Ledger.Simulation` or
    `Logistiki.Ledger.Beancount`.

## Examples

    iex> Logistiki.Ledger.backend()
    Logistiki.Ledger.Simulation

# `backends`
*since 0.1.0* 

```elixir
@spec backends() :: [module(), ...]
```

Returns the list of available backends.

## Returns

  * `[module()]` — `[Logistiki.Ledger.Simulation, Logistiki.Ledger.Beancount]`.

## Examples

    iex> Logistiki.Ledger.backends()
    [Logistiki.Ledger.Simulation, Logistiki.Ledger.Beancount]

# `balance`
*since 0.1.0* 

```elixir
@spec balance(
  Logistiki.VirtualAccounts.VirtualAccount.t() | String.t() | integer(),
  keyword()
) :: {:ok, [Logistiki.Projections.Balance.t()]} | {:error, term()}
```

Computes a balance through the configured backend.

## Arguments

  * `account` — `VirtualAccount.t() | String.t() | integer()` — account
    struct, code, or id.
  * `opts` — `keyword()` — e.g. `[currency: "USD"]`.

## Returns

  * `{:ok, [Logistiki.Projections.Balance.t()]}` — balances per currency.

## Examples

    iex> {:ok, [balance]} = Logistiki.Ledger.balance("ASSETS:CASH:USD:NOSTRO")
    iex> balance.net
    Decimal.new("1000.00")

# `execute_journal`
*since 0.1.0* 

```elixir
@spec execute_journal(
  Logistiki.Accounting.Journal.t(),
  keyword()
) :: {:ok, Logistiki.Ledger.Result.t()} | {:error, term()}
```

Executes a journal through the configured backend.

## Arguments

  * `journal` — `Journal.t()` — the draft journal with postings attached.
  * `opts` — `keyword()` — backend-specific options (e.g. `[currency: "USD"]`).

## Returns

  * `{:ok, Logistiki.Ledger.Result.t()}` — the backend result.
  * `{:error, term()}` — execution failed.

## Examples

    iex> {:ok, result} = Logistiki.Ledger.execute_journal(journal)
    iex> result.status
    :ok

# `put_backend`
*since 0.1.0* 

```elixir
@spec put_backend(module()) :: :ok
```

Sets the ledger backend at runtime (mainly for tests).

## Arguments

  * `module` — `module()` — a module implementing
    `Logistiki.Ledger.Behaviour` (e.g. `Logistiki.Ledger.Beancount`).

## Examples

    iex> Logistiki.Ledger.put_backend(Logistiki.Ledger.Beancount)
    :ok

# `reverse_journal`
*since 0.1.0* 

```elixir
@spec reverse_journal(Logistiki.Accounting.Journal.t(), map(), keyword()) ::
  {:ok, Logistiki.Ledger.Result.t()} | {:error, term()}
```

Reverses a journal through the configured backend.

## Arguments

  * `journal` — `Journal.t()` — the posted journal to reverse.
  * `attrs` — `map()` — reversal attributes (e.g. `%{reason: "mistaken fee"}`).
  * `opts` — `keyword()` — backend-specific options.

## Returns

  * `{:ok, Logistiki.Ledger.Result.t()}` — the reversal result.
  * `{:error, term()}` — reversal failed.

## Examples

    iex> {:ok, result} = Logistiki.Ledger.reverse_journal(journal, %{reason: "mistaken fee"})
    iex> result.status
    :ok

# `statement`
*since 0.1.0* 

```elixir
@spec statement(
  Logistiki.VirtualAccounts.VirtualAccount.t() | String.t() | integer(),
  keyword()
) :: {:ok, [Logistiki.Projections.StatementLine.t()]} | {:error, term()}
```

Computes a statement through the configured backend.

## Arguments

  * `account` — `VirtualAccount.t() | String.t() | integer()`.
  * `opts` — `keyword()` — e.g. `[currency: "USD"]`.

## Returns

  * `{:ok, [Logistiki.Projections.StatementLine.t()]}` — ordered lines.

## Examples

    iex> {:ok, lines} = Logistiki.Ledger.statement("LIABILITIES:CLIENT_DEPOSITS:USD:ACME:OPERATING")
    iex> hd(lines).running_balance
    Decimal.new("-1000.00")

# `trial_balance`
*since 0.1.0* 

```elixir
@spec trial_balance(keyword()) :: {:ok, Logistiki.Projections.TrialBalance.t()}
```

Computes a trial balance through the configured backend.

## Arguments

  * `opts` — `keyword()` — e.g. `[currency: "USD"]`.

## Returns

  * `{:ok, Logistiki.Projections.TrialBalance.t()}` — with `lines`,
    `currencies`, `balanced`.

## Examples

    iex> {:ok, tb} = Logistiki.Ledger.trial_balance()
    iex> tb.balanced
    true

---

*Consult [api-reference.md](api-reference.md) for complete listing*
