Skip to content

Latest commit

 

History

History
162 lines (81 loc) · 6.69 KB

Users.pod

File metadata and controls

162 lines (81 loc) · 6.69 KB

NAME

RevBank::Users - Banking and bookkeeping accounts

DESCRIPTION

This package handles all accounts in RevBank. Accounts are called "users" because originally, RevBank only had user accounts. Today, RevBank does doubly-entry bookkeeping and has multiple account types to accommodate that.

This package is where manipulation of revbank.accounts happens.

Account types

  • User accounts

    User accounts are typically made with the adduser command, and almost all interactions with RevBank will involve only user accounts, from the perspective of the user.

  • Hidden accounts

    The name of a hidden account begins with a - or + sign. These accounts are created automatically by plugins to provide the double part in doubly-entry bookkeeping.

    Hidden accounts are internal accounts in the sense that they are not displayed and can't be used in the CLI where user accounts can.

    There is no technical difference between + and -, but it is suggested to use - for accounts that will typically go negative and would be flipped to a positive number to make intuitive sense.

    For example, the -cash account will go to -4.20 when someone deposits 4.20 into the cash box. It has to be a negative number, to balance the positive number added to the balance of the user. But the cash box will contain 4.20 more than before, even though the number is negative.

    Some plugins will use / to establish hierarchical account names in hidden accounts, like in +sales/products. To RevBank, / is just a regular character, and it has no specific semantics for these hierarchies.

  • User-accessible special accounts

    The name of a user-accessible special account begins with a * sign. A special account can only be created by editing the revbank.accounts file manually. They can be used like user accounts, with or without the * sign, but they do not count towards the grand total of user accounts.

    The suggested use for user-accessible special accounts is for creating accounts that are virtual jars. For example, if users pay towards a virtual jar for kitchen equipment when they use the kitchen (like in the dinnerbonus plugin), but are also allowed to use those funds for buying kitchen equipment, a user-accessible special account might be more convenient than having separate revenue and expense accounts, especially because those would typically be hidden accounts.

Bookkeeping

While RevBank does double-entry bookeeping, it does not use the terms credit and debit anywhere. Everything is just plus or minus. To use the data in bookkeeping software, some translation is required.

There are many systems for bookkeeping. In the accounting equation approach, RevBank's account types would translate as:

  • user accounts

    Liabilities accounts

  • hidden accounts (+)

    Revenues/incomes accounts.

  • hidden accounts (-)

    Expenses/losses accounts, or assets accounts.

  • user-accessible special accounts (*)

    This one is slightly more complicated, because this depends on your view on accounting. From a pure bookkeeping perspective, this would be a liabilities account because it is technically equivalent to a user account, but it would make sense to book additions as revenue and deductions as expenses.

Data format

The file revbank.accounts is a text file with one record per line, and whitespace separated fields. The columns are:

  • Account name

    The account name can be anything, but cannot contain whitespace. Special accounts begin with +, -, or *.

    Account names are case preserving, but case insensitive.

    Every account name must be unique. A file with duplicate names is not valid and may lead to crashes or undefined behavior. Since *foo can be used as either *foo or foo, it is not allowed to have both *foo and foo in the accounts file.

  • Balance

    The account balance is a number with two decimal digits. Positive numbers may have a + sign. Negative number have a - sign.

    If the value in this field is not a valid number, the account is treated as non-existent by most of RevBank, while still being unavailable for adduser.

    If the value begins with a ! character, the rest of the line is taken as a description of why the account name is not available and printed as a warning when the account name is used.

  • Last use timestamp

    Local datetime of the last update of this account.

  • Zero-crossing timestamp

    Local datetime of the last time the balance went through 0.00. The timestamp is preceded with -@, +@, or 0@ to indicate the direction of the crossing: -@ can be read as "became negative at", etc.

    This field is empty for accounts that have not yet been used.

Only the first two columns are mandatory. This makes migrating to RevBank very simple.

Functions

Usernames are case preserving, but case insensitive. Account name arguments to functions are case insensitive, but return values use the canonical capitalization.

Anything that outputs a username should always run it through parse_user or assert_user.

names

Returns a list of all account names.

balance($name)

Returns a RevBank::Amount that represents the balance of the account.

since($name)

Returns the last used datetime of the account.

create($name)

Creates an account with that name and a balance of zero. The name must not already exist.

After updating the file, calls the user_created hook with the account name.

update($name, $delta, $transaction_id)

Given the relative change ($delta), updates the user balance for an account.

After updating the file, calls the user_balance hook with the account name, the old balance, the given delta, the new balance, and the transaction_id.

This function should not be used directly; instead, create a transaction via RevBank::Cart and use checkout to ensure a balanced booking for proper double-entry bookkeeping.

is_hidden($name)

Returns true if the account is hidden (begins with + or -).

is_special($name)

Returns true if the account is hidden (begins with + or -), or user-accessible but special (begins with *).

parse_user($username)

Returns the canonical account name if the user account exists, or undef if it does not exist.

assert_user($name)

For a hidden account, returns the canonical account name, creating the account if it did not already exist.

For a non-hidden account, works like parse_user.

CAVEATS

The identifiers can be confusing and most instances of user should probably be renamed to account.

AUTHOR

Juerd Waalboer <#####@juerd.nl>

LICENSE

Pick your favorite OSI license.