Skip to main content

Configurable double-entry accounting package for Django REST Framework

Project description

django-accounting

A configurable, installable double-entry accounting package for Django REST Framework.

Covers: Chart of Accounts · General Ledger · Accounts Receivable · Accounts Payable · Inventory with batch/expiry tracking · Multi-warehouse · Tax rates & groups.


Installation

pip install django-accounting

Add to INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "django_accounting.core.apps.CoreConfig",
    "django_accounting.ledger.apps.LedgerConfig",
    "django_accounting.tax.apps.TaxConfig",
    "django_accounting.inventory.apps.InventoryConfig",
    "django_accounting.ar.apps.ARConfig",
    "django_accounting.ap.apps.APConfig",
]

Add URLs:

# urls.py
path("api/accounting/", include("django_accounting.urls")),

Run migrations:

python manage.py makemigrations \
    accounting_core accounting_ledger accounting_tax \
    accounting_inventory accounting_ar accounting_ap
python manage.py migrate

Configuration

All settings go under a single ACCOUNTING dict in settings.py. Every key is optional — the defaults are shown below.

ACCOUNTING = {
    # ── Currency & precision ─────────────────────────────────────────────
    "DEFAULT_CURRENCY": "PHP",       # ISO 4217 code
    "MONEY_DECIMAL_PLACES": 2,       # monetary amounts (invoice totals, etc.)
    "COST_DECIMAL_PLACES": 6,        # unit costs (preserves precision)
    "QTY_DECIMAL_PLACES": 4,         # quantities
    "RATE_DECIMAL_PLACES": 4,        # tax rates

    # ── Document number prefixes ─────────────────────────────────────────
    "INVOICE_NUMBER_PREFIX": "INV",
    "BILL_NUMBER_PREFIX": "BILL",
    "JOURNAL_ENTRY_PREFIX": "JE",
    "PAYMENT_NUMBER_PREFIX": "PAY",

    # ── Feature flags ────────────────────────────────────────────────────
    "ENABLE_BATCH_TRACKING": True,   # enforce batch FK on items/movements
    "ENABLE_EXPIRY_TRACKING": True,  # enforce expiration_date on batches
    "ENABLE_MULTI_WAREHOUSE": True,  # allow multiple warehouse locations
    "ENABLE_TAX": True,
    "ENABLE_SOFT_DELETE": False,     # soft-delete instead of hard-delete
    "AUTO_POST_JOURNAL_ENTRIES": False,

    # ── Defaults ─────────────────────────────────────────────────────────
    "DEFAULT_PAYMENT_TERMS_DAYS": 30,
    "DEFAULT_CREDIT_LIMIT": "0.00",
    "EXPIRY_WARNING_DAYS": 30,       # used by /item-batches/expiring_soon/

    # ── Swappable models ─────────────────────────────────────────────────
    "CUSTOMER_MODEL": None,          # e.g. "myapp.ExtendedCustomer"
    "VENDOR_MODEL": None,

    # ── Serializer behaviour ─────────────────────────────────────────────
    # Inject extra read-only fields onto any serializer by model name:
    "SERIALIZER_EXTRA_FIELDS": {
        "Invoice": ["erp_reference"],
        "Customer": ["loyalty_tier"],
    },

    # Mark fields as write-once (read-only on updates) by model name:
    "SERIALIZER_WRITE_ONCE_FIELDS": {
        "Invoice":      ["invoice_number", "customer"],
        "Bill":         ["bill_number", "vendor"],
        "JournalEntry": ["entry_number"],
    },
}

API Endpoints

All endpoints are under /api/accounting/ (or your configured prefix).

Resource URL
Accounts (COA) /accounts/ + /accounts/tree/
Fiscal Years /fiscal-years/
Fiscal Periods /fiscal-periods/
Journal Entries /journal-entries/
Tax Authorities /tax-authorities/
Tax Rates /tax-rates/
Tax Groups /tax-groups/
Item Categories /item-categories/
Items /items/
Item Batches /item-batches/ + /item-batches/expiring_soon/
Warehouses /warehouses/
Warehouse Locations /warehouse-locations/
Inventory Balances /inventory-balances/ (read-only)
Inventory Movements /inventory-movements/
Customers /customers/
Invoices /invoices/
Payments /payments/
Invoice Payments /invoice-payments/
Vendors /vendors/
Bills /bills/
Bill Payments /bill-payments/

Serializer features

Dynamic field selection

Trim any response via query params — available on every endpoint:

GET /invoices/123/?fields=id,invoice_number,total_amount
GET /customers/456/?exclude=phone,address

Or pass via code:

InvoiceSerializer(invoice, fields=["id", "total_amount"])

Write-once fields

Fields listed in ACCOUNTING["SERIALIZER_WRITE_ONCE_FIELDS"] become read-only on updates. The defaults protect invoice_number, bill_number, and entry_number. Add your own:

ACCOUNTING = {
    "SERIALIZER_WRITE_ONCE_FIELDS": {
        "Invoice": ["invoice_number", "customer", "currency"],
    }
}

Extra fields

Inject additional read-only fields onto any serializer without subclassing:

ACCOUNTING = {
    "SERIALIZER_EXTRA_FIELDS": {
        "Customer": ["loyalty_points"],   # must exist on the model
    }
}

Extending models

Swappable Customer / Vendor

# myapp/models.py
from django_accounting.ar.models import Customer

class ExtendedCustomer(Customer):
    loyalty_points = models.IntegerField(default=0)
    assigned_rep = models.ForeignKey("auth.User", null=True, on_delete=models.SET_NULL)
# settings.py
ACCOUNTING = {"CUSTOMER_MODEL": "myapp.ExtendedCustomer"}

Lifecycle signals

Connect to any of these in your AppConfig.ready():

from django_accounting.signals import invoice_posted, batch_expiring_soon

@receiver(invoice_posted)
def on_invoice_posted(sender, invoice, journal_entry, **kwargs):
    send_invoice_email(invoice)

@receiver(batch_expiring_soon)
def on_expiry_warning(sender, batch, days_remaining, **kwargs):
    notify_warehouse_manager(batch, days_remaining)

Available signals: account_created, journal_entry_posted, invoice_created/posted/paid/voided, bill_created/posted/paid/voided, payment_received, payment_applied, disbursement_made/applied, inventory_received/issued/transferred/adjusted, batch_created, batch_expired, batch_expiring_soon, low_stock_alert.


Running tests

pip install -e ".[dev]"
pytest

Package structure

django_accounting/
├── conf.py              ← ACCOUNTING settings + helpers
├── mixins.py            ← Abstract model mixins (UUID, timestamps, soft-delete, currency)
├── serializer_mixins.py ← DynamicFields, WriteOnce, ExtraFields
├── signals.py           ← Lifecycle signals
├── admin.py             ← Django admin registrations
├── apps.py              ← AppConfig for each sub-app
├── urls.py              ← DRF router + ViewSets
├── core/                ← Account, FiscalYear, FiscalPeriod
├── ledger/              ← JournalEntry, JournalLine
├── tax/                 ← TaxAuthority, TaxRate, TaxGroup, TaxLine
├── inventory/           ← Item, ItemBatch, Warehouse, InventoryBalance, InventoryMovement
├── ar/                  ← Customer, Invoice, Payment, InvoicePayment
└── ap/                  ← Vendor, Bill, BillPayment

License

MIT

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

django_accounting_dminozadev-1.0.1.tar.gz (41.7 kB view details)

Uploaded Source

Built Distribution

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

django_accounting_dminozadev-1.0.1-py3-none-any.whl (52.1 kB view details)

Uploaded Python 3

File details

Details for the file django_accounting_dminozadev-1.0.1.tar.gz.

File metadata

File hashes

Hashes for django_accounting_dminozadev-1.0.1.tar.gz
Algorithm Hash digest
SHA256 8266e2792f74cf5b405f63dcd9961471272fc4f0646c26c17f826e9a1cffac32
MD5 a329b6d39cec6f95b16ddbf1571b5cbb
BLAKE2b-256 d0998c1dc97bab9a56386bf4841b7e281af9be98bf257a242460b591d9678d46

See more details on using hashes here.

File details

Details for the file django_accounting_dminozadev-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_accounting_dminozadev-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0f9b2ca956884de8c42af039939a3ac9788054d2c298002aa34830cc2a0b6b94
MD5 1fb776e49abce5945a4c938313905f6e
BLAKE2b-256 2af5f04fb5babe1ba1ce2f795e8176e4e3367a72daf60e83dcaee8b8e9a20e1f

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