GLPI knows how many toners you have in stock, but not which ticket the last one left on. Consumables are native (ConsumableItem), the stock-out is manual and disconnected from the ticket - so when it is time to audit a period's consumption or justify a ticket's cost, the information simply does not exist. NexTool's Stock module closes that gap by linking the two sides GLPI left apart.
The problem
GLPI has a native consumables module - ConsumableItem, stored in the tables glpi_consumableitems (the consumable model) and glpi_consumables (each physical unit). It tracks quantity, entry and exit: taking a unit out is, at heart, filling that row's date_out column. The problem is not stock control itself - it is that this stock-out is born loose. Natively, a consumable is "given" to a user or a group, never to a ticket. So when a technician uses three memory sticks solving a request, they do record the exit, but nowhere is it stored that those three sticks left because of that ticket.
The consequences show up later. Auditing a period's consumption by ticket becomes impossible: the data lives on two islands that never cross. Costing the consumables of a single request turns into the technician's memory exercise. And the manual stock-out, done outside the ticket flow, opens the door to the most common mistake of all - forgetting to record it, or recording it against the wrong consumable, with no one to double-check.
How it works
The Stock module builds a two-way bridge between tickets and native consumables, without duplicating data: it keeps writing to glpi_consumables, only now tying each exit to the ticket that caused it.
- Stock tab on the ticket - the technician picks the consumable and quantity inside the ticket itself and debits right there, without switching screens.
- Exits tab on the consumable - the same movement shows on the consumable record, with the linked ticket visible.
- Real-time balance validation - before debiting, the module checks the available balance using GLPI's native calculation (units with an empty
date_out), blocking any stock-out above what exists. - Write to native stock - the exit fills
date_outon the consumed units and writes the ticket link on the native row itself, keeping GLPI's stock consistent. - Reversal with configurable return - an exit can be reversed in one click, returning the units to stock; the behavior is configurable.
- Reports with CSV export - a movements panel with filters by period, consumable and status, and a CSV export button for the spreadsheet.
- Ticket required - an option that forces every exit to be linked to a ticket, closing the door on stock-outs without traceability.
How to enable it
- Install NexTool on your GLPI (10 or 11).
- Go to Setup > NexTool > Modules.
- Enable the Stock module and click Configure.
- In the settings tab, define whether a reversal returns the consumable to stock and whether a ticket is mandatory on every exit.
Native vs. Stock module
The point is not to replace the native consumable - it is to extend it. The table shows where the native behavior stops and where the module carries on:
| Feature | Native GLPI (ConsumableItem) | Stock module |
|---|---|---|
| Stock-out linked to the ticket | Manual, assigned to a user or group (itemtype User/Group) - no link to the ticket | Debits from inside the ticket and writes itemtype = 'Ticket' on the native row |
| Balance validation | Tracks the balance, but outside the ticket flow | Checks the balance in real time on the ticket tab, before debiting |
| Reversal | Manual return, editing the unit to clear the exit | One-click reversal, with configurable return |
| Auditable traceability | Records who received it, not which ticket caused it | Movement with ticket, consumable, quantity, user and date |
| CSV report by period | Listing per consumable, no ticket breakdown | Panel with period and status filters, exportable to CSV |
Diagnosing straight in the database
While you evaluate the module - or just to check what the native side records - you can measure balance and exits straight in GLPI's tables. The two queries we use:
-- Real balance per consumable, straight from GLPI's native tables.
-- Each glpi_consumables row is ONE physical unit: empty date_out = in stock,
-- filled date_out = already consumed. glpi_consumableitems is the consumable model.
SELECT ci.id AS consumable_id,
ci.name AS consumable,
SUM(c.date_out IS NULL) AS in_stock,
SUM(c.date_out IS NOT NULL) AS consumed,
COUNT(c.id) AS total_registered
FROM glpi_consumableitems ci
LEFT JOIN glpi_consumables c ON c.consumableitems_id = ci.id
WHERE ci.is_deleted = 0
GROUP BY ci.id, ci.name
ORDER BY in_stock ASC;
-- Exits already linked to tickets: when debiting, the module writes itemtype='Ticket'
-- and items_id = the ticket number on the native row itself.
-- On a GLPI without the module this filter returns nothing (native exit goes to User/Group).
SELECT c.items_id AS ticket,
ci.name AS consumable,
COUNT(*) AS units_taken,
MAX(c.date_out) AS last_exit
FROM glpi_consumables c
JOIN glpi_consumableitems ci ON ci.id = c.consumableitems_id
WHERE c.date_out IS NOT NULL
AND c.itemtype = 'Ticket'
GROUP BY c.items_id, ci.name
ORDER BY last_exit DESC;
What operating it taught us
Running client service desks in sustainment, ticket-level traceability was always the missing piece - GLPI could say "20 toners left this month" but not "which tickets consumed them". Without that cross-check, auditing consumption by period was rebuilt on guesswork. Two mistakes repeat in the field. The first is the manual stock-out on the consumable without naming the ticket: the technician hands the item out through the native flow, the balance even closes, but the request has no cost and the report is holed. The second is quieter - rolling out the module and forgetting to turn on "ticket required": for weeks exits coexist, some linked and some not, and only when someone asks for the report does the gap surface. The detail only operators know: the module does not invent a parallel stock table, it writes to the same glpi_consumables - so the stock-out done from the ticket and the one done from the native screen compete for the same balance. Standardizing everything through the ticket, with the requirement on from day one, is what keeps the two numbers from drifting apart.
Who it is for (and when not to use it)
Stock makes sense for support and infrastructure teams that consume physical supplies - toners, cables, parts, memory - during their work and need to tie each use to the ticket that generated it. And for managers who want to see consumable cost per request without exporting spreadsheets from two systems.
It is not worth it if you do not use GLPI's native consumables - the module leans on them, it does not replace them - or if your operation's stock control lives in an external ERP that remains the source of truth. In those cases the right integration is with the ERP, not a second stock ledger inside GLPI.
Compatibility
- GLPI: 10.0+ and 11.0+.
- Availability: on demand.
- Plugin: NexTool 3.x or higher.
Stock is part of NexTool, the module ecosystem that extends GLPI without code customization. To see the per-ticket stock-out working in your environment, talk to the team.
This content was produced with the assistance of artificial intelligence and reviewed by the Nextool Solutions team.