The Number on the Document
Document numbers here are sequential per organisation, per document type, per prefix and per year, zero-padded, and safe when two people create documents at the same moment. What the key does not contain is a branch — so ten sites share one run of numbers.
Nobody evaluates software on its numbering. Everybody has an opinion about it three months after go-live, usually expressed as a question about why the invoices from one branch are interleaved with another.
The position, up front
One sequence per organisation, per document type, per prefix, per year. It is gapless, ordered, zero-padded and concurrency-safe. It has no branch or site component, so a multi-site business gets one interleaved run per document type — and there is no setting that changes it.
What the sequence actually is
A row identified by four things: your organisation, the document type, the prefix, and the year. Ask for the next number and the row is created if it does not exist, read, incremented and written back — all inside a transaction, which is the detail that matters.
Two people raising invoices at the same instant get consecutive numbers rather than the same one. That sounds like a small thing until it happens, at which point it is two documents with one number and a customer asking which is which.
The year is a real part of the key, so sequences restart each year. And numbers are padded — six digits by default — so they sort correctly as text, which every spreadsheet anybody exports them into will do.
Gapless, ordered, padded, and safe when two people press save together. That is most of what numbering is for.
What is not in the key
A branch. A warehouse. A site. A salesperson. A customer category. None of those form part of the sequence, so none of them can have a run of their own.
For a single-site business that is exactly right and simpler than the alternative. For a business with several branches it produces a specific, ordinary irritation.
| What a multi-site business wants | What happens |
|---|---|
| Each branch with its own run | One shared run per document type |
| A branch identifiable from the number | Not encoded — the number says nothing about where it came from |
| A gapless sequence per branch for a local reconciliation | Gapless overall, interleaved per branch |
| A prefix per branch | The prefix is set by the code path, not by configuration |
| Sequences restarting each year | Yes — the year is part of the key |
The third row is the one with a real consequence. A branch manager reconciling their own documents sees a run with holes in it — not because anything is missing, but because the missing numbers went to other branches. Explaining that once is fine. Explaining it every month to five managers is a process cost.
Why distance makes this worse than it sounds
A Mongolian business operating out of the capital with branches in the aimags is running sites that are genuinely far apart, sometimes with intermittent connectivity, and often reconciling locally before anything is consolidated.
Local reconciliation is where an interleaved sequence stops being cosmetic. The natural check a branch performs — do I have every document from the last one to this one — cannot be performed, because the sequence is not theirs.
The workaround is not elegant and it does work: reconcile by date range and count, not by sequence. Ask "how many documents did this branch raise in this period, and does that match what I have" rather than "is the run unbroken". It answers the same question and it does not depend on the numbering.
A branch in the key
The sequence service is well built and the change is a narrow one — an extra component in the key and a way to configure the prefix. Worth being honest that it is not free: existing sequences would need a decision about what happens to numbers already issued.
A site component in the sequence key
One more column in the key and one more argument at the call site. Mechanically small; the migration question is the real work.
A configurable prefix per document type
Today the prefix is passed by the code path rather than set by you. Making it configurable is small and is what most people actually mean when they ask for branch numbering.
A per-branch sequence report
The cheapest of the three and possibly sufficient: a listing that shows a branch its own documents in order, so a local reconciliation is possible without changing the numbers.
No dates on a public page. If branch-level document numbering is a requirement rather than a preference, describe how many sites and whether the numbers appear on customer-facing documents, and we will scope it in writing.
Scope document numberingThree questions about document numbering
Two users create an invoice at the same moment. What numbers do they get?
A good answer sounds like
Consecutive ones.
What it actually means
Ours handles this inside a transaction. It is the single most common numbering defect and it only appears under load, which is to say after go-live.
Does the sequence reset each year?
A good answer sounds like
Yes or no, deliberately.
What it actually means
Ours resets, because the year is part of the key. Either is defensible; a system that has not decided will surprise you in January.
Can a branch have its own run?
A good answer sounds like
Yes, configurable.
What it actually means
Ours cannot. Ask before go-live, because renumbering after the fact is not something anybody should attempt.
What AWRA OpsHub does today
- Sequential document numbers per organisation, per document type, per prefix and per year.
- The read, increment and write performed inside a transaction, so simultaneous creation produces consecutive numbers.
- Zero padding, six digits by default, so numbers sort correctly as text.
- Sequences that restart each year, with the year as part of the key.
- Numbers issued the same way across document types rather than each module inventing its own scheme.
What it does not do
- Any branch, warehouse or site component in the sequence key.
- A configurable prefix. The prefix is supplied by the code path rather than by a setting.
- Per-branch sequence reporting, so a local gapless reconciliation is not possible.
- Manual number assignment or a way to reserve a number.
- Any encoding of a location, a period beyond the year, or a salesperson in the number itself.
Not ours, by choice
- Gapless and concurrency-safe are the two properties that matter most and both are present. The branch question is a fit question, not a defect.
- Reconciling by date range and count is a genuine substitute for reconciling by sequence, and it is what we would recommend regardless.
- Nothing here is Mongolian. It is what a shared sequence does across sites; long distances are what make local reconciliation the normal practice.
Decide your numbering before your first document
It is the one thing that genuinely cannot be changed afterwards without confusing every customer who has a filed copy. Ten minutes before go-live, and never again.
Settle the numberingFrequently asked questions
Can I choose the prefix on my invoices?
The prefix is supplied by the code path that issues the number rather than by a setting, so it is consistent across the product and not configurable by you. If a specific prefix matters — because it appears on customer-facing documents or matches a legacy scheme — raise it before go-live rather than after.
What happens in January?
The year is part of the sequence key, so a new year starts a new run from the beginning. Plan your reconciliation around that: a year-end comparison is by count within the year, not by continuing sequence.
Are numbers ever reused or skipped?
The increment happens inside a transaction, so two simultaneous requests get different numbers rather than the same one. A document created and then deleted leaves its number unused, which is a gap rather than a reuse — and that is the correct behaviour, because reissuing a number is far worse than skipping one.