README.md

Managed accounts for Django

A 'managed account' is an allocation of money that can be debited and credited. This
package provides managed account functionality for use with the e-commerce framework
Oscar. It can also be used
standalone without Oscar.

Accounts can be used to implement a variety of interesting components, including:

Giftcards

Web accounts

Loyalty schemes

Basically anything that involves tracking the movement of funds within a closed
system.

This package uses double-entry bookkeeping
where every transaction is recorded twice (once for the source and once for the
destination). This ensures the books always balance and there is full audit
trail of all transactional activity.

If your project manages money, you should be using a library like this. Your
finance people will thank you.

Features

An account has a credit limit which defaults to zero. Accounts can be set up
with no credit limit so that they are a 'source' of money within the system.
At least one account must be set up without a credit limit in order for money
to move around the system.

Accounts can have:

No users assigned

A single "primary" user - this is the most common case

A set of users assigned

A user can have multiple accounts

An account can have a start and end date to allow its usage in a limited time
window

An account can be restricted so that it can only be used to pay for a range of
products.

Accounts can be categorised

Screenshots

Installation

Install using pip:

pip install django-oscar-accounts

and add accounts to INSTALLED_APPS. Runnning manage.py migrate accounts will create the appropriate database
tables and also initial some core accounts and account-types. The names of these accounts can be controlled using
settings (see below).

If the proposed transfer is invalid, an exception will be raised. All
exceptions are subclasses of accounts.exceptions.AccountException. Your
client code should look for exceptions of this type and handle them
appropriately.

Client code should only use the accounts.models.Budget class and the
two functions from accounts.facade - nothing else should be required.

Error handling

Note that the transfer operation is wrapped in its own database transaction to
ensure that only complete transfers are written out. When using Django's
transaction middleware, you need to be careful. If you have an unhandled
exception, then account transfers will still be committed even though nothing
else will be. To handle this, you need to make sure that, if an exception
occurs during your post-payment code, then you roll-back any transfers.

As you can see, there is some careful handling of the scenario where not all transfers can be
executed.

If you using Oscar then ensure that you create an OrderSource instance for every transfer (rather than
aggregating them all into one). This will provide better audit information. Here's some example code:

Core accounts and account types

A post-syncdb signal will create the common structure for account types and
accounts. Some names can be controlled with settings, as indicated in parentheses.

Assets

Sales

Redemptions (ACCOUNTS_REDEMPTIONS_NAME) - where money is
transferred to when an account is used to pay for something.

Lapsed (ACCOUNTS_LAPSED_NAME) - where money is transferred to
when an account expires. This is done by the
'close_expired_accounts' management command. The name of this
account can be set using the ACCOUNTS_LAPSED_NAME.

Cash

"Bank" (ACCOUNTS_BANK_NAME) - the source account for creating new
accounts that are paid for by the customer (eg a giftcard). This
account will not have a credit limit and will normally have a
negative balance as money is only transferred out.

Unpaid - This contains accounts that are used as sources for other
accounts but aren't paid for by the customer. For instance, you might
allow admins to create new accounts in the dashboard. An account of this
type will be the source account for the initial transfer.

Liabilities

Deferred income - This contains customer accounts/giftcards. You may want to create
additional account types within this type to categorise accounts.

Example transactions

Consider the following accounts and account types:

Assets

Sales

Redemptions

Lapsed

Cash

Bank

Unpaid

Merchant funded

Liabilities

Deferred income

Note that all accounts start with a balance of 0 and the sum of all balances will always be zero.

A customer purchases a £50 giftcard

A new account is created of type 'Deferred income' with an end date

£50 is transferred from the Bank to this new account

A customer pays for a £30 order using their £50 giftcard

£30 is transferred from the giftcard account to the redemptions account

The customer's giftcard expires with £20 still on it

£20 is transferred from the giftcard account to the lapsed account

The customer phones up to complain and a staff member creates a new giftcard for £20

A new account is created of type 'Deferred income'

£20 is transferred from the "Merchant funded" account to this new account

Settings

There are settings to control the naming and initial unpaid and deferred income account
types:

ACCOUNTS_MIN_INITIAL_VALUE The minimum value that can be used to create an
account (or for a top-up)

ACCOUNTS_MAX_INITIAL_VALUE The maximum value that can be transferred to an
account.