In GLPI, native "approval" is a single round. You request validation from one or more people, set an acceptance percentage, and that is it - there is no hierarchical chaining where finance is only asked after the line manager has approved. NexTool's Approval Flow module fills exactly that gap.
The problem: hierarchical approval does not exist in the core
In corporate environments, approving a ticket usually spans more than one level: the line manager clears it, then finance validates the budget, then the board signs off. It is a sequential flow - each step only makes sense after the previous one approved. GLPI does not model this.
What the core offers is a single validation round. You open the approvals tab, pick validators (users or groups) and set the validation_percent field - the share of approvals needed for the ticket to count as validated. Every validator receives the request at the same time. There is no ordering, no "level 2 only fires if level 1 approves", no separate path for when someone refuses.
Why emulating levels with validation_percent does not work
In our support and maintenance practice, the design we see most often is trying to force a sequence with the percentage field: the team requests validation from three people and sets 100%, expecting a chain. It is not one. All three receive the request simultaneously - the board sees it before the line manager has even looked. Worse: if one refuses, the ticket goes to REFUSED, but the others' requests stay pending in their "my validations" queue, cluttering each approver's view. And there is no way to say "if refused, escalate to another level" or "if approved, close automatically with this solution template". The usual outcome is the team abandoning the native feature and handling the chain over email, outside the system - which kills traceability and opens an audit gap.
How Approval Flow works
The Approval Flow module adds multi-level approval flows tied to the tickets' ITIL categories, reusing GLPI's own native validation templates (ITILValidationTemplate) - so approvers keep using the standard approvals tab, with no parallel screen.
- One flow per ITIL category - each category has at most one active flow, removing any ambiguity about which rule applies to this ticket.
- Chained levels in a tree - each level has independent paths for approval and refusal, so you set different outcomes per branch.
- Configurable action per outcome - on approval or refusal you choose what happens: do nothing, solve, close or advance to the next level.
- Standardized solution - when the action is solve or close, binding a SolutionTemplate is mandatory, guaranteeing the same message to the requester across every ticket.
- Automatic trigger - when a ticket is created in a category with an active flow, the first-level validation is requested on its own, with no one having to remember to open the approvals tab.
- Users or groups per level - each level can point to a specific person or a group, using the same targets as the native validator.
| Aspect | Native GLPI validation | Approval Flow |
|---|---|---|
| Rounds | A single flat round | Chained levels in a tree |
| Sequence | Everyone gets it at once | Next level only fires after the previous one approves |
| Refusal | global_validation = REFUSED, no follow-up action | Its own refusal path (solve, close or escalate) |
| Trigger | Manual, via the approvals tab | Automatic per ITIL category when the ticket opens |
| Approvers | Users or groups, all peers | User or group set per level |
| Action after the decision | None automatic | Solve/close via SolutionTemplate or advance |
Diagnostics: where to read the approval state
Before designing a flow, it helps to know where GLPI keeps the native state - that is what the module orchestrates underneath. Two queries cover the read:
-- GLPI: inspect a ticket's native validation state.
-- global_validation and status follow CommonITILValidation:
-- 1 = NONE (not subject to approval)
-- 2 = WAITING (awaiting)
-- 3 = ACCEPTED (approved)
-- 4 = REFUSED (refused)
SELECT id, name, global_validation, validation_percent
FROM glpi_tickets
WHERE id = 12345;
-- Individual requests: natively they are all "peers" in the SAME round.
-- There is no "level" column and no hierarchical ordering.
SELECT tickets_id, status, submission_date, validation_date
FROM glpi_ticketvalidations
WHERE tickets_id = 12345
ORDER BY submission_date;
If you are already trying to simulate levels with several validators, the second query makes the problem obvious: multiple rows in status = 2 (WAITING) at the same time, with no column expressing order. That is the gap the chained flow closes.
How to enable it
- Install NexTool on your GLPI (10.0+ or 11.0+).
- Go to Setup > NexTool > Modules.
- Enable Approval Flow and click Configure.
- On the Flows tab, create a flow and bind it to the desired ITIL category.
- Define the levels, the approvers (user or group) and the action for each outcome (approve/refuse).
- For solve or close actions, bind the matching SolutionTemplate.
Who it is for (and when not to use it)
It fits organizations that need formal IT governance: access requests, purchases, infrastructure changes, any ticket that requires a hierarchical sign-off with traceability inside GLPI itself. Also teams running ITIL that do not want their approval chain living in an inbox.
It is not worth it if your approval is a single level - the native GLPI validation already handles that, and adding a chained flow only piles on configuration with no gain. It also does not replace a full BPM engine: the scope is ticket approval, not orchestrating arbitrary processes with forms and external integrations.
Compatibility
- GLPI: 10.0+ and 11.0+
- Plan: PAID
- Plugin: NexTool 3.x+
Next step
Approval Flow is part of NexTool, an ecosystem of modules that extends GLPI without touching core code. Talk to the team to see the multi-level flow running against your scenario.
This content was produced with the help of artificial intelligence and reviewed by the NexTool Solutions team.