Bookk.ChartOfAccounts behaviour (bookk v1.0.0)

Copy Markdown View Source

A Chart of Accounts (abbrv.: CoA) is a mapping of all the accounts and all the ledgers that can exist in your system. But instead of hard-coding them, you define patterns for accounts and ledgers supported by your application using functions and pattern matching.

For example, if your application allows ledgers to have an account for expenses related to paying salary to an employee, you could define a function with a signature the like the one below:

def account({:salary, {:employee, employee_id}})

And if your application, following the previous example, allows for every employee to have their own ledger, you could define a function with a signature like the one below:

def ledger_id({:employee, employee_id})

Summary

Callbacks

This function maps all possible patterns of accounts that your application supports. It's recomended to use pattern matching and let it crash in the event of a mismatch.

Combines a ledger id with an account header, returning a unique id for the account.

Get a Bookk.AccountClass definition by its id.

This function maps all of your ledger codes into a ledger id string. It's recomended to use pattern matching and let it crash in the event of a mismatch.

Functions

By using this module, you are declaring that your module implements the Bookk.ChartOfAccounts behaviour.

Callbacks

account(term)

@callback account(term()) :: Bookk.AccountHead.t()

This function maps all possible patterns of accounts that your application supports. It's recomended to use pattern matching and let it crash in the event of a mismatch.

Examples

@impl Bookk.ChartOfAccounts
def account(:cash), do: %Bookk.AccountHead{name: "cash", class: class("CA")}
def account({:payables, {:user, id}}), do: %Bookk.AccountHead{name: "payables:user(#{id})", class: class("L")}

account_id(ledger_id, account_head)

@callback account_id(ledger_id, account_head) :: String.t()
when ledger_id: String.t(), account_head: Bookk.AccountHead.t()
@callback account_id(ledger_code, account_code) :: String.t()
when ledger_code: term(), account_code: term()

Combines a ledger id with an account header, returning a unique id for the account.

  id = account_id(ledger_id(:acme), account(:cash))
  #> %Bookk.AccountHead{...}

Can alternativelly be called directly with ledger code and account code:

id = account_id(:acme, :cash)
#> %Bookk.AccountHead{...}

class(id)

@callback class(id :: String.t()) :: Bookk.AccountClass.t() | nil

Get a Bookk.AccountClass definition by its id.

You are free to choose how and where you define your account classes, but you need to provide an implementation for this function so that your classes definitions are accessible to other modules.

Example

@impl Bookk.ChartOfAccounts
def class("A"), do: %Bookk.AccountClass{id: "A", parent_id: nil, name: "Assets", natural_balance: :debit},
def class("CA"), do: %Bookk.AccountClass{id: "CA", parent_id: "A", name: "Current Assets", natural_balance: :debit}

ledger_id(term)

@callback ledger_id(term()) :: String.t()

This function maps all of your ledger codes into a ledger id string. It's recomended to use pattern matching and let it crash in the event of a mismatch.

Example

@impl Bookk.ChartOfAccounts
def ledger_id(:acme), do: "acme"
def ledger_id({:user, <<id::binary-size(36)>>}), do: "user(#{id})"

Functions

__using__(_)

(macro)

By using this module, you are declaring that your module implements the Bookk.ChartOfAccounts behaviour.