Statuses
The Statuses editor defines the lifecycle statuses an invoice can take in NomaUBL — codes such as 200 Deposited, 205 Payment received, 9906 In progress. The same codes appear in E-Invoicing → Actions, in the invoice detail modal and in every dashboard widget.
Each row binds a regulatory code to:
- the internal Tag referenced by
InvoiceStatusCatalogfactory methods in Java; - the bilingual labels displayed in the UI;
- the PA Code sent to the Plateforme Agréée API;
- a Collect flag controlling whether the status is polled back from the PA;
- the Groups that map the status to dashboard counters and SQL filters.
The page applies to documents from any source system — JD Edwards, SAP, NetSuite or a custom ERP — once the source is mapped to UBL.
Two changes shipped in 2026.05.5:
- Groups field — each status now declares the top-level counter it belongs to (
inflight,errorTech,errorBusiness,terminal) and the funnel stage it sits in (created,sent,pending,transmission,approved,rejected). The dashboard counters and the SQL filters inDashboardApiread from this single source instead of inlining literalIN ('9904','9905',…)lists. Adding a new PA status is one line in the template. - Tag is read-only —
Tagvalues are referenced byInvoiceStatusCatalogfactory methods in Java; renaming would silently break callers, so the editor protects them. - Inline editor — each row is a card that expands into a 4-column form (Code, Tag, PA Code, Polling on row 1; FR + EN labels spanning two columns each on row 2; Groups multi-select on row 3). The toolbar carries a search box that matches Code, Tag, both labels, PA Code and group labels.
Opening the editor
- Sidebar → Configuration → System → Statuses (or
/settings/statusesdirectly). - The list opens with every status currently declared, ordered by code. Use the search box to filter; click a row to expand it.
At a glance
Per-row fields
| Column | Example | Description |
|---|---|---|
| Code | 200 | Regulatory status code stored in the database (tableHeader). The canonical identifier of the status across NomaUBL. |
| Tag (read-only) | STATUS_DEPOSITED | Internal name referenced by InvoiceStatusCatalog factory methods in Java. The editor displays it as read-only — renaming would break Java callers silently. |
| Label · French | Déposée | Human-readable French label shown in the UI when the active locale is French. |
| Label · English | Deposited | Human-readable English label shown in the UI when the active locale is English. |
| PA Code | fr_e_invoicing_200 | Event name sent to the Plateforme Agréée API — placed in the names[] payload of status calls. Must match what the PA expects exactly. |
| Polling — Collect from PA API | checkbox | When ticked, NomaUBL polls this status from the PA API on every Sync → Retrieve Statuses run. Untick to skip a status during polling. |
| Groups | multi-select | Top-level counter and funnel stage the status belongs to — drives the dashboard widgets and the SQL filters in DashboardApi. See Groups below. |
Use + Add status to create a row. The new row opens immediately with empty fields. Click any row header to expand or collapse the form; click the × icon on the right of the header to delete the row.
Groups
The Groups field replaces the previous CSV columns and inline IN ('9904','9905',…) lists in the dashboard backend. It exposes ten predefined values across two axes:
Top-level — counters and SQL filters
| Value | Label | Used by |
|---|---|---|
inflight | In flight | Dashboard → In flight hero card; SQL filters that count "still moving" invoices. |
errorTech | Error · Tech | Dashboard → Rejected — IT hero card; surfaces technical / pipeline failures (XSL, PDF, PA HTTP, DB). |
errorBusiness | Error · Business | Dashboard → Rejected — Business hero card; surfaces validation / regulation failures the buyer or PA emitted. |
terminal | Terminal | Dashboard → Total drill-down for end-of-life invoices (deposited, paid, archived, refused). |
Funnel stages — pipeline charts
| Value | Label | Used by |
|---|---|---|
created | Stage · Created | Pipeline funnel — created locally but not yet sent. |
sent | Stage · Sent | Pipeline funnel — sent to the PA, awaiting acknowledgement. |
pending | Stage · Pending PA | Pipeline funnel — PA acknowledged, awaiting downstream processing. |
transmission | Stage · Transmission | Pipeline funnel — transmitted to the buyer's PA. |
approved | Stage · Approved | Pipeline funnel / e-Reporting coverage — accepted at every step. |
rejected | Stage · Rejected | Pipeline funnel / e-Reporting coverage — rejected at any step. |
A status declares as many groups as it needs — typically one top-level value plus one stage. The chip palette in the row header mirrors the palette in the multi-select picker so the assignment can be checked at a glance.
The /api/status-codes/groups endpoint serves the merged map, and the React statusGroupsStore caches it once at app boot. Adding a new PA status code becomes a one-line edit in the template — no Java change needed.
How the fields are wired together
- Code is the source of truth in the database (
tableHeader). - Tag is what application code consumes, through
InvoiceStatusCatalogfactory methods. The editor protects it. - Label · French / English drive the UI text. Both should be filled — when a label is empty the UI falls back to the Code.
- PA Code is the contract with the Plateforme Agréée. If the PA renames an event, only the
paCodehere needs to change — the Tag stays stable, so Java code is unaffected. - Collect controls the polling loop driven by Sync → Retrieve Statuses. Statuses set only locally (e.g. internal validation results) usually have Collect off.
- Groups flow into the dashboard counters via
/api/status-codes/groups. A status with no group is effectively invisible to the dashboard.
Tips & best practices
- Keep Codes aligned with the regulation. They are the lingua franca between NomaUBL, the PA and downstream tooling — do not invent custom codes.
- Treat the Tag as a stable internal contract. It is read-only on purpose; if you genuinely need to rename one, do it in
InvoiceStatusCatalogand in this template in the same commit. - Match PA Codes exactly to your PA's catalog. A typo in
fr_e_invoicing_xxxproduces silent integration failures (the PA rejects unknown event names). - Tick Collect only on statuses the PA actually emits. Polling for unsupported statuses wastes API calls and pollutes logs with empty results.
- Assign at least one top-level group to every active status. Otherwise the In flight / Rejected — IT / Rejected — Business hero cards on the dashboard will undercount.
- A status can sit in two top-level groups. A locally-rejected validation that the PA never sees can be both
errorTechandterminal— the dashboard will count it once per axis. - Use the search box. Searching for a partial label or PA Code is faster than scrolling through the full list, especially after a regulation update that adds five or six new codes.
- Bilingual labels are not optional. Both Label · French and Label · English should be filled — the UI falls back to the Code when the active locale's label is empty, which is unhelpful.