HR Workflow Engine for Odoo 16
One declarative state machine that every HR document shares, so a new approval step is a data change, not a Python deploy.
Why this module
HR Workflow Engine for Odoo 16
A new step is a data change
States and transitions are records on eh.hr.workflow.definition. Adding a transition, reordering states, or pointing a step at a different next state is editing data in the Workflows screen, never a Python deploy. The status bar and the available buttons follow the definition automatically.
The same lifecycle everywhere
Models inherit one mixin and set a workflow code. They gain a dynamic state field, an initial state on brand-new unsaved forms, a state label, and action_transition. The platform already wires this engine into more than twenty HR document types so they behave consistently.
Transitions that refuse to misbehave
Every advance checks that the transition is defined from the current state, that final states reject further moves, and that the user holds one of the transition's allowed groups. Gated transitions hand off to the approval engine, which captures the real submitter so a person cannot approve their own request.
Day in the life
An attendance correction moves through its lifecycle
An employee saves a correction; the form already shows the initial state from the definition because the default is resolved before the first save. They press Submit, which calls action_transition with the submit code. The engine confirms the transition exists from the current state, writes the new state, and emits a workflow.transition event that lands in the append-only audit log with a correlation id. Because the submit transition is marked requires_approval, the engine opens an approval request through eh.hr.approval.engine, recording the submitter so they cannot later approve it themselves. When an approver with the right group decides, the approval engine fires the follow-up approve or refuse transition back into the workflow, and the record reaches its final state, after which no further transition is allowed.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
A record in a state flagged is_final rejects every further transition with a clear error, even one a misconfigured definition declares from it. The terminal marker is authoritative, not the transition table.
When a gated transition opens an approval request, the engine captures the real submitter before its internal sudo, so the user who fired the transition cannot approve their own request even if they hold an approver group.
The state advance is unconditional and the approval handoff is a side effect on the follow-up step, so a submit no longer leaves the record stuck in its pre-submit state or fires repeated approval requests against the same record on close.
If a transition declares allowed groups, only members of those groups (or the admin) can execute it; everyone else is refused. An empty group list means any owner may run it.
The transition code can arrive positionally from server callers or from the view context for header buttons, which cannot pass positional arguments, and a missing code raises rather than silently passing.
A database constraint enforces one active definition per workflow code, so a model never resolves an ambiguous state machine. The constraint is declared in the version-correct form for Odoo 16.
Every transition emits a typed platform event that is cross-written to the append-only, hash-chained audit log, so the lifecycle of a record is reconstructable after the fact.
What is inside
Built to do the job, end to end.
- Four data models. eh.hr.workflow.definition holds the code, name, initial state, and active flag; eh.hr.workflow.state carries code, name, sequence, kind, and the is_final marker; eh.hr.workflow.transition carries from and to states, allowed groups, the requires_approval flag, an approval chain code, and an optional post-action method name.
- The consumer mixin. eh.hr.workflow.mixin builds on the platform mixin and exposes a dynamic Selection state field, a state label, a default initial state, action_transition, and audit emission. A model joins by inheriting it and declaring its workflow code.
- Service entry point. A registered eh.hr.workflow.engine service exposes apply_transition so other engines, such as the approval engine after a chain approves, can drive a transition programmatically rather than through the UI.
- Configuration UI. A Workflows form under the HR configuration menu, restricted to the HR admin group, lets you edit definitions with inline State and Transition tabs, including drag-handle ordering of states.
- Access control. Shipped record rules give the HR admin group full read and write on definitions, states, and transitions, and the HR officer group read-only visibility.
Honest about the edges
What this does not do, so nothing surprises you.
- This is a platform engine, not a standalone app. It depends on eh_hr_core and is intended to back EH HR Platform document modules, not to be used in isolation.
- Approval routing, escalation, and multi-step chains live in the separate approval engine. This module hands gated transitions off to it and applies the follow-up transition it returns; it does not implement the approval ladder itself.
- States and transitions are configured as data through the Workflows screen or XML. There is no drag-and-drop visual flow designer.
- The module ships no automated test suite of its own. Workflow behavior is exercised by tests in consumer modules such as attendance and leave.
- Events publish on the in-process bus and the audit log. Clustered or cross-host delivery would need a queue or broker adapter in place of the in-process bus.
- Transition rules cover state validity, final-state guarding, and group membership. Field-level or value-based conditions on a transition are not part of the definition model.
Odoo 16 HR workflow engine, declarative state machine Odoo, configurable HR approval workflow, Odoo status bar workflow, HR document lifecycle Odoo, transition security groups Odoo, data-driven workflow Odoo 16, HR audit log Odoo, no-code workflow Odoo, eh_hr_core platform, HR approval handoff, Odoo Community HR engine
Please log in to comment on this module