2025-09-10 20:52:12 -03:00
|
|
|
// src/models/ticketGlpiModel.js
|
|
|
|
|
const glpiPool = require('../data/glpiDataBase');
|
|
|
|
|
const { logInfo, logError } = require('../utils/logger');
|
|
|
|
|
|
|
|
|
|
class TicketGlpiModel {
|
2025-09-11 20:57:43 -03:00
|
|
|
|
2025-09-10 20:52:12 -03:00
|
|
|
// Mapeamento de status ServiceNow → GLPI
|
|
|
|
|
static mapStatus(snState) {
|
|
|
|
|
const statusMap = {
|
|
|
|
|
'1': 1, // Aguardando Atendimento → Novo
|
|
|
|
|
'2': 2, // Em Andamento → Em andamento
|
|
|
|
|
'3': 3, // Pendente → Pendente
|
|
|
|
|
'6': 5, // Resolvido → Resolvido
|
|
|
|
|
'7': 6 // Fechado → Fechado
|
|
|
|
|
};
|
|
|
|
|
return statusMap[snState] || 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mapeamento de prioridade
|
|
|
|
|
static mapPriority(snPriority) {
|
|
|
|
|
const priorityMap = {
|
|
|
|
|
'1': 5, // Crítico → Muito alta
|
|
|
|
|
'2': 4, // Alto → Alta
|
|
|
|
|
'3': 3, // Moderado → Média
|
|
|
|
|
'4': 2, // Baixo → Baixa
|
|
|
|
|
'5': 1 // Planejamento → Muito baixa
|
|
|
|
|
};
|
|
|
|
|
return priorityMap[snPriority] || 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mapeamento de categoria
|
|
|
|
|
static mapCategory(shortDescription) {
|
|
|
|
|
const categoryMap = {
|
|
|
|
|
'Problemas com Telefonia Fixa': 5717, // PABX IP Nuvem
|
|
|
|
|
'Problemas com Internet': 5720, // Link Dedicado
|
|
|
|
|
'Problemas com Wi-Fi/Rede Corporativa': 5722, // Wifi
|
|
|
|
|
'Wi-fi Clientes': 5722 // Wifi
|
|
|
|
|
};
|
|
|
|
|
return categoryMap[shortDescription] || 5717;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-09-11 20:57:43 -03:00
|
|
|
// Criar ticket no GLPI
|
|
|
|
|
// src/models/ticketGlpiModel.js
|
2025-09-10 20:52:12 -03:00
|
|
|
|
2025-09-11 20:57:43 -03:00
|
|
|
static async createTicket(ticketData) {
|
2025-09-12 12:09:41 -03:00
|
|
|
const connection = await glpiPool.getConnection();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await connection.beginTransaction();
|
|
|
|
|
|
|
|
|
|
// 1. Preparar dados para o GLPI (usando valores fixos para teste)
|
|
|
|
|
const glpiTicketData = {
|
|
|
|
|
entities_id: 1371, // Valor fixo para teste
|
|
|
|
|
name: ticketData.short_description || 'Sem título',
|
|
|
|
|
date: ticketData.opened_at || new Date(),
|
|
|
|
|
date_mod: ticketData.updated_at || new Date(),
|
|
|
|
|
status: TicketGlpiModel.mapStatus(ticketData.state || '1'),
|
|
|
|
|
users_id_recipient: 917, // Valor fixo para teste
|
|
|
|
|
requesttypes_id: 1,
|
|
|
|
|
content: ticketData.description || '',
|
|
|
|
|
urgency: 3, // Valor fixo
|
|
|
|
|
impact: 3, // Valor fixo
|
|
|
|
|
priority: TicketGlpiModel.mapPriority(ticketData.priority || '3'),
|
|
|
|
|
type: 1, // Incidente
|
|
|
|
|
itilcategories_id: TicketGlpiModel.mapCategory(ticketData.short_description),
|
|
|
|
|
global_validation: 1,
|
|
|
|
|
date_creation: ticketData.opened_at || new Date()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Construir a query dinamicamente e inserir o ticket principal
|
2025-09-11 20:57:43 -03:00
|
|
|
const fields = Object.keys(glpiTicketData).join(', ');
|
|
|
|
|
const placeholders = Object.keys(glpiTicketData).map(() => '?').join(', ');
|
|
|
|
|
const values = Object.values(glpiTicketData);
|
|
|
|
|
|
|
|
|
|
const ticketQuery = `INSERT INTO glpi_tickets (${fields}) VALUES (${placeholders})`;
|
|
|
|
|
|
2025-09-12 12:09:41 -03:00
|
|
|
// Inserir ticket principal e obter insertId
|
2025-09-11 20:57:43 -03:00
|
|
|
const [ticketResult] = await connection.execute(ticketQuery, values);
|
|
|
|
|
const ticketId = ticketResult.insertId;
|
|
|
|
|
|
2025-09-12 12:09:41 -03:00
|
|
|
// Adicionar requerente (usa ticketId agora que foi criado)
|
2025-09-11 20:57:43 -03:00
|
|
|
await connection.execute(
|
|
|
|
|
`INSERT INTO glpi_tickets_users
|
2025-09-10 20:52:12 -03:00
|
|
|
(tickets_id, users_id, type, use_notification, alternative_email)
|
2025-09-11 20:57:43 -03:00
|
|
|
VALUES (?, ?, 1, 1, '')`,
|
|
|
|
|
[ticketId, 917]
|
|
|
|
|
);
|
2025-09-10 20:52:12 -03:00
|
|
|
|
2025-09-11 20:57:43 -03:00
|
|
|
// Adicionar grupo
|
|
|
|
|
await connection.execute(
|
|
|
|
|
`INSERT INTO glpi_groups_tickets
|
2025-09-10 20:52:12 -03:00
|
|
|
(tickets_id, groups_id, type)
|
2025-09-11 20:57:43 -03:00
|
|
|
VALUES (?, ?, 2)`,
|
|
|
|
|
[ticketId, 30]
|
|
|
|
|
);
|
2025-09-10 20:52:12 -03:00
|
|
|
|
2025-09-11 20:57:43 -03:00
|
|
|
await connection.commit();
|
2025-09-10 20:52:12 -03:00
|
|
|
|
2025-09-11 20:57:43 -03:00
|
|
|
logInfo(`✅ Ticket GLPI criado: ${ticketId}`);
|
|
|
|
|
return ticketId;
|
2025-09-10 20:52:12 -03:00
|
|
|
|
2025-09-11 20:57:43 -03:00
|
|
|
} catch (error) {
|
|
|
|
|
await connection.rollback();
|
|
|
|
|
logError(error, `❌ Erro ao criar ticket GLPI`);
|
|
|
|
|
throw error;
|
|
|
|
|
} finally {
|
|
|
|
|
connection.release();
|
2025-09-10 20:52:12 -03:00
|
|
|
}
|
2025-09-11 20:57:43 -03:00
|
|
|
}
|
2025-09-10 20:52:12 -03:00
|
|
|
|
2025-09-12 12:09:41 -03:00
|
|
|
// Verificar se ticket já existe no GLPI
|
|
|
|
|
static async ticketExists(snTicketNumber) {
|
|
|
|
|
try {
|
|
|
|
|
const query = `
|
|
|
|
|
SELECT id FROM glpi_tickets
|
|
|
|
|
WHERE name LIKE ? OR content LIKE ?
|
|
|
|
|
LIMIT 1
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const [rows] = await glpiPool.execute(query, [
|
|
|
|
|
`%${snTicketNumber}%`,
|
|
|
|
|
`%${snTicketNumber}%`
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return rows.length > 0 ? rows[0].id : null;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logError(error, 'Erro ao verificar ticket existente');
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-09-10 20:52:12 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = TicketGlpiModel;
|