Skip to main content

A minimal, yet valid double-entry accounting system in Python.

Project description

abacus

pytest PyPI

A minimal, yet valid double-entry accounting system, provided as abacus-py Python package and the bx command line tool.

Using abacus you can:

  • define a chart of accounts,
  • post regular and adjustment entries to ledger,
  • make trial balance,
  • close accounts at period end,
  • produce balance sheet and income statement.

Quotes about abacus

Reddit Discussion

I think it's a great idea to mock-up a mini GL ERP to really get a foundational understanding of how the accounting in ERP works!

I teach accounting information systems... I'd be tempted to use abacus as a way of simply showing the structure of a simple AIS.

Hey, what a cool job, thanks much. Do you plan to make a possibility for RAS accounting?

Install

pip install abacus-py

This will install both abacus-py package and the bx command line tool.

For latest version install from github:

pip install git+https://github.com/epogrebnyak/abacus.git

abacus-py requires Python 3.10 or higher.

Minimal command line example

Сreate temporary directory where chart.json and entries.csv will be created:

mkdir -p scripts/try && cd scripts/try

Create chart of accounts:

bx chart init
bx chart add --asset cash
bx chart add --asset ar --title "Accounts receivable"
bx chart add --asset goods --title "Inventory (goods for resale)"
bx chart add --asset prepaid_rent --title "Storage facility prepaid rent"
bx chart add --capital equity
bx chart add --liability dividend_due
bx chart add --income sales
bx chart offset sales discounts
bx chart add --expense cogs --title "Cost of goods sold"
bx chart add --expense sga --title "Selling, general and adm. expenses"
bx chart alias --operation invoice --debit ar --credit sales
bx chart alias --operation cost --debit cogs --credit goods
bx chart show

Start ledger, post entries and close accounts at period end:

bx ledger init
bx ledger post --debit cash  --credit equity --amount 5000 --title "Initial investment"
bx ledger post --debit goods --credit cash   --amount 3500 --title "Acquire goods for cash"
bx ledger post --debit prepaid_rent --credit cash --amount 1200 --title "Prepay rent"
bx ledger post --operation invoice 4300 cost 2500 --title "Issue invoice and register sales"
bx ledger post --debit discounts --credit ar --amount  450 --title "Provide discount"
bx ledger post --debit cash  --credit ar     --amount 3000 --title "Accept payment"
bx ledger post --debit sga   --credit cash   --amount  300 --title "Reimburse sales team"
bx ledger adjust --debit sga --credit prepaid_rent --amount 800 --title "Expense 8 months of rent"
bx ledger close
bx ledger post-close --debit re --credit dividend_due --amount 150 --title "Accrue dividend"

Make reports:

bx report --trial-balance
bx report --balance-sheet
bx report --income-statement

Inspect accounts:

bx account sales
bx account cash --assert 3000
bx balances --nonzero

The results should look similar to this:

Balance sheet
Assets                          5500  Capital              5500
- Cash                          2700  - Equity             5000
- Accounts receivable           1500  - Retained earnings   500
- Inventory (goods for resale)  1300  Liabilities             0
Total                           5500  Total                5500

Income statement
Income                                                     3500
- Sales                                                    3500
Expenses                                                   3000
- Cost of goods sold                                       2700
- Selling, general and adm. expenses                        300
Profit                                                      500
Python code (`scripts/minimal.py`)
from abacus import Chart, Entry, BalanceSheet, IncomeStatement

chart = (
    Chart(
        assets=["cash", "ar", "goods"],
        expenses=["cogs", "sga"],
        equity=["equity", "re"],
        income=["sales"],
    )
    .offset("sales", "discounts")
    .set_name("cogs", "Cost of goods sold")
    .set_name("sga", "Selling, general and adm.expenses")
    .set_name("goods", "Inventory (goods for sale)")
    .set_name("ar", "Accounts receivable")
)

ledger = (
    chart.ledger()
    .post(Entry(debit="cash", credit="equity", amount=1000))
    .post(Entry(debit="goods", credit="cash", amount=800))
    .post(Entry(debit="ar", credit="sales", amount=465))
    .post(Entry(debit="discounts", credit="ar", amount=65))
    .post(Entry(debit="cogs", credit="goods", amount=200))
    .post(Entry(debit="sga", credit="cash", amount=100))
    .post(Entry(debit="cash", credit="ar", amount=360))
)

income_statement = ledger.income_statement(chart)
income_statement.print(chart.names)
income_statement.print_rich(chart.names)
assert income_statement == IncomeStatement(
    income={"sales": 400}, expenses={"cogs": 200, "sga": 100}
)

ledger.close(chart)
balance_sheet = ledger.balance_sheet(chart)
balance_sheet.print(chart.names)
balance_sheet.print_rich(chart.names)
assert balance_sheet == BalanceSheet(
    assets={"cash": 460, "ar": 40, "goods": 600},
    capital={"equity": 1000, "re": 100},
    liabilities={},
)

# Create end of period balances
end_balances = ledger.nonzero_balances()
print(end_balances)
next_book = chart.ledger(starting_balances=end_balances)

Documentation

https://epogrebnyak.github.io/abacus/

Feedback

Anything missing in abacus? Got a good use case for abacus or used abacus for teaching?

Feel free to contact abacus author in issues, on reddit or via Telegram.

Your feedback is highly appreciated and helps steering abacus development.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

abacus_py-0.6.0.tar.gz (35.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

abacus_py-0.6.0-py3-none-any.whl (41.8 kB view details)

Uploaded Python 3

File details

Details for the file abacus_py-0.6.0.tar.gz.

File metadata

  • Download URL: abacus_py-0.6.0.tar.gz
  • Upload date:
  • Size: 35.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.8 Linux/5.15.0-1041-azure

File hashes

Hashes for abacus_py-0.6.0.tar.gz
Algorithm Hash digest
SHA256 7daedd547728390ed74ee1c987e18f757495a4a55fa7ac6df36d4f01e4bcf061
MD5 b3684ed98e1caaad7af2b076dd820727
BLAKE2b-256 2eff74d4d6f9c0a18658725d711c9c27f6ecbe9c73bffb22e71cad3bd6ca8c58

See more details on using hashes here.

File details

Details for the file abacus_py-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: abacus_py-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 41.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.8 Linux/5.15.0-1041-azure

File hashes

Hashes for abacus_py-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9036dd95deb550c54c07264a1d6b5154c8b03c98f6e644499531247f6acade5a
MD5 6602b0cf22f74e634aae8c5bd7346511
BLAKE2b-256 6e17a22f8384b482261259f52aca3da1f41983bfd41f5e0416baf894a75e036e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page