snglpi/src/models/ticketSnModel.js

197 lines
6.9 KiB
JavaScript
Raw Normal View History

// src/models/ticketSnModel.js
const pool = require('../data/database');
const { logInfo, logError, logWarning } = require('../utils/logger');
2025-08-30 19:04:35 -03:00
class TicketSnModel {
// Salva ou atualiza um ticket no banco de dados
static async saveTicket(ticketData, typeTicket) {
const query = `
INSERT INTO tickets_sn
(ticket_number, sys_id, short_description, status, description, caller_id, caller_email,
location_id, location_name, ramal, telefone, opened_at, tipo)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
ON CONFLICT (ticket_number)
DO UPDATE SET
sys_id = EXCLUDED.sys_id,
short_description = EXCLUDED.short_description,
status = EXCLUDED.status,
description = EXCLUDED.description,
caller_id = EXCLUDED.caller_id,
caller_email = EXCLUDED.caller_email,
location_id = EXCLUDED.location_id,
location_name = EXCLUDED.location_name,
ramal = EXCLUDED.ramal,
telefone = EXCLUDED.telefone,
opened_at = EXCLUDED.opened_at,
tipo = EXCLUDED.tipo,
updated_at = NOW()
RETURNING id, xmax = 0 as inserted`;
2025-08-30 19:04:35 -03:00
const values = [
ticketData.number?.value || null,
ticketData.sys_id?.value || null,
ticketData.short_description?.value || null,
ticketData.state?.display_value || null,
ticketData.description?.value || null,
ticketData.opened_by?.display_value || null,
ticketData.sys_created_by?.display_value || null,
ticketData.location?.value || null,
ticketData.location?.display_value || null,
ticketData['variables.numero_ramal']?.value || null,
ticketData['variables.telephone_favorecido_rh']?.value || null,
ticketData.opened_at?.value ? new Date(ticketData.opened_at.value) : null,
typeTicket
];
try {
const result = await pool.query(query, values);
const wasInserted = result.rows[0].inserted;
if (wasInserted) {
logInfo(`✅ NOVO ticket salvo! ID: ${result.rows[0].id}`, {
ticket_id: result.rows[0].id,
ticket_number: values[0],
action: 'insert'
});
} else {
logInfo(`🔄 Ticket atualizado! ID: ${result.rows[0].id}`, {
ticket_id: result.rows[0].id,
ticket_number: values[0],
action: 'update'
});
}
return result.rows[0].id;
} catch (error) {
logError(error, `❌ Erro ao salvar ticket ${values[0]}`);
throw error;
}
}
2025-08-30 19:04:35 -03:00
// Busca tickets que ainda não foram sincronizados com o GLPI
static async getPendingTickets() {
try {
const query = `
SELECT
ts.id,
ts.ticket_number,
ts.short_description,
ts.description,
ts.status,
ts.caller_id,
ts.caller_email,
ts.location_id,
ts.location_name,
ts.ramal,
ts.telefone,
ts.opened_at,
ts.tipo,
ts.created_at,
ts.updated_at
FROM tickets_sn ts
LEFT JOIN ticket_sync tsync ON ts.id = tsync.sn_ticket_id
WHERE tsync.id IS NULL
AND ts.status NOT IN ('Encerrado', 'Encerrado - Omitido')
ORDER BY ts.opened_at
`;
const result = await pool.query(query);
logInfo(`📋 Tickets pendentes encontrados: ${result.rows.length}`);
return result.rows;
} catch (error) {
logError(error, '❌ Erro ao buscar tickets pendentes');
return [];
}
}
// Busca um ticket pelo número
static async findByTicketNumber(ticketNumber) {
try {
const query = `
SELECT * FROM tickets_sn
WHERE ticket_number = $1
`;
const result = await pool.query(query, [ticketNumber]);
return result.rows[0] || null;
} catch (error) {
logError(error, `❌ Erro ao buscar ticket por número: ${ticketNumber}`);
return null;
}
}
// Busca um ticket pelo ID
static async findById(ticketId) {
try {
const query = `
SELECT * FROM tickets_sn
WHERE id = $1
`;
const result = await pool.query(query, [ticketId]);
return result.rows[0] || null;
} catch (error) {
logError(error, `❌ Erro ao buscar ticket por ID: ${ticketId}`);
return null;
}
}
// Atualiza os dados de um ticket
static async updateTicket(ticketId, updateData) {
try {
const fields = [];
const values = [];
let paramCount = 1;
// Construir dinamicamente a query baseada nos campos fornecidos
for (const [key, value] of Object.entries(updateData)) {
fields.push(`${key} = $${paramCount}`);
values.push(value);
paramCount++;
}
// Adicionar updated_at
fields.push(`updated_at = NOW()`);
// Adicionar o ID no final dos valores
values.push(ticketId);
const query = `
UPDATE tickets_sn
SET ${fields.join(', ')}
WHERE id = $${paramCount}
RETURNING *
`;
const result = await pool.query(query, values);
if (result.rows.length > 0) {
logInfo(`✅ Ticket atualizado: ${ticketId}`);
return result.rows[0];
}
return null;
} catch (error) {
logError(error, `❌ Erro ao atualizar ticket ${ticketId}`);
throw error;
}
}
}
/**
* @module TicketSnModel
* @description Este módulo fornece métodos para interagir com a tabela de tickets do ServiceNow (tickets_sn) no banco de dados.
* Inclui funcionalidades para salvar um ticket, buscar tickets pendentes para sincronização com o GLPI,
* e buscar/atualizar tickets específicos.
*
* A função saveTicket insere ou atualiza um ticket na tabela tickets_sn.
* A função getPendingTickets busca tickets que ainda não foram sincronizados com o GLPI (não possuem registro em ticket_sync)
* e ignora os tickets com status 'Encerrado' ou 'Encerrado - Omitido'.
*/
module.exports = TicketSnModel;