csv de respuestas corregido

This commit is contained in:
Your Name
2025-04-25 09:37:58 -06:00
parent 14d191790f
commit 4e472e9e33
@@ -400,72 +400,114 @@ recibas tu constancia.</p>
throw new NotFoundException(`Cuestionario con ID ${idCuestionario} no encontrado`);
}
// Obtener todas las respuestas para este cuestionario con sus relaciones
const respuestas = await this.dataSource.query(`
// Obtener todas las preguntas del cuestionario para los encabezados
const preguntas = await this.dataSource.query(`
SELECT
p.id_pregunta,
p.pregunta,
p.id_tipo_pregunta
FROM pregunta p
JOIN seccion_pregunta sp ON p.id_pregunta = sp.id_pregunta
JOIN seccion s ON sp.id_seccion = s.id_seccion
JOIN cuestionario_seccion cs ON s.id_seccion = cs.id_seccion
WHERE cs.id_cuestionario = ?
ORDER BY sp.posicion, p.id_pregunta
`, [idCuestionario]);
// Obtener los participantes que han respondido este cuestionario
const participantes = await this.dataSource.query(`
SELECT DISTINCT
cr.id_cuestionario_respondido,
cr.fecha_respuesta,
p.id_participante,
p.correo AS correo_participante,
c.id_cuestionario,
c.nombre_form AS nombre_cuestionario,
e.id_evento,
e.nombre_evento,
preg.id_pregunta,
preg.pregunta,
-- Para respuestas abiertas
rpa.respuesta AS respuesta_abierta,
-- Para respuestas cerradas
o.id_opcion,
o.opcion AS respuesta_cerrada
p.correo AS correo_participante
FROM cuestionario_respondido cr
JOIN participante p ON cr.id_participante = p.id_participante
JOIN cuestionario c ON cr.id_cuestionario = c.id_cuestionario
LEFT JOIN evento e ON c.id_evento = e.id_evento
-- Respuestas abiertas
LEFT JOIN respuesta_participante_abierta rpa ON rpa.id_cuestionario_respondido = cr.id_cuestionario_respondido
LEFT JOIN pregunta preg_abierta ON rpa.id_pregunta = preg_abierta.id_pregunta
-- Respuestas cerradas
LEFT JOIN respuesta_participante_cerrada rpc ON rpc.id_cuestionario_respondido = cr.id_cuestionario_respondido
LEFT JOIN pregunta_opcion po ON rpc.id_pregunta_opcion = po.id_pregunta_opcion
LEFT JOIN pregunta preg ON po.id_pregunta = preg.id_pregunta
LEFT JOIN opcion o ON po.id_opcion = o.id_opcion
WHERE c.id_cuestionario = ?
ORDER BY cr.id_cuestionario_respondido, preg.id_pregunta
WHERE cr.id_cuestionario = ?
ORDER BY cr.fecha_respuesta DESC
`, [idCuestionario]);
// Obtener todas las respuestas para este cuestionario
const respuestasAbiertas = await this.dataSource.query(`
SELECT
cr.id_cuestionario_respondido,
p.id_pregunta,
rpa.respuesta
FROM respuesta_participante_abierta rpa
JOIN pregunta p ON rpa.id_pregunta = p.id_pregunta
JOIN cuestionario_respondido cr ON rpa.id_cuestionario_respondido = cr.id_cuestionario_respondido
WHERE cr.id_cuestionario = ?
`, [idCuestionario]);
const respuestasCerradas = await this.dataSource.query(`
SELECT
cr.id_cuestionario_respondido,
p.id_pregunta,
o.opcion
FROM respuesta_participante_cerrada rpc
JOIN pregunta_opcion po ON rpc.id_pregunta_opcion = po.id_pregunta_opcion
JOIN pregunta p ON po.id_pregunta = p.id_pregunta
JOIN opcion o ON po.id_opcion = o.id_opcion
JOIN cuestionario_respondido cr ON rpc.id_cuestionario_respondido = cr.id_cuestionario_respondido
WHERE cr.id_cuestionario = ?
`, [idCuestionario]);
// Crear un mapa de respuestas por participante y pregunta
const respuestasPorParticipante = new Map();
// Agregar respuestas abiertas al mapa
respuestasAbiertas.forEach(respuesta => {
const key = `${respuesta.id_cuestionario_respondido}_${respuesta.id_pregunta}`;
respuestasPorParticipante.set(key, respuesta.respuesta);
});
// Agregar respuestas cerradas al mapa (posiblemente múltiples por pregunta)
respuestasCerradas.forEach(respuesta => {
const key = `${respuesta.id_cuestionario_respondido}_${respuesta.id_pregunta}`;
const respuestaActual = respuestasPorParticipante.get(key);
if (respuestaActual) {
// Si ya hay una respuesta para esta pregunta, agregar esta opción
respuestasPorParticipante.set(key, `${respuestaActual}, ${respuesta.opcion}`);
} else {
respuestasPorParticipante.set(key, respuesta.opcion);
}
});
// Preparar los datos para el CSV
const datosReporte: string[][] = [];
// Agregar encabezados
const encabezados: string[] = [
'ID Respuesta',
'Fecha Respuesta',
// Agregar encabezados con datos del participante seguidos por las preguntas
const encabezados = [
'ID Participante',
'Correo Participante',
'Evento',
'Cuestionario',
'Pregunta',
'Respuesta'
'Correo',
'Fecha Respuesta'
];
// Agregar cada pregunta como un encabezado
preguntas.forEach(pregunta => {
encabezados.push(pregunta.pregunta);
});
datosReporte.push(encabezados);
// Procesar los resultados para el CSV
for (const fila of respuestas) {
const respuesta = fila.respuesta_abierta || fila.respuesta_cerrada || '';
// Crear una fila por cada participante
participantes.forEach(participante => {
const fila = [
participante.id_participante.toString(),
participante.correo_participante,
new Date(participante.fecha_respuesta).toLocaleString()
];
datosReporte.push([
fila.id_cuestionario_respondido?.toString() || '',
new Date(fila.fecha_respuesta).toLocaleString(),
fila.id_participante?.toString() || '',
fila.correo_participante || '',
fila.nombre_evento || 'Sin evento',
fila.nombre_cuestionario || '',
fila.pregunta || '',
respuesta
]);
}
// Agregar cada respuesta en el orden de las preguntas
preguntas.forEach(pregunta => {
const key = `${participante.id_cuestionario_respondido}_${pregunta.id_pregunta}`;
const respuesta = respuestasPorParticipante.get(key) || '';
fila.push(respuesta);
});
datosReporte.push(fila);
});
// Generar CSV de forma manual con valores separados por comas y líneas con saltos de línea
// Escapar valores que contengan comas para evitar problemas con el formato CSV