Skip to main content

abacus-minimal

PyPI - Version

Accounting logic should be possible to express in good code. abacus-minimal aims to be concise, correct and expressive in implementation of double entry book-keeping rules.

Progress and notable features so far:

  • event-based ledger,
  • contra accounts,
  • period end closing,
  • income statement and balance sheet before and after closing,
  • saving and loading from JSON.

Install

pip install abacus-minimal

Latest:

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

Ledger as a sequence of events

abacus-minimal provides an accounting ledger that is controlled by events:

  • chart of account changes,
  • business transactions, and
  • closing entries.

Given a sequence of events you can always recreate the ledger state from scratch.

Аccount creation, double entries and a command to close accounts are in the events list in an example below.

from abacus import Asset, Double, Equity, Expense, Income, Ledger, Close

events = [
    # Create accounts
    Asset("cash"),
    Equity("equity"),
    Equity("re", title="Retained earnings"),
    Income("sales"),
    Expense("salaries"),
    # Post entries
    Double("cash", "equity", 1000),
    Double("cash", "sales", 250),
    Double("salaries", "cash", 150),
    # Close period
    Close(earnings_account="re")
]
ledger = Ledger.from_list(events)

Reports reflect the state of ledger:

print(ledger.balances)
print(ledger.income_statement())
print(ledger.balance_sheet())

Ledger history can be saved to a JSON file.

Primitives

There are six types of 'primitive' events in abacus-minimal:

  • add account or contra account,
  • debit or credit account,
  • drop account, and
  • mark period end.

All compound event types translate to primitives.

In example above you can extract the primitives as following:

for p in ledger.history.primitives:
   print(p)

Ledger as class

You can also work with higher-level Chart, Book and Entry classes.

Consider an example where you need to process the following transactions and show end reports:

  • a company gets $1000 equity investment from shareholders,
  • bills a client $1000 plus 20% value added tax (VAT) for services,
  • receives $600 installment payment,
  • makes a $150 refund,
  • pays $450 in salaries to the staff.
from abacus import Book, Chart, Entry

# Create chart and ledger
chart = Chart(
    assets=["cash", "ar"],
    equity=["equity"],
    liabilities=["tax_due"],
    income=["services"],
    expenses=["salaries"],
    contra_accounts={"services": ["refunds"]},
    retained_earnings="retained_earnings",
    current_earnings="current_earnings")
book = Book.from_chart(chart)

# Post entries
entries = [
    Entry("Shareholder investment").double("cash", "equity", 1000),
    Entry("Invoiced services")
       .debit("ar", 1200)
       .credit("services", 1000)
       .credit("tax_due", 200),
    Entry("Accepted payment").double("cash", "ar", 600),
    Entry("Made refund").double("refunds", "cash", 150),
    Entry("Paid salaries").double("salaries", "cash", 450),
]
book.post_many(entries)
print(book.balances)

# Close the period and show reports
book.close()
print(book.income_statement)
print(book.balance_sheet)

Everything as JSON

All data structures used are serialisable. You can write code to create a chart of accounts and a ledger, save them to JSONs or pick up data from the JSON files, restore the ledger, work on it, save again and so on.

# Save
book.save("chart.json", "history.json", allow_overwrite=True)

# Load and re-enter
book2 = Book.load_unsafe("chart.json", "history.json")

from pprint import pprint
pprint(book2) # may not fully identical to `book` yet

Accounting concepts

In abacus-minimal there are regular accounts of five types: asset, liability, equity, income, expense. Contra accounts to regular accounts are possible (eg depreciation, discounts).

Period end closes temporary accounts (income, expense and their associated contra accounts), but balance sheet and income statement are available before and after close.

Post close entries are allowed on permanent accounts.

Accounting workflow

The steps for using abacus-minimal follow the steps of a typical accounting cycle:

  • create a chart of accounts,
  • open ledger for the current reporting period,
  • post account balances for the previous period,
  • post entries that reflect business transactions within the period,
  • post reconciliation and adjustment entries,
  • close accounts at reporting period end,
  • make post-close entries,
  • show financial reports,
  • save account balances data for the next reporting period.

Accounting identity

abacus-minimal adheres to the following interpretation of accounting identity.

  1. The value of company property, or assets, equals to shareholder and creditor claims on the company:
Assets = Equity + Liabilities

Equity is the residual claim after creditors:

Equity = Assets - Liabilities
  1. Company current earnings, or profit, equal to income less expenses associated with generating this income:
Current Earnings = Income - Expenses

Current earnings accumulate to retained earnings:

Retained Earnings = Retained Earnings From Previous Period + Current Earnings
  1. Equity consists of shareholder equity, other equity accounts and retained earnings:
Equity = Shareholder Equity + Other Equity + Retained Earnings
  1. Substituting we get a form of extended accounting equation:
Assets + Expenses =
   Shareholder Equity + Other Equity + Retained Earnings + Income + Liabilities

Our book-keeping goal is to reflect business events as changes to the variables while maintaining this equation.

Limitations

Several assumptions and simplifications are used to make abacus-minimal easier to develop and reason about:

  • one currency
  • one reporting period
  • one level of accounts, no sub-accounts
  • no account aggregation for reports
  • account names must be globally unique (eg cannot have two accounts named "other")
  • chart always has current earnings account and retained earnings account
  • period end closing will transfer current earnings to retained earnings
  • no account durations, current vs non-current accounts not distinguished
  • other comprehensive income account (OCIA) not calculated
  • no revaluations
  • no intermediate accounts except current earnings
  • accounts either debit normal or credit normal, no mixed accounts
  • no journals, entries are posted to ledger directly
  • an entry can touch any accounts
  • entry amount can be positive, negative or zero
  • net earnings are income less expenses, no gross profit or earnings before tax calculated
  • no cash flow statement
  • no statement of changes in equity
  • no date or any transaction metadata recorded

Alternatives

abacus-minimal takes a lot of inspiration from the following projects:

Accounting knowledge

If you are totally new to accounting the suggested friendly course is https://www.accountingcoach.com/.

ACCA and CPA are the international and the US professional qualifications and IFRS and US GAAP are the standards for accounting recognition, measurement and disclosure.

A great overview of accounting concepts is at
[IFRS Conceptual Framework for Financial Reporting] (https://www.ifrs.org/content/dam/ifrs/publications/pdf-standards/english/2021/issued/part-a/conceptual-framework-for-financial-reporting.pdf).

Part B-G in the ACCA syllabus for the FFA exam talk about what abacus-minimal is designed for.

Textbooks and articles:

  1. list of free and open source textbooks
  2. Frank Wood "Business Accounting"
  3. "200 Years of Accounting History Dates and Events"

Project conventions

I use just command runner to automate code maintenance tasks in this project.

just test and just fix scripts will run the following tools:

  • pytest
  • mypy
  • black and isort --float-to-top (probably should replace with ruff format)
  • ruff check
  • prettier for markdown formatting
  • codedown to extract Python code from README.md.

examples/readme.py is overwritten by the just readme command.

I use poetry as a package manager, but heard good things about uv that I want to try.

Changelog

  • 0.14.2 (2024-11-23) Added just sql command to run database examples.
  • 0.14.0 (2024-11-15) Event-based ledger now on main. Mixed test suite and pyright.
  • 0.13.0 (2024-11-15) Event-based ledger will become next minor version.
  • 0.12.0 (2024-11-13) events.py offers events-based ledger modification.
  • 0.11.1 (2024-11-06) abacus.core now feature complete.
  • 0.10.7 (2024-11-02) Posting type is a list of single entries.
  • 0.10.5 (2024-10-27) Handles income statement and balances sheet before and after close.
  • 0.10.0 (2024-10-24) Separates core, chart, entry and book code and tests.

Metadata

Release files for abacus-minimal 0.14.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for abacus-minimal 0.14.2
File Size Uploaded Provenance Actions
abacus_minimal-0.14.2.tar.gz 16.3 kB Without provenance Details for abacus_minimal-0.14.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for abacus-minimal 0.14.2
File Interpreter ABI Platform Actions
abacus_minimal-0.14.2-py3-none-any.whl Python 3 none any Details for abacus_minimal-0.14.2-py3-none-any.whl

Total release size: 30.8 kB

Release files / abacus_minimal-0.14.2.tar.gz

Download URL abacus_minimal-0.14.2.tar.gz
Size 16.3 kB
Tags Source
SHA-256 checksum
How to use checksums
cf736e4841919508dd7fe5b86342c870f88f8f00ee63eb4dccf92ad6c8785a34
BLAKE2b-256 checksum
How to use checksums
9ca821171fa3bcf472a110aa09e806f3c414ad34a6b990e5bca87762e39caa10
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.3 CPython/3.12.1 Linux/6.5.0-1025-azure

Release files / abacus_minimal-0.14.2-py3-none-any.whl

Download URL abacus_minimal-0.14.2-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6b030d967d63ab675fd5eb96a610a03eae321e8bde7eddfb15287363d7df1f1f
BLAKE2b-256 checksum
How to use checksums
e194c6bfcf2c0651ea5ab7602e7eb9a35ff36c995ffb7f2dd952fc358b0a0d13
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.3 CPython/3.12.1 Linux/6.5.0-1025-azure

Security for abacus-minimal 0.14.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page