RevBank::Users - Banking and bookkeeping accounts
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.
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 therevbank.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.
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.
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
orfoo
, it is not allowed to have both*foo
andfoo
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
-@
,+@
, or0@
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.
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
.
Returns a list of all account names.
Returns a RevBank::Amount that represents the balance of the account.
Returns the last used datetime of the account.
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.
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 -
).
Returns true if the account is hidden (begins with +
or -
), or user-accessible but special (begins with *
).
Returns the canonical account name if the user account exists, or undef if it does not exist.
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.
The identifiers can be confusing and most instances of user
should probably be renamed to account
.
Juerd Waalboer <#####@juerd.nl>
Pick your favorite OSI license.