Bookk.Account (bookk v1.0.0)

Copy Markdown View Source

An Account is pretty much like a bucked. It has a single purpose: holding a measurable amount of something, in this case it's currency.

Summary

Types

t()

The struct that represents the state of an account.

Functions

Checks whether an account is empty (no balance).

Merges a non-empty set of accounts into one (account head MUST be the same).

Merges two accounts into one (account head MUST be the same).

Calculates de delta amount for the operation then adds it the account's balance. See Bookk.Operation.to_delta_amount/1 for more information on delta amount.

Types

t()

@type t() :: %Bookk.Account{balance: Decimal.t(), head: Bookk.AccountHead.t()}

The struct that represents the state of an account.

Fields

An account is composed of:

  • head: the Bookk.AccountHead that identifies the account;
  • balance: the amount of currency held by the account, in cents or the smallest fraction supported by the currency you're using.

Functions

empty?(account)

@spec empty?(t()) :: boolean()

Checks whether an account is empty (no balance).

Examples

iex> Bookk.Account.new(fixture_account_head(:cash), Decimal.new(0))
iex> |> Bookk.Account.empty?()
true

iex> Bookk.Account.new(fixture_account_head(:cash), Decimal.new(10))
iex> |> Bookk.Account.empty?()
false

merge(list)

@spec merge([t(), ...]) :: t()

Merges a non-empty set of accounts into one (account head MUST be the same).

Examples

iex> a = Bookk.Account.new(fixture_account_head(:cash), Decimal.new(5))
iex> b = Bookk.Account.new(fixture_account_head(:cash), Decimal.new(15))
iex> c = Bookk.Account.new(fixture_account_head(:cash), Decimal.new(30))
iex> Bookk.Account.merge([a, b, c])
Bookk.Account.new(fixture_account_head(:cash), Decimal.new(50))

If you try to merge an empty list of accounts, an error will be raised.

merge(a, b)

@spec merge(t(), t()) :: t()

Merges two accounts into one (account head MUST be the same).

Examples

iex> a = Bookk.Account.new(fixture_account_head(:cash), Decimal.new(5))
iex> b = Bookk.Account.new(fixture_account_head(:cash), Decimal.new(15))
iex> Bookk.Account.merge(a, b)
Bookk.Account.new(fixture_account_head(:cash), Decimal.new(20))

It raises if the account head is different:

iex> a = Bookk.Account.new(fixture_account_head(:cash), Decimal.new(5))
iex> b = Bookk.Account.new(fixture_account_head(:deposits), Decimal.new(15))
iex> Bookk.Account.merge(a, b)
** (FunctionClauseError) no function clause matching in Bookk.Account.merge/2

new(head, balance \\ Decimal.new(0))

@spec new(Bookk.AccountHead.t(), balance :: Decimal.t()) :: t()

Creates a new account from a Bookk.AccountHead.

Examples

If no initial balance is provided in the second argument, then balance will be set to zero:

iex> head = fixture_account_head(:cash)
iex> Bookk.Account.new(head)
%Bookk.Account{
  head: fixture_account_head(:cash),
  balance: Decimal.new(0)
}

If an initial balance is provided in the second argument, then balance will be set to it:

iex> head = fixture_account_head(:cash)
iex> Bookk.Account.new(head, Decimal.new(50))
%Bookk.Account{
  head: fixture_account_head(:cash),
  balance: Decimal.new(50)
}

post(account, op)

@spec post(t(), Bookk.Operation.t()) :: t()

Calculates de delta amount for the operation then adds it the account's balance. See Bookk.Operation.to_delta_amount/1 for more information on delta amount.

Examples

iex> class = %Bookk.AccountClass{natural_balance: :debit}
iex> head = %Bookk.AccountHead{class: class}
iex> account = Bookk.Account.new(head)
iex>
iex> op = debit(head, Decimal.new(25))
iex>
iex> Bookk.Account.post(account, op)
%Bookk.Account{
  head: %Bookk.AccountHead{class: %Bookk.AccountClass{natural_balance: :debit}},
  balance: Decimal.new(25)
}

The account's head must match the head in the operation, otherwise an error is raised:

iex> head_a = %Bookk.AccountHead{name: "a"}
iex> head_b = %Bookk.AccountHead{name: "b"}
iex>
iex> account = Bookk.Account.new(head_a)
iex> op = debit(head_b, Decimal.new(25))
iex>
iex> Bookk.Account.post(account, op)
** (FunctionClauseError) no function clause matching in Bookk.Account.post/2