snglpi/src/models/ticketSnModel.js

181 lines
6.8 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 {
static async saveTicket(ticketData, typeTicket) {
const query = `
INSERT INTO tickets_sn
(ticket_number, 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)
ON CONFLICT (ticket_number)
DO UPDATE SET
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, // $1 - ticket_number
ticketData.short_description?.value || null, // $2 - short_description
ticketData.state?.display_value || null, // $3 - status
ticketData.description?.value || null, // $4 - description
ticketData.opened_by?.display_value || null, // $5 - caller_id
ticketData['opened_by.email']?.value || null, // $6 - caller_email
ticketData.location?.value || null, // $7 - location_id
ticketData.location?.display_value || null, // $8 - location_name
ticketData['variables.numero_ramal']?.value || null, // $9 - ramal
ticketData['variables.telephone_favorecido_rh']?.value || null, // $10 - telefone
ticketData.opened_at?.value ? new Date(ticketData.opened_at.value) : null, // $11 - opened_at
typeTicket // $12 - tipo
];
try {
const result = await pool.query(query, values);
const wasInserted = result.rows[0].inserted; // true = INSERT, false = UPDATE
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
// NOVO: Buscar tickets pendentes para sincronização com GLPI
static async getPendingTickets(limit = 3) {
try {
const query = `
SELECT
id,
ticket_number,
short_description,
description,
status,
caller_id,
caller_email,
location_id,
location_name,
ramal,
telefone,
opened_at,
tipo,
created_at,
updated_at
FROM tickets_sn
WHERE glpi_sync_status IS NULL
ORDER BY opened_at ASC
LIMIT $1
`;
const result = await pool.query(query, [limit]);
logInfo(`📋 Tickets pendentes encontrados: ${result.rows.length}`);
return result.rows;
} catch (error) {
logError(error, '❌ Erro ao buscar tickets pendentes');
return [];
}
}
// NOVO: Atualizar status de sincronização com GLPI
static async updateSyncStatus(ticketId, status, glpiTicketId = null) {
try {
const query = `
UPDATE tickets_sn
SET glpi_sync_status = $1,
glpi_ticket_id = $2,
glpi_sync_date = NOW()
WHERE id = $3
RETURNING id, ticket_number
`;
const result = await pool.query(query, [status, glpiTicketId, ticketId]);
if (result.rows.length > 0) {
logInfo(`🔄 Status atualizado: ${status} para ticket ${result.rows[0].ticket_number}`, {
ticket_id: result.rows[0].id,
ticket_number: result.rows[0].ticket_number,
glpi_ticket_id: glpiTicketId,
status: status
});
}
} catch (error) {
logError(error, `❌ Erro ao atualizar status de sync para ticket ${ticketId}`);
}
}
// NOVO: Resetar status de sync para testes (opcional)
static async resetSyncStatus() {
try {
const query = `
UPDATE tickets_sn
SET glpi_sync_status = NULL,
glpi_ticket_id = NULL,
glpi_sync_date = NULL
WHERE id IN (
SELECT id FROM tickets_sn
ORDER BY opened_at DESC
LIMIT $1
)
RETURNING id, ticket_number
`;
const result = await pool.query(query, [limit]);
logInfo(`🔄 Status resetado para ${result.rows.length} tickets`);
return result.rows;
} catch (error) {
logError(error, '❌ Erro ao resetar status de sync');
return [];
}
}
// NOVO: Verificar status de sincronização
static async getSyncStatus() {
try {
const query = `
SELECT
glpi_sync_status,
COUNT(*) as total,
COUNT(glpi_ticket_id) as synchronized
FROM tickets_sn
GROUP BY glpi_sync_status
`;
const result = await pool.query(query);
return result.rows;
} catch (error) {
logError(error, '❌ Erro ao verificar status de sync');
return [];
}
}
}
module.exports = TicketSnModel;