Documents and Document Flow
The document is the atomic unit of an ERP. If you understand documents and how they chain, you understand 80% of the system.
Anatomy of a document
Every ERP document has the same shape:
HEADER
document number (from a number range)
document type
company / org assignment
partner(s)
document date ← the real-world date on the paper
posting date ← determines the accounting period
currency + exchange rate
reference (external doc number)
status
created by / at, changed by / at
ITEMS (lines)
line number
material / account / service
quantity + UoM
price + amount
tax code
cost assignment (cost centre, project, order)
reference to predecessor document + line
status
(optional) SCHEDULE LINES — delivery dates and quantities per item
(optional) CONDITIONS — pricing elements per item
(optional) PARTNERS — per header and per item
(optional) TEXTS — header/item notes, some printed, some internal
Header + items + schedule lines + conditions is the canonical four-level shape. Homemade ERPs usually stop at header + items and then discover they need the other two.
Document categories
| Category | Posts to GL? | Changes stock? | Examples |
|---|---|---|---|
| Planning | No | No | Planned order, purchase requisition, forecast |
| Commercial / commitment | No (may create commitment) | No | Quotation, sales order, purchase order, contract |
| Logistics | Usually yes | Yes | Goods receipt, goods issue, delivery, transfer, production confirmation |
| Financial | Yes | No | Journal entry, customer invoice, vendor invoice, payment, credit memo |
| Statistical | No | No | Inquiry, credit memo request pending approval |
The key mental model: an order is a promise. Nothing has happened financially. Only goods movements and invoices create accounting entries.
Document flow — the chain
Order to Cash
Inquiry → Quotation → Sales Order → Delivery → Goods Issue → Billing → Payment → Clearing
│ │ │
(commitment) (stock ↓, COGS) (AR ↑, revenue)
Procure to Pay
Purchase Requisition → RFQ → Quotation → Purchase Order → Goods Receipt → Invoice Receipt → Payment
│ │ │
(commitment) (stock ↑, GR/IR) (GR/IR cleared, AP ↑)
Plan to Produce
Demand → MRP → Planned Order → Production Order → Material Issue → Confirmation → Goods Receipt → Settlement
│ │ │ │
(stock ↓, WIP↑) (activity cost) (FG stock ↑) (variance→P&L)
Record to Report
Sub-ledger postings → GL → Period-end accruals/allocations → Trial balance → Close → Financial statements
Memorise these four chains. Every ERP conversation you will ever have sits inside one of them.
Copy control / document referencing
You rarely create a downstream document from scratch. You create with reference:
- Sales order → Delivery (copies items, quantities, partners)
- Delivery → Billing document
- Purchase order → Goods receipt
- Invoice → Credit memo
The rules for what copies, what can change, and what’s checked are in copy control configuration. This is where “why did the price recalculate on the invoice?” questions get answered.
Document flow tracking
Every ERP maintains a link table:
CREATE TABLE document_flow (
predecessor_doc VARCHAR(20),
predecessor_item INT,
successor_doc VARCHAR(20),
successor_item INT,
quantity_referenced NUMERIC(18,6),
value_referenced NUMERIC(18,2),
flow_type VARCHAR(10)
);
This drives:
- The “document flow” screen users love (click from invoice back to the original order)
- Open quantity calculation:
PO qty − sum(received qty)= still to receive - Preventing over-delivery and over-invoicing beyond tolerance
- Audit traceability from a journal line back to the originating business event
If you build your own ERP, build this table on day one. Retrofitting document flow is nearly impossible.
Status management
Statuses are usually derived, not stored as a single field:
Item status = f(delivered qty, invoiced qty, ordered qty, blocks, rejection)
Not delivered → delivered_qty = 0
Partially delivered→ 0 < delivered_qty < ordered_qty
Fully delivered → delivered_qty >= ordered_qty (within tolerance)
Completed → fully delivered AND fully invoiced
Rejected → rejection reason set
Header status = aggregate of item statuses. Common design mistake: storing header status directly and letting it drift out of sync with the items.
Additional orthogonal statuses: blocked (credit block, quality block, delivery block, billing block), approval status, release status.
Immutability and correction
Once a document posts to the ledger, it cannot be changed. Corrections:
| Wrong thing | Correction |
|---|---|
| Journal entry posted incorrectly | Reversal document (mirror entry, linked) |
| Customer over-invoiced | Credit memo |
| Customer under-invoiced | Debit memo / supplementary invoice |
| Goods receipt wrong quantity | Reversal / return delivery movement |
| Wrong cost object | Repost / reallocation journal |
The reversal is itself a document, linked to the original, and both remain visible forever. Users will ask you to “just delete it”. The answer is no, and the reason is that auditors must see that a mistake was made and corrected.
Before posting, documents in “parked”, “held”, or “draft” state can be edited or deleted freely. The park/post boundary is the immutability boundary.
Number ranges
Document numbers are not sequences you can casually change. See Number Ranges and Keys. Key point: legal invoice numbering in most countries must be gapless and sequential per legal entity per year, which is at odds with high-concurrency database sequences.
Document types
Within each category, the document type varies behaviour:
| Sales order types | Behaviour |
|---|---|
| Standard order | Normal flow |
| Rush order | Delivery created immediately at order save |
| Cash sale | Delivery and billing at once, cash posting |
| Free-of-charge delivery | No billing, no revenue |
| Returns order | Reverse flow, returns delivery, credit memo |
| Consignment fill-up | Stock moves, no sale yet |
| Credit memo request | Requires approval before billing |
Document type controls: number range, screen layout, pricing procedure, output determination, allowed follow-on documents, account determination, and approval requirements. It’s the main configuration lever in the transaction world.
Practical rules
- Header/item/schedule-line/condition — build all four levels or plan to.
- Every downstream document links to its predecessor, at line level, with the referenced quantity.
- Derive status; don’t store it as truth.
- Snapshot master data onto the document (price, address, tax code, payment terms) so reprints are faithful.
- Separate
document_datefromposting_datefromcreated_at. They are three different things and finance needs all three. - Draft vs posted is a hard state boundary, with different rules on each side.