'Новая',
'processing' => 'В обработке',
'incoming' => 'Входящая',
'waiting' => 'Ожидание',
'pending' => 'На рассмотрении',
'closed' => 'Закрыта',
'solved' => 'Решена',
'assigned' => 'Назначена',
'rejected' => 'Отклонена'
];
// Синхронизация с GLPI
$updatedForms = [];
foreach ($userForms as $form) {
if (syncFormWithGlpi($pdo, $form, $glpi)) {
$updatedForms[] = $form;
}
}
$userForms = $updatedForms;
// Обработка создания заявки
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_request'])) {
$formType = $_POST['form_type'] ?? '';
$priority = $_POST['priority'] ?? 'medium';
$locationId = !empty($_POST['location']) ? (int)$_POST['location'] : null;
$allowedTypes = ['it_request', 'anonymous_complaint'];
if (!in_array($formType, $allowedTypes)) {
$message = 'Выберите корректный тип заявки';
$messageType = 'danger';
} else {
$formData = [];
$glpiDescription = '';
$uploadedFilePath = null;
if (!empty($_FILES['attachment']) && $_FILES['attachment']['error'] !== UPLOAD_ERR_NO_FILE) {
$uploadedFilePath = uploadFile($_FILES['attachment']);
if (!$uploadedFilePath) {
$message = 'Ошибка загрузки файла. Проверьте размер и тип.';
$messageType = 'danger';
}
}
if (!$message) {
if ($formType === 'it_request') {
$computerId = $_POST['computer_id'] ?? '';
$categoryId = $_POST['itil_category'] ?? '';
$description = trim($_POST['description'] ?? '');
if (!$computerId || !$categoryId || empty($description)) {
$message = 'Заполните все обязательные поля IT-заявки';
$messageType = 'danger';
} else {
// Получаем читаемые имена из GLPI
$computerName = $glpi->getComputerName((int)$computerId);
$categoryName = $glpi->getCategoryName((int)$categoryId);
// Данные пользователя
$userFullName = trim($user['last_name'] . ' ' . $user['first_name'] . ' ' . $user['patronymic']);
$userDepartment = $user['department'] ?? 'не указан';
$userPosition = $user['position'] ?? 'не указана';
// Формируем красивое описание
$glpiDescription = "Пользователь: $userFullName\n";
$glpiDescription .= "Отдел: $userDepartment\n";
$glpiDescription .= "Должность: $userPosition\n";
$glpiDescription .= "Оборудование: $computerName\n";
$glpiDescription .= "Категория: $categoryName\n";
$glpiDescription .= "Описание проблемы:\n$description";
if ($uploadedFilePath) {
$glpiDescription .= "\n\nПрикреплённый файл: " . $_SERVER['HTTP_HOST'] . '/' . $uploadedFilePath;
}
$formData = [
'computer_id' => $computerId,
'computer_name' => $computerName,
'itil_category' => $categoryId,
'category_name' => $categoryName,
'description' => $description,
'location_id' => $locationId,
'user_info' => [
'name' => $userFullName,
'department' => $userDepartment,
'position' => $userPosition
]
];
if ($uploadedFilePath) $formData['attachment'] = $uploadedFilePath;
}
} else {
$subject = trim($_POST['subject'] ?? '');
$complaintText = trim($_POST['complaint_text'] ?? '');
if (empty($subject) || empty($complaintText)) {
$message = 'Укажите тему и текст жалобы';
$messageType = 'danger';
} else {
// Для анонимной жалобы не пишем данные пользователя
$glpiDescription = "Тема: $subject\n\nТекст жалобы:\n$complaintText";
if ($uploadedFilePath) {
$glpiDescription .= "\n\nПрикреплённый файл: " . $_SERVER['HTTP_HOST'] . '/' . $uploadedFilePath;
}
$formData = ['subject' => $subject, 'text' => $complaintText];
if ($uploadedFilePath) $formData['attachment'] = $uploadedFilePath;
}
}
}
if (!$message) {
$glpiData = [
'name' => $formType === 'it_request' ? 'IT-заявка' : 'Анонимная жалоба',
'content' => $glpiDescription,
'priority' => $priority === 'high' ? 4 : ($priority === 'medium' ? 2 : 1), // 1-5, обычно 3 средний, но уточните по вашей конфигурации
'type' => 1, // инцидент
'requesttypes_id' => 1, // по умолчанию
];
if ($formType === 'it_request' && !empty($computerId)) {
$glpiData['items_id'] = ['itemtype' => 'Computer', 'items_id' => (int)$computerId];
}
if ($locationId) {
$glpiData['locations_id'] = $locationId;
}
// Попробуем установить автора заявки (если текущий пользователь может создавать заявки от своего имени)
// В GLPI API можно передать _users_id_requester. Но для этого нужны права.
// Оставим как есть, GLPI сам подставит автора из сессии API.
$glpiResponse = $glpi->createTicket($glpiData);
$userIdForDb = $formType === 'it_request' ? $user['id'] : null;
$localData = [
'glpi_response' => $glpiResponse ? 'success' : 'error',
'glpi_ticket_id' => $glpiResponse['id'] ?? null,
'form_fields' => $formData,
];
createLocalForm($pdo, $userIdForDb, $formType, $localData, 'pending', $priority, $locationId);
if ($glpiResponse) {
$message = "Заявка успешно отправлена! ID GLPI: " . ($glpiResponse['id'] ?? 'N/A');
$messageType = 'success';
} else {
$message = "Ошибка при отправке в GLPI. Заявка сохранена локально.";
$messageType = 'warning';
}
}
}
}
// Повторно получаем формы после возможного обновления
$userForms = getUserForms($pdo, $user['id']);
?>
Панель заявок – Service Desk
= htmlspecialchars($message) ?>
📌 Как это работает? Выберите тип заявки: ИТ‑заявка или анонимная жалоба. Для ИТ‑заявок поля подгружаются из GLPI. При выборе оборудования локация подставится автоматически. Заполните все поля, при необходимости прикрепите файл, и нажмите «Отправить».
📋 Мои заявки
У вас пока нет заявок.
ID Название Приоритет Статус Дата
#= $form['id'] ?>
= htmlspecialchars($glpiName) ?>GLPI #= $glpiId ?>
= $priorityRaw === 'low' ? 'Низкий' : ($priorityRaw === 'medium' ? 'Средний' : ($priorityRaw === 'high' ? 'Высокий' : $priorityRaw)) ?>
= htmlspecialchars($statusRu) ?>
= date('d.m.Y H:i', strtotime($form['created_at'])) ?>
Подробнее Ожидает GLPI
❓ Часто задаваемые вопросы