feat(fsm): modulo de asignacion de tareas y visitas tecnicas integrado con tareas.telcotronics.com
This commit is contained in:
@@ -90,6 +90,35 @@ async function setup() {
|
||||
await conn.query('ALTER TABLE tickets ADD FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE');
|
||||
} catch (e) { if (e.errno !== 1826 && e.errno !== 1005) throw e; }
|
||||
|
||||
// Create ticket_visitas table
|
||||
await conn.query(`
|
||||
CREATE TABLE IF NOT EXISTS ticket_visitas (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
ticket_id INT NOT NULL,
|
||||
external_id VARCHAR(100) NULL,
|
||||
tecnico_email VARCHAR(150) NOT NULL,
|
||||
tecnico_nombre VARCHAR(150) NULL,
|
||||
titulo VARCHAR(255) NOT NULL,
|
||||
descripcion TEXT NULL,
|
||||
ubicacion VARCHAR(255) NULL,
|
||||
latitud DECIMAL(10, 7) NULL,
|
||||
longitud DECIMAL(10, 7) NULL,
|
||||
fecha_visita DATETIME NULL,
|
||||
fecha_fin DATETIME NULL,
|
||||
estado ENUM('programada', 'en_camino', 'en_sitio', 'completada', 'cancelada') DEFAULT 'programada',
|
||||
checklist_json TEXT NULL,
|
||||
historial_json LONGTEXT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX (ticket_id),
|
||||
INDEX (company_id),
|
||||
INDEX (external_id),
|
||||
FOREIGN KEY (ticket_id) REFERENCES tickets(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
`);
|
||||
|
||||
// Seed departments
|
||||
const [depts] = await conn.query('SELECT COUNT(*) as c FROM departments WHERE company_id = ?', [companyId]);
|
||||
if (depts[0].c === 0) {
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* tareasHubService.js
|
||||
* Servicio de integración con el sistema de Tareas y Gestión de Campo (FSM) de Telcotronics.
|
||||
* Conecta con https://tareas.telcotronics.com/api/external
|
||||
*/
|
||||
|
||||
const HUB_API_URL = process.env.HUB_API_URL || 'https://tareas.telcotronics.com/api/external';
|
||||
const HUB_API_KEY = process.env.HUB_API_KEY || 'sigma_crm_test_key_123';
|
||||
|
||||
class TareasHubService {
|
||||
/**
|
||||
* Obtiene el listado de técnicos/usuarios disponibles en tareas.telcotronics.com
|
||||
*/
|
||||
static async obtenerTecnicos() {
|
||||
try {
|
||||
const url = `${HUB_API_URL}/users/list`;
|
||||
const res = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'x-api-key': HUB_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}: Fallo al consultar técnicos en Hub`);
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
return data.usuarios || [];
|
||||
} catch (error) {
|
||||
console.error('[TareasHubService.obtenerTecnicos]:', error.message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Programa una visita técnica / tarea operativa con trazabilidad de campo (FSM)
|
||||
*/
|
||||
static async crearVisita({
|
||||
ticketId,
|
||||
titulo,
|
||||
descripcion,
|
||||
emailTecnico,
|
||||
fechaVisita = null,
|
||||
fechaFin = null,
|
||||
ubicacion = '',
|
||||
coordenadas = null,
|
||||
referencia = '',
|
||||
prioridad = 'Media',
|
||||
checklist = []
|
||||
}) {
|
||||
try {
|
||||
const url = `${HUB_API_URL}/tareas`;
|
||||
|
||||
let lat = null;
|
||||
let lng = null;
|
||||
if (coordenadas && typeof coordenadas === 'string' && coordenadas.includes(',')) {
|
||||
const parts = coordenadas.split(',');
|
||||
lat = parseFloat(parts[0].trim()) || null;
|
||||
lng = parseFloat(parts[1].trim()) || null;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
titulo: titulo || `Visita Técnica - Ticket #${ticketId}`,
|
||||
descripcion: descripcion || `Visita técnica generada desde Help Desk para el Ticket #${ticketId}`,
|
||||
emailTecnico: emailTecnico,
|
||||
prioridad: prioridad,
|
||||
ticket_id: String(ticketId),
|
||||
origen: 'HELP_DESK',
|
||||
origen_externo_id: String(ticketId),
|
||||
fechaInicio: fechaVisita ? new Date(fechaVisita).toISOString() : new Date().toISOString(),
|
||||
fechaLimite: fechaFin ? new Date(fechaFin).toISOString() : (fechaVisita ? new Date(fechaVisita).toISOString() : null),
|
||||
ubicacion: ubicacion,
|
||||
destino: {
|
||||
direccion: ubicacion,
|
||||
latitud: lat,
|
||||
longitud: lng,
|
||||
referencia: referencia
|
||||
},
|
||||
checklist_inicial: Array.isArray(checklist) && checklist.length > 0
|
||||
? checklist
|
||||
: [
|
||||
'Revisión física de acometida y equipamiento',
|
||||
'Verificación de conectividad y potencia',
|
||||
'Pruebas operativas con el cliente y firma'
|
||||
]
|
||||
};
|
||||
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'x-api-key': HUB_API_KEY
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
if (!res.ok || !data.success) {
|
||||
throw new Error(data.mensaje || data.error || `HTTP ${res.status} al crear tarea en Hub`);
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('[TareasHubService.crearVisita]:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consulta el estado en tiempo real y el timeline operativo de la tarea/visita en el Hub
|
||||
*/
|
||||
static async consultarEstadoVisita(externalIdOrTicketId) {
|
||||
try {
|
||||
const url = `${HUB_API_URL}/tareas/${externalIdOrTicketId}/status`;
|
||||
const res = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'x-api-key': HUB_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}: No se pudo obtener el estado de la tarea`);
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('[TareasHubService.consultarEstadoVisita]:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TareasHubService;
|
||||
Reference in New Issue
Block a user