Stock Management by Ticket in GLPI

GLPI tracks native consumables (ConsumableItem), but the stock-out is born loose from the ticket. NexTool's Stock module debits from inside the ticket, writes the link on the glpi_consumables table itself, validates the balance in real time and delivers a period consumption report exportable to CSV - with the per-ticket traceability the native side does not record.

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_out on 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

  1. Install NexTool on your GLPI (10 or 11).
  2. Go to Setup > NexTool > Modules.
  3. Enable the Stock module and click Configure.
  4. 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:

FeatureNative GLPI (ConsumableItem)Stock module
Stock-out linked to the ticketManual, assigned to a user or group (itemtype User/Group) - no link to the ticketDebits from inside the ticket and writes itemtype = 'Ticket' on the native row
Balance validationTracks the balance, but outside the ticket flowChecks the balance in real time on the ticket tab, before debiting
ReversalManual return, editing the unit to clear the exitOne-click reversal, with configurable return
Auditable traceabilityRecords who received it, not which ticket caused itMovement with ticket, consumable, quantity, user and date
CSV report by periodListing per consumable, no ticket breakdownPanel 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.

Frequently Asked Questions

GLPI tracks consumable balance natively (ConsumableItem), but the stock-out is assigned to a user or group, never to a ticket. The Stock module debits from inside the ticket and writes the link on the native row itself (itemtype='Ticket'), which makes it possible to audit consumption per ticket - something the native side does not record.

Yes. The Stock tab on the ticket lists that ticket's exits, and the Exits tab on the consumable shows the reverse path. The report, filtered by period and consumable and exportable to CSV, completes the consumption view.

Turn on the "ticket required" option in the module settings. With it on, every exit through the module demands a ticket. Turn it on from day one: old exits made through the native screen stay unlinked and hole the report.

Yes, it is compatible with GLPI 10.0+ and 11.0+, available on demand, and requires the NexTool plugin 3.x or higher.

Need help?