KB-212 – Accounting Engine Architecture¶
Knowledge Base ID: KB-212
Chapter: 5 - Fact & FactLine
Project: BLACK ERP
Version: 0.5
Status: Draft
Last Updated: 2026-06-26
Applies To: ADempiere 3.9.4
Purpose¶
This chapter explains how ADempiere represents accounting entries internally before they are persisted into the General Ledger.
The Fact and FactLine classes are the core accounting objects responsible for building journal entries during the posting process.
Understanding these classes is essential before analyzing any specific accounting implementation.
Conceptual Model¶
The Accounting Engine never writes directly into the FACT_ACCT table.
Instead, it constructs an in-memory accounting document composed of one or more accounting lines.
Business Document
│
▼
Doc
│
▼
Fact
│
▼
FactLine
│
▼
FACT_ACCT
Only after all validations succeed are the generated accounting entries persisted into the database.
The Fact Class¶
Class:
org.compiere.acct.Fact
A Fact represents a complete accounting document for a specific accounting schema.
It contains:
- Accounting Schema
- Posting Type
- Currency
- Accounting Lines
- Posting Metadata
Conceptually, one Fact is equivalent to one accounting journal.
The FactLine Class¶
Class:
org.compiere.acct.FactLine
Each FactLine represents a single accounting movement.
Every line contains:
- Account Combination
- Debit Amount
- Credit Amount
- Currency
- Organization
- Business Partner
- Product
- Project
- Campaign
- User Dimensions
Multiple FactLine objects compose a single Fact.
Object Relationship¶
Doc
│
▼
Fact
│
├──────────────┐
▼ ▼
FactLine FactLine
│ │
▼ ▼
Debit Credit
A valid accounting document always contains balanced debit and credit lines.
Posting Sequence¶
The Accounting Engine follows a consistent sequence.
Instantiate Fact
↓
Create Debit FactLine
↓
Create Credit FactLine
↓
Validate Balance
↓
Persist into FACT_ACCT
No database records are written until the Fact is complete.
Fact Creation¶
Each Doc_* implementation is responsible for constructing one or more Fact objects.
Typical pattern:
Fact fact = new Fact(...);
fact.createLine(...);
fact.createLine(...);
return facts;
The document-specific implementation determines:
- Which accounts are used.
- Which amounts are posted.
- Which dimensions are assigned.
The posting infrastructure itself remains generic.
Multiple Facts¶
A single business document may generate multiple accounting documents.
Examples include:
- Different Accounting Schemas.
- Different Posting Types.
- Parallel Accounting.
Conceptually:
Invoice
↓
Fact (Primary Ledger)
↓
Fact (Secondary Ledger)
↓
Fact (Tax Ledger)
Each Fact remains independent while sharing the same business document.
Account Resolution¶
FactLine objects never invent accounting accounts.
Instead, they receive valid account combinations previously resolved by the Doc class.
Doc
↓
Resolve Account
↓
Valid Combination
↓
FactLine
This separation keeps account determination independent from accounting persistence.
Persistence¶
After successful validation, every FactLine is stored in:
FACT_ACCT
Each row represents a single debit or credit movement.
Conceptually:
Fact
↓
FactLine
↓
FACT_ACCT Record
BLACK ERP Example¶
Our Mexican VAT Cash Basis implementation follows the standard architecture.
Doc_AllocationHdr
↓
MXVATCashBasisEngine
↓
Fact
↓
FactLine (119.001)
↓
FactLine (118.001)
The customization generates additional accounting lines while preserving the standard posting workflow.
Engineering Notes¶
When implementing accounting customizations:
- Never write directly to
FACT_ACCT. - Always create
FactLineobjects. - Keep all accounting logic inside the corresponding
Doc_*implementation. - Allow the Accounting Engine to persist the results.
Following this pattern preserves compatibility with future ADempiere upgrades.
Key Takeaways¶
Factrepresents an accounting document.FactLinerepresents an accounting movement.- Multiple
FactLineobjects compose a balanced journal. - Only completed
Factobjects are persisted. FACT_ACCTis the persistence layer, not the business logic.
Next Chapter¶
Chapter 6 explains how ADempiere resolves accounting accounts using MAcctSchema, MAccount, and MAccountLookup before creating FactLine objects.
Revision History¶
| Version | Date | Description |
|---|---|---|
| 0.5 | 2026-06-26 | Added Fact and FactLine architecture. |