GLPI знает, сколько тонеров у вас на складе, но не знает, по какой заявке ушёл последний. Расходные материалы нативные (ConsumableItem), списание ручное и оторвано от обслуживания - и когда приходит время проверить расход за период или обосновать затраты по заявке, этой информации просто нет. Модуль Stock от NexTool закрывает этот пробел, связывая две стороны, которые GLPI оставил раздельными.
Проблема
В GLPI есть нативный модуль расходных материалов - ConsumableItem, хранящийся в таблицах glpi_consumableitems (модель материала) и glpi_consumables (каждая физическая единица). Он учитывает количество, поступление и выдачу: списать единицу по сути означает заполнить столбец date_out в соответствующей строке. Проблема не в учёте остатка как таковом - а в том, что это списание ни к чему не привязано. Нативно расходный материал «выдаётся» пользователю или группе, но никогда не заявке. Поэтому, когда специалист расходует три модуля памяти, решая обращение, он, может, и спишет их, но нигде не будет зафиксировано, что эти три модуля ушли именно из-за этой заявки.
Последствия проявляются позже. Проверить расход за период в разрезе заявок невозможно: данные существуют на двух островах, которые не пересекаются. Подсчёт затрат на материалы по обращению превращается в упражнение на память специалиста. А ручное списание вне процесса заявки открывает дорогу самой распространённой ошибке - забыть зарегистрировать или зарегистрировать не тот материал, и никто этого не проверит.
Как это работает
Модуль Stock создаёт двусторонний мост между заявками и нативными расходными материалами без дублирования данных: он по-прежнему пишет в glpi_consumables, только привязывает каждую выдачу к заявке, которая её вызвала.
- Вкладка «Склад» в заявке - специалист выбирает материал и количество прямо в заявке и списывает там же, не переключая экран.
- Вкладка «Выдачи» в материале - то же движение отображается в карточке материала, с видимой привязанной заявкой.
- Проверка остатка в реальном времени - перед списанием модуль проверяет доступный остаток с помощью нативного расчёта GLPI (единицы с пустым
date_out), не допуская списания сверх имеющегося. - Списание в нативном складе - выдача заполняет
date_outу израсходованных единиц и записывает связь с заявкой в той же нативной строке, сохраняя согласованность склада GLPI. - Сторнирование с настраиваемым возвратом - выдачу можно сторнировать одним кликом, вернув единицы на склад; поведение настраивается.
- Отчёты с экспортом в CSV - панель движений с фильтрами по периоду, материалу и статусу и кнопкой экспорта в CSV для работы в таблице.
- Обязательная заявка - опция, требующая привязки каждой выдачи к заявке, что закрывает путь для списаний без прослеживаемости.
Как включить
- Установите NexTool в свой GLPI (10 или 11).
- Перейдите в Настройка > NexTool > Модули.
- Активируйте модуль Stock и нажмите Настроить.
- На вкладке настроек определите, возвращает ли сторнирование материал на склад и обязательна ли заявка для каждой выдачи.
Нативный механизм и модуль Stock
Смысл не в том, чтобы заменить нативные расходные материалы, а в том, чтобы их расширить. Таблица показывает, где заканчивается нативное поведение и где продолжает модуль:
| Функция | Нативный GLPI (ConsumableItem) | Модуль Stock |
|---|---|---|
| Списание с привязкой к заявке | Вручную, на пользователя или группу (itemtype User/Group) - без связи с заявкой | Списывает прямо из заявки и записывает itemtype = 'Ticket' в нативную строку |
| Проверка остатка | Учитывает остаток, но вне процесса обслуживания | Проверяет остаток в реальном времени на вкладке заявки, перед списанием |
| Сторнирование | Ручной возврат через редактирование единицы для очистки выдачи | Сторнирование одним кликом, с настраиваемым возвратом |
| Прослеживаемость для аудита | Фиксирует, кто получил, но не какая заявка послужила причиной | Движение с заявкой, материалом, количеством, пользователем и датой |
| Отчёт CSV за период | Список по материалу, без разреза по заявкам | Панель с фильтрами по периоду и статусу, с экспортом в CSV |
Диагностика прямо в базе данных
Пока вы оцениваете модуль - или чтобы проверить, что фиксирует нативный механизм, - остаток и выдачи можно измерить прямо в таблицах GLPI. Два запроса, которые мы используем:
-- 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;
Опыт эксплуатации
При сопровождении служб поддержки клиентов прослеживаемости по заявкам всегда не хватало - GLPI говорил «в этом месяце ушло 20 тонеров», но не «какие заявки их израсходовали». Без этой связи проверка расхода за период восстанавливалась на глазок. На практике повторяются две ошибки. Первая - ручное списание материала без указания заявки: специалист выдаёт позицию через нативный процесс, остаток сходится, но обращение остаётся без затрат, а отчёт - с дырами. Вторая тише - запустить модуль и забыть включить «обязательную заявку»: неделями выдачи сосуществуют, часть привязана, часть нет, и пробел обнаруживается, только когда кто-то запрашивает отчёт. Деталь, которую знают только те, кто эксплуатирует: модуль не придумывает параллельную складскую таблицу, он пишет в ту же glpi_consumables - поэтому списание через заявку и списание через нативный экран расходуют один и тот же остаток. Стандартизировать всё через заявку, с включённой обязательностью с первого дня, - вот что не даёт двум цифрам разойтись.
Кому подходит (и когда НЕ использовать)
Stock имеет смысл для команд поддержки и инфраструктуры, которые расходуют физические материалы - тонеры, кабели, запчасти, модули памяти - в ходе обслуживания и должны привязывать каждый расход к заявке, которая его вызвала. А также для руководителей, которые хотят видеть затраты на материалы по каждому обращению, не выгружая таблицы из двух систем.
Он не стоит того, если вы не используете нативные расходные материалы GLPI - модуль опирается на них, а не заменяет их, - или если складской учёт вашей компании ведётся во внешней ERP, которая остаётся источником истины. В таких случаях правильная интеграция - с ERP, а не второй складской учёт внутри GLPI.
Совместимость
- GLPI: 10.0+ и 11.0+.
- Доступность: по запросу.
- Плагин: NexTool 3.x или выше.
Stock входит в NexTool - экосистему модулей, расширяющую GLPI без доработки кода. Чтобы увидеть списание по заявке в своей среде, свяжитесь с командой.
Проверено командой NexTool Solutions.