View Source Bookk.Ledger (bookk v0.1.0)
A ledger is a book that holds accounts. Traditionally, ledgers would also hold the journal entries that changed the accounts but, in this library, persisting those journal entries is considered off its scope -- you can persistem them on your own though.
Related
Summary
Functions
Checks whether the ledger is balanced. It is considered balance whe the sum of balance of its accounts that has a debit natural balance is equal the sum of balance of its accounts that has a credit natural balance.
Get an account from the ledger by its Bookk.AccountHead
. If the account
doesn't exist yet, then an account will be returned with empty state.
Creates a new Bookk.Ledger
from its name and, optionally, a list of
Bookk.Account
.
Posts a Bookk.JournalEntry
to a ledger. This means that the balance change
described in each operation of the journal entry will be applied to their
respective accounts of the ledger. If there's a change to an account that
doesn't exist yet, then the account is first created.
Types
@type t() :: %Bookk.Ledger{ accounts_by_name: %{required(name :: String.t()) => Bookk.Account.t()}, name: String.t() }
The struct that represents a ledger.
Fields
name
: the name of the ledger;accounts_by_name
: a map of the accounts known by the ledger, grouped by their name.
Functions
Checks whether the ledger is balanced. It is considered balance whe the sum of balance of its accounts that has a debit natural balance is equal the sum of balance of its accounts that has a credit natural balance.
See Bookk.AccountClass
for more information on natural balance.
Examples
Is balanced when the ledger is empty:
iex> Bookk.Ledger.new("acme")
iex> |> Bookk.Ledger.balanced?()
true
Is balanced when the sum of debit accounts balances is equal the sum of credit accounts balances:
iex> ledger = Bookk.Ledger.new("acme")
iex> cash = fixture_account_head(:cash)
iex> deposits = fixture_account_head(:deposits)
iex>
iex> journal_entry = %Bookk.JournalEntry{
iex> operations: [
iex> debit(cash, 50_00),
iex> credit(deposits, 50_00)
iex> ]
iex> }
iex>
iex> Bookk.Ledger.post(ledger, journal_entry)
iex> |> Bookk.Ledger.balanced?()
true
Is unbalanced when the sum of debit accounts balances isn't equal the sum of credit accounts balances:
iex> ledger = Bookk.Ledger.new("acme")
iex> cash = fixture_account_head(:cash)
iex>
iex> journal_entry = %Bookk.JournalEntry{
iex> operations: [
iex> debit(cash, 50_00)
iex> ]
iex> }
iex>
iex> Bookk.Ledger.post(ledger, journal_entry)
iex> |> Bookk.Ledger.balanced?()
false
@spec get_account(t(), Bookk.AccountHead.t()) :: Bookk.Account.t()
Get an account from the ledger by its Bookk.AccountHead
. If the account
doesn't exist yet, then an account will be returned with empty state.
Examples
Returns the account when it exists in the ledger:
iex> ledger = %Bookk.Ledger{
iex> name: "acme",
iex> accounts_by_name: %{
iex> "cash/CA" => %Bookk.Account{
iex> head: fixture_account_head(:cash),
iex> balance: 25_00
iex> }
iex> }
iex> }
iex>
iex> Bookk.Ledger.get_account(ledger, fixture_account_head(:cash))
%Bookk.Account{
head: fixture_account_head(:cash),
balance: 25_00
}
Returns an empty account when the it doesn't exist in the ledger:
iex> Bookk.Ledger.new("acme")
iex> |> Bookk.Ledger.get_account(fixture_account_head(:cash))
%Bookk.Account{
head: fixture_account_head(:cash),
balance: 0
}
@spec new(name :: String.t(), [Bookk.Account.t()]) :: t()
Creates a new Bookk.Ledger
from its name and, optionally, a list of
Bookk.Account
.
@spec post(t(), Bookk.JournalEntry.t()) :: t()
Posts a Bookk.JournalEntry
to a ledger. This means that the balance change
described in each operation of the journal entry will be applied to their
respective accounts of the ledger. If there's a change to an account that
doesn't exist yet, then the account is first created.
Examples
When account doesn't exist then it gets created:
iex> ledger = Bookk.Ledger.new("acme")
iex>
iex> cash = fixture_account_head(:cash)
iex> deposits = fixture_account_head(:deposits)
iex>
iex> journal_entry = %Bookk.JournalEntry{
iex> operations: [
iex> debit(cash, 50_00),
iex> credit(deposits, 50_00)
iex> ]
iex> }
iex>
iex> updated_ledger = Bookk.Ledger.post(ledger, journal_entry)
iex>
iex> %Bookk.Account{balance: 50_00} = Bookk.Ledger.get_account(updated_ledger, cash)
iex> %Bookk.Account{balance: 50_00} = Bookk.Ledger.get_account(updated_ledger, deposits)
When account exists then it gets updated:
iex> ledger = Bookk.Ledger.new("acme")
iex>
iex> cash = fixture_account_head(:cash)
iex> deposits = fixture_account_head(:deposits)
iex>
iex> journal_entry = %Bookk.JournalEntry{
iex> operations: [
iex> debit(cash, 50_00),
iex> credit(deposits, 50_00)
iex> ]
iex> }
iex>
iex> updated_ledger =
iex> ledger
iex> |> Bookk.Ledger.post(journal_entry)
iex> |> Bookk.Ledger.post(journal_entry) # post twice
iex>
iex> %Bookk.Account{balance: 100_00} = Bookk.Ledger.get_account(updated_ledger, cash)
iex> %Bookk.Account{balance: 100_00} = Bookk.Ledger.get_account(updated_ledger, deposits)