Bookk.Notation (bookk v1.0.0)

Copy Markdown View Source

DSL notation for describing an interledger entries (Bookk.InterledgerEntry).

Summary

Functions

DSL notation for describing an interledger entries (Bookk.InterledgerEntry).

Functions

journalize(opts, list)

(macro)

DSL notation for describing an interledger entries (Bookk.InterledgerEntry).

Options

  • using (required): your chart of accounts module;
  • compact: whether the resulting interledger entry should be compacted, where postings to the same account are merged, guaranteeing a single post per account. Defaults to false.
  • on_unbalanced: either :nothing or :raise, controls the desired behaviour for when journalize/2 produces a unbalanced interledger entry. Defaults to :nothing.

Examples

Returns a balanced interledger journal entry:

iex> use Bookk.Notation
iex>
iex> %Bookk.InterledgerEntry{} = journal_entry =
iex>   journalize using: DummyChartOfAccounts do
iex>     on ledger(:acme) do
iex>       debit account(:cash), Decimal.new(150)
iex>       credit account(:deposits), Decimal.new(150)
iex>     end
iex>   end
iex>
iex> assert not Bookk.InterledgerEntry.empty?(journal_entry)
iex> assert Bookk.InterledgerEntry.balanced?(journal_entry)

Returns an unbalanced interledger journal entry:

iex> use Bookk.Notation
iex>
iex> %Bookk.InterledgerEntry{} = journal_entry =
iex>   journalize using: DummyChartOfAccounts do
iex>     on ledger(:acme) do
iex>       debit account(:cash), Decimal.new(150)
iex>       credit account(:deposits), Decimal.new(50)
iex>     end
iex>   end
iex>
iex> assert not Bookk.InterledgerEntry.empty?(journal_entry)
iex> assert not Bookk.InterledgerEntry.balanced?(journal_entry)

You can do basic arithmetic operations with amounts even though they are most likely Decimal structs. The supported operations are addition, subtraction, multiplication and division where you can mix and match the use of Decimal amounts with integer or float amounts since they will automatically be converted into Decimal. These operations will be replaced by Decimal.add/2, Decimal.sub/2, Decimal.mul/2 and Decimal.div/2 respectively.

iex> use Bookk.Notation
iex>
iex> foo = %{amount: 50}
iex>
iex> journalize using: DummyChartOfAccounts do
iex>   on ledger(:acme) do
iex>     debit account(:cash), ((%Decimal{exp: 0, sign: 1, coef: 100} + Decimal.new(100) - foo.amount) * 2) / 2
iex>     credit account(:deposits), ((Decimal.new(100) + foo.amount) * Decimal.new(2)) / Decimal.new(2)
iex>   end
iex> end
Bookk.InterledgerEntry.new([
  {"acme", Bookk.JournalEntry.new([
    debit(fixture_account_head(:cash), Decimal.new(150)),
    credit(fixture_account_head(:deposits), Decimal.new(150))
  ])}
])

It's possible to post multiple times to the same ledger inside the interledger entry:

iex> use Bookk.Notation
iex>
iex> journalize using: DummyChartOfAccounts do
iex>   on ledger(:acme) do
iex>     debit account(:cash), 50
iex>     credit account(:deposits), 50
iex>   end
iex>
iex>   on ledger(:acme) do
iex>     debit account(:cash), 100
iex>     credit account(:deposits), 100
iex>   end
iex> end
Bookk.InterledgerEntry.new([
  {"acme", Bookk.JournalEntry.new([
    debit(fixture_account_head(:cash), Decimal.new(50)),
    credit(fixture_account_head(:deposits), Decimal.new(50))
  ])},
  {"acme", Bookk.JournalEntry.new([
    debit(fixture_account_head(:cash), Decimal.new(100)),
    credit(fixture_account_head(:deposits), Decimal.new(100))
  ])}
])

You can compact multiple postings to the same ledger into a single post:

iex> use Bookk.Notation
iex>
iex> journalize using: DummyChartOfAccounts, compact: true do
iex>   on ledger(:acme) do
iex>     debit account(:cash), 50
iex>     credit account(:deposits), 50
iex>   end
iex>
iex>   on ledger(:acme) do
iex>     debit account(:cash), 100
iex>     credit account(:deposits), 100
iex>   end
iex> end
Bookk.InterledgerEntry.new([
  {"acme", Bookk.JournalEntry.new([
    debit(fixture_account_head(:cash), Decimal.new(150)),
    credit(fixture_account_head(:deposits), Decimal.new(150))
  ])}
])

You can define the behaviour for when your journalize/2 produces a unbalanced interledger entry. The default is doing :nothing, but your can set it to :raise:

iex> use Bookk.Notation
iex>
iex> journalize using: DummyChartOfAccounts, on_unbalanced: :raise do
iex>   on ledger(:acme) do
iex>     debit account(:cash), 50
iex>   end
iex> end
** (Bookk.UnbalancedError) The interledger entry is unbalanced!