dodil/erp-brick-gl

DODIL ERP brick: general ledger

README.md

erp-brick-gl: the books

Every transaction as a balanced entry, account balances you can trust, month-end and year-end close, and the reports your accountant asks for - fed by the rest of the business rather than re-keyed from it. Built from the gl module spec, version 3 (SAP FI-GL at mid-market scope): brick_gl, tables gl_*, namespace gl.

  • One path writes a journal. ar, payments, tax, purchasing, inventory and fixed-assets post to POST /journal-entry/journals (idempotent by source, gl:journal:post, a service client). A posting that names no company, ledger or profit centre lands in the default company and every ledger, so the built callers' bodies work unchanged.
  • Companies, ledgers, dimensions. Several legal entities in one bucket, a leading ledger and parallel ones (IFRS beside local GAAP), profit centres, segments and cost centres derived on every line, document splitting (active, passive, zero-balance) from a year's first day.
  • Periods and years. Close per company with readiness gates {gate, met, reason, fix}; the carry-forward is derived (no closing journal); audit adjustments after the last close; a closing cockpit with a second-person sign-off.
  • Scheduled work, posted once per key. Recurring entries, accruals and deferrals, allocation cycles (simulate, post, reverse), FX revaluation of balances and of open items, the period-end re-split, auto-reversals.
  • Intercompany: one proposal posts in both companies with the due-to/due-from lines made; matching per pair before the close.
  • Reports: trial balance (opening, movement, closing, per ledger and dimension), account lines with a running balance, the account-tree rollup, financial statement versions, the cash-flow statement, plan against actual, the group extract consolidation reads.
  • Audit: a hash chain per company (GoBD), FEC and SAF-T exports stored as objects with their sha-256, a change log of master data.
  • Odoo migration: load, id map (GET /migration-map/{db}/{model}), reconcile on both sides, explain, the owner signs.

Both doors are generated from application/*.py (a route and an MCP tool per use case, named as the spec's transitions). See AGENTS.md for where a change goes and the rules that must not be undone; src/brick_gl/roles.yaml for the default roles.

python -m venv .venv && .venv/bin/pip install -e '.[test]'
.venv/bin/pytest -q --tb=short
erp-compose check tests/tier1.compose.yaml --strict --roles src/brick_gl/roles.yaml

Run it on a bucket: BUCKET=... uvicorn brick_gl.app:app, erp-migrate (or erp-compose migrate) applies migrations/00001_init. Neighbours are optional and found by name: PAY_BASE_URL, PUR_BASE_URL, AR_BASE_URL, FA_BASE_URL, BP_BASE_URL, TAX_BASE_URL. Objects (statutory files) go to DataK3's S3 endpoint when OBJECT_ACCESS_KEY/OBJECT_SECRET_KEY are set, else to gl_object.