Files
formularios_api/src/cuestionario/cuestionario.service.ts
T
2025-10-01 12:46:12 -06:00

766 lines
28 KiB
TypeScript

import {
Injectable,
InternalServerErrorException,
NotFoundException,
UnprocessableEntityException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource, In, MoreThan } from 'typeorm';
import {
CreateCuestionarioDto,
CreateCuestionarioEventoDto,
} from './dto/create-cuestionario.dto';
import { UpdateCuestionarioDto } from './dto/update-cuestionario.dto';
import { Cuestionario } from './entities/cuestionario.entity';
import { Seccion } from '../seccion/entities/seccion.entity';
import { CuestionarioSeccion } from '../cuestionario_seccion/entities/cuestionario_seccion.entity';
import { Pregunta, TiposValidacion } from '../pregunta/entities/pregunta.entity';
import { SeccionPregunta } from '../seccion_pregunta/entities/seccion_pregunta.entity';
import { Opcion } from '../opcion/entities/opcion.entity';
import { PreguntaOpcion } from '../pregunta_opcion/entities/pregunta_opcion.entity';
import {
TipoPregunta,
TipoPreguntaEnum,
} from '../tipo_pregunta/entities/tipo_pregunta.entity';
import { Evento } from '../evento/entities/evento.entity';
import { EventoService } from '../evento/evento.service';
import { CreateEventoWithCuestionarioDto } from './dto/create-evento-cuestionario.dto';
import * as ExcelJS from 'exceljs';
import { PLANTILLAS } from './plantillas';
@Injectable()
export class CuestionarioService {
constructor(
@InjectRepository(Cuestionario)
private cuestionarioRepository: Repository<Cuestionario>,
@InjectRepository(Seccion)
private seccionRepository: Repository<Seccion>,
@InjectRepository(CuestionarioSeccion)
private cuestionarioSeccionRepository: Repository<CuestionarioSeccion>,
@InjectRepository(Pregunta)
private preguntaRepository: Repository<Pregunta>,
@InjectRepository(SeccionPregunta)
private seccionPreguntaRepository: Repository<SeccionPregunta>,
@InjectRepository(Opcion)
private opcionRepository: Repository<Opcion>,
@InjectRepository(PreguntaOpcion)
private preguntaOpcionRepository: Repository<PreguntaOpcion>,
@InjectRepository(TipoPregunta)
private tipoPreguntaRepository: Repository<TipoPregunta>,
@InjectRepository(Evento)
private eventoRepository: Repository<Evento>,
private dataSource: DataSource,
private eventoService: EventoService,
) {}
private mapTipoPregunta(tipo: string): TipoPreguntaEnum {
switch (tipo.toLowerCase()) {
case 'cerrada': return TipoPreguntaEnum.Cerrada;
case 'multiple': return TipoPreguntaEnum.Multiple;
case 'abierta (parrafo)': return TipoPreguntaEnum.AbiertaParrafo;
case 'abierta (respuesta corta)': return TipoPreguntaEnum.AbiertaRespuestaCorta;
default: throw new Error(`Tipo de pregunta inválido: ${tipo}`);
}
}
// Mapear validación desde string a enum
private mapValidacion(validacion?: string): TiposValidacion | undefined {
if (!validacion) return undefined;
switch (validacion.trim().toLowerCase()) {
case 'correo': return TiposValidacion.CORREO;
case 'correo_institucional': return TiposValidacion.CORREO_INSTITUCIONAL;
case 'telefono': return TiposValidacion.TELEFONO;
case 'nombre': return TiposValidacion.NOMBRE;
case 'apellidos': return TiposValidacion.APELLIDOS;
case 'entero': return TiposValidacion.ENTERO;
case 'decimal': return TiposValidacion.DECIMAL;
case 'comunidad_alumno': return TiposValidacion.COMUNIDAD_ALUMNO;
case 'cuenta_alumno': return TiposValidacion.CUENTA_ALUMNO;
case 'comunidad_trabajador': return TiposValidacion.COMUNIDAD_TRABAJADOR;
case 'cuenta_trabajador': return TiposValidacion.CUENTA_TRABAJADOR;
case 'genero': return TiposValidacion.GENERO;
case 'carrera': return TiposValidacion.CARRERA;
case 'institucion': return TiposValidacion.INSTITUCION;
case 'rfc': return TiposValidacion.RFC;
default: return undefined;
}
}
async cargarEventosDesdeExcel(filePath: string) {
const PLANTILLA_MAP: Record<number, string> = {
1: 'registro-comunidad-alumnos',
2: 'registro-comunidad-trabajadores',
3: 'registro-general',
};
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.readFile(filePath);
const eventosSheet = workbook.getWorksheet('Eventos');
const cuestionariosSheet = workbook.getWorksheet('Cuestionarios');
const seccionesSheet = workbook.getWorksheet('Secciones');
const preguntasSheet = workbook.getWorksheet('Preguntas');
const opcionesSheet = workbook.getWorksheet('Opciones');
if (!eventosSheet || !cuestionariosSheet || !seccionesSheet || !preguntasSheet || !opcionesSheet) {
throw new UnprocessableEntityException('El archivo Excel debe contener las hojas: Eventos, Cuestionarios, Secciones, Preguntas y Opciones.');
}
for (let i = 2; i <= eventosSheet.rowCount; i++) {
const row = eventosSheet.getRow(i);
// Construir objeto evento
const eventoDto = {
tipo_evento: row.getCell(2).value as string,
nombre_evento: row.getCell(3).value as string,
descripcion_evento: row.getCell(4).value as string,
fecha_inicio: new Date(row.getCell(5).value as string),
fecha_fin: new Date(row.getCell(6).value as string),
banner: row.getCell(7).value as string, // nombre del archivo subido previamente
};
// Filtrar cuestionarios de este evento
const cuestionarios = cuestionariosSheet.getRows(2, cuestionariosSheet.rowCount - 1)
?.filter(qRow => qRow.getCell(2).value === row.getCell(1).value) || [];
for (const qRow of cuestionarios) {
const plantilla = qRow.getCell(9).value ? Number(row.getCell(8).value) : null;
if (plantilla && PLANTILLA_MAP[plantilla]) {
const fecha_inicio = new Date(qRow.getCell(4).value as string);
const fecha_fin = new Date(qRow.getCell(5).value as string);
const id_tipo_evento= Number(qRow.getCell(8).value);
const plantillaId = PLANTILLA_MAP[plantilla];
const base = PLANTILLAS.find(p => p.id === plantillaId);
if (!base) throw new Error(`Plantilla ${plantillaId} no encontrada`);
return {
...base.datos,
fecha_inicio,
fecha_fin,
id_tipo_evento,
};
}
// Filtrar secciones de este cuestionario
const secciones = seccionesSheet.getRows(2, seccionesSheet.rowCount - 1)
?.filter(sRow => sRow.getCell(2).value === qRow.getCell(1).value)
.map(sRow => {
// Filtrar preguntas de esta sección
const preguntas = preguntasSheet.getRows(2, preguntasSheet.rowCount - 1)
?.filter(pRow => pRow.getCell(2).value === sRow.getCell(1).value)
.map(pRow => {
const opciones = opcionesSheet.getRows(2, opcionesSheet.rowCount - 1)
?.filter(oRow => oRow.getCell(2).value === pRow.getCell(1).value)
.map(oRow => ({ valor: oRow.getCell(3).value as string })) || [];
return {
titulo: pRow.getCell(3).value as string,
tipo: this.mapTipoPregunta(pRow.getCell(4).value as string),
obligatoria: !!pRow.getCell(5).value,
validacion: this.mapValidacion(pRow.getCell(6).value as string),
opciones,
};
}) || [];
return {
titulo: sRow.getCell(3).value as string,
descripcion: sRow.getCell(4).value as string,
preguntas,
};
}) || [];
// Construir DTO completo
const createDto: CreateEventoWithCuestionarioDto = {
evento: eventoDto,
cuestionario: {
nombre_form: qRow.getCell(3).value as string,
descripcion: qRow.getCell(4).value as string,
fecha_inicio: new Date(qRow.getCell(5).value as string),
fecha_fin: new Date(qRow.getCell(6).value as string),
id_tipo_cuestionario: Number(qRow.getCell(7).value),
id_tipo_evento: Number(qRow.getCell(8).value), // obligatorio
secciones,
},
};
// Llamada a tu servicio para guardar en DB
await this.createCuestionarioEvento(createDto);
}
}
return { message: 'Carga masiva completada' };
}
async create(createCuestionarioDto: CreateCuestionarioDto) {
// Verificar que el evento exista
await this.eventoService.getEventoOrFail(createCuestionarioDto.id_evento);
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
// 1. Crear cuestionario
const cuestionario = new Cuestionario();
cuestionario.nombre_form = createCuestionarioDto.nombre_form;
cuestionario.descripcion = createCuestionarioDto.descripcion;
cuestionario.fecha_inicio = new Date(createCuestionarioDto.fecha_inicio);
cuestionario.fecha_fin = new Date(createCuestionarioDto.fecha_fin);
cuestionario.id_tipo_cuestionario =
createCuestionarioDto.id_tipo_cuestionario;
cuestionario.id_tipo_evento = createCuestionarioDto.id_tipo_evento;
cuestionario.contador_secciones =
createCuestionarioDto.secciones?.length || 0;
cuestionario.editable = true;
cuestionario.id_evento = createCuestionarioDto.id_evento;
cuestionario.cupo_maximo = createCuestionarioDto.cupo_maximo;
const savedCuestionario = await queryRunner.manager.save(cuestionario);
// 2. Crear secciones y vincularlas
if (
createCuestionarioDto.secciones &&
createCuestionarioDto.secciones?.length > 0
) {
for (let i = 0; i < createCuestionarioDto.secciones.length; i++) {
const seccionDto = createCuestionarioDto.secciones[i];
const seccion = new Seccion();
seccion.titulo = seccionDto.titulo;
seccion.descripcion = seccionDto.descripcion;
seccion.contador_pregunta = seccionDto.preguntas?.length || 0;
const savedSeccion = await queryRunner.manager.save(seccion);
const cuestionarioSeccion = new CuestionarioSeccion();
cuestionarioSeccion.id_cuestionario =
savedCuestionario.id_cuestionario;
cuestionarioSeccion.id_seccion = savedSeccion.id_seccion;
cuestionarioSeccion.posicion = i + 1;
await queryRunner.manager.save(cuestionarioSeccion);
// 3. Preguntas por sección
if (seccionDto.preguntas && seccionDto.preguntas?.length > 0) {
for (let j = 0; j < seccionDto.preguntas.length; j++) {
const preguntaDto = seccionDto.preguntas[j];
let idTipoPregunta = 7;
switch (preguntaDto.tipo) {
case TipoPreguntaEnum.AbiertaParrafo:
idTipoPregunta = 1;
break;
case TipoPreguntaEnum.AbiertaRespuestaCorta:
idTipoPregunta = 2;
break;
case TipoPreguntaEnum.Cerrada:
idTipoPregunta = 3;
break;
case TipoPreguntaEnum.Multiple:
idTipoPregunta = 4;
break;
default:
console.warn(
`Tipo de pregunta no reconocido: ${preguntaDto.tipo}. Se asignará como desconocido.`,
);
idTipoPregunta = 7;
break;
}
const pregunta = new Pregunta();
pregunta.pregunta = preguntaDto.titulo;
pregunta.obligatoria = preguntaDto.obligatoria || false;
pregunta.id_tipo_pregunta = idTipoPregunta;
pregunta.contador_opcion = preguntaDto.opciones?.length || 0;
pregunta.validacion = preguntaDto.validacion || undefined;
const savedPregunta = await queryRunner.manager.save(pregunta);
const seccionPregunta = new SeccionPregunta();
seccionPregunta.id_seccion = savedSeccion.id_seccion;
seccionPregunta.id_pregunta = savedPregunta.id_pregunta;
seccionPregunta.posicion = j + 1;
await queryRunner.manager.save(seccionPregunta);
// 4. Crear opciones si las hay
if (preguntaDto.opciones && preguntaDto.opciones?.length > 0) {
for (let k = 0; k < preguntaDto.opciones.length; k++) {
const opcionDto = preguntaDto.opciones[k];
const opcion = new Opcion();
opcion.opcion = opcionDto.valor;
const savedOpcion = await queryRunner.manager.save(opcion);
const preguntaOpcion = new PreguntaOpcion();
preguntaOpcion.id_pregunta = savedPregunta.id_pregunta;
preguntaOpcion.opcion = savedOpcion;
preguntaOpcion.posicion = k + 1;
await queryRunner.manager.save(preguntaOpcion);
}
}
}
}
}
}
await queryRunner.commitTransaction();
return {
success: true,
message: 'Cuestionario creado exitosamente',
id_cuestionario: savedCuestionario.id_cuestionario,
id_evento: savedCuestionario.id_evento,
};
} catch (error) {
await queryRunner.rollbackTransaction();
throw new InternalServerErrorException(
'Error al crear el cuestionario y evento',
error.message,
);
} finally {
await queryRunner.release();
}
}
async findAllRecientes() {
console.log('Buscando cuestionarios recientes');
const now = new Date();
const pastDate = new Date();
pastDate.setDate(now.getDate() - 30);
return this.cuestionarioRepository.find({
where: {
fecha_inicio: MoreThan(pastDate),
},
order: { fecha_fin: 'DESC' },
});
}
async createCuestionarioEvento(
createCuestionarioDto: CreateEventoWithCuestionarioDto,
) {
const { evento, cuestionario } = createCuestionarioDto;
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
// Buscar si ya existe un evento con el nombre proporcionado
let eventoExistente = await this.eventoRepository.findOne({
where: { nombre_evento: evento.nombre_evento },
});
// Si el evento no existe, crearlo
if (!eventoExistente) {
eventoExistente = queryRunner.manager.create(Evento, evento);
await queryRunner.manager.save(eventoExistente);
console.log(`Creando nuevo evento: ${evento.nombre_evento}`);
}
// Crear el cuestionario asociado al evento
const cuestionarioEntity = queryRunner.manager.create(Cuestionario, {
nombre_form: cuestionario.nombre_form,
descripcion: cuestionario.descripcion,
fecha_inicio: new Date(cuestionario.fecha_inicio),
fecha_fin: new Date(cuestionario.fecha_fin),
id_tipo_cuestionario: cuestionario.id_tipo_cuestionario,
id_tipo_evento: cuestionario.id_tipo_evento,
contador_secciones: cuestionario.secciones?.length || 0,
editable: true,
id_evento: eventoExistente.id_evento, // Asociar el evento creado
cupo_maximo: cuestionario.cupo_maximo,
});
const savedCuestionario =
await queryRunner.manager.save(cuestionarioEntity);
console.log(
`Cuestionario creado: ${savedCuestionario.nombre_form}, ID: ${savedCuestionario.id_cuestionario}`,
);
// Crear las secciones del cuestionario
if (
createCuestionarioDto.cuestionario.secciones &&
createCuestionarioDto.cuestionario.secciones.length > 0
) {
for (
let i = 0;
i < createCuestionarioDto.cuestionario.secciones.length;
i++
) {
const seccionDto = createCuestionarioDto.cuestionario.secciones[i];
// Crear sección
const seccion = new Seccion();
seccion.titulo = seccionDto.titulo;
seccion.descripcion = seccionDto.descripcion;
seccion.contador_pregunta = seccionDto.preguntas?.length || 0;
const savedSeccion = await queryRunner.manager.save(seccion);
// Vincular sección con cuestionario
const cuestionarioSeccion = new CuestionarioSeccion();
cuestionarioSeccion.id_cuestionario =
savedCuestionario.id_cuestionario;
cuestionarioSeccion.id_seccion = savedSeccion.id_seccion;
cuestionarioSeccion.posicion = i + 1;
await queryRunner.manager.save(cuestionarioSeccion);
// 3. Crear preguntas y vincularlas a la sección
if (seccionDto.preguntas && seccionDto.preguntas.length > 0) {
for (let j = 0; j < seccionDto.preguntas.length; j++) {
const preguntaDto = seccionDto.preguntas[j];
let idTipoPregunta = 7;
switch (preguntaDto.tipo) {
case TipoPreguntaEnum.AbiertaParrafo:
idTipoPregunta = 1;
break;
case TipoPreguntaEnum.AbiertaRespuestaCorta:
idTipoPregunta = 2;
break;
case TipoPreguntaEnum.Cerrada:
idTipoPregunta = 3;
break;
case TipoPreguntaEnum.Multiple:
idTipoPregunta = 4;
break;
default:
console.warn(
`Tipo de pregunta no reconocido: ${preguntaDto.tipo}. Se asignará como desconocido.`,
);
idTipoPregunta = 7;
break;
}
const tipoPregunta = {
id_tipo: idTipoPregunta,
tipo_pregunta: preguntaDto.tipo,
};
// Crear pregunta
const pregunta = new Pregunta();
pregunta.pregunta = preguntaDto.titulo;
pregunta.obligatoria = preguntaDto.obligatoria || false;
pregunta.id_tipo_pregunta = tipoPregunta.id_tipo;
pregunta.contador_opcion = preguntaDto.opciones?.length || 0;
pregunta.validacion = preguntaDto.validacion || undefined;
const savedPregunta = await queryRunner.manager.save(pregunta);
// Vincular pregunta con sección
const seccionPregunta = new SeccionPregunta();
seccionPregunta.id_seccion = savedSeccion.id_seccion;
seccionPregunta.id_pregunta = savedPregunta.id_pregunta;
seccionPregunta.posicion = j + 1;
await queryRunner.manager.save(seccionPregunta);
// 4. Crear opciones para preguntas de tipo multiple/radio
if (preguntaDto.opciones && preguntaDto.opciones.length > 0) {
for (let k = 0; k < preguntaDto.opciones.length; k++) {
const opcionDto = preguntaDto.opciones[k];
// Crear opción
const opcion = new Opcion();
opcion.opcion = opcionDto.valor;
const savedOpcion = await queryRunner.manager.save(opcion);
// Vincular opción con pregunta
const preguntaOpcion = new PreguntaOpcion();
preguntaOpcion.id_pregunta = savedPregunta.id_pregunta;
// Utilizamos la opción como objeto, no como ID
preguntaOpcion.opcion = savedOpcion;
preguntaOpcion.posicion = k + 1;
await queryRunner.manager.save(preguntaOpcion);
}
}
}
}
}
}
await queryRunner.commitTransaction();
return {
success: true,
message: 'Cuestionario y evento creados exitosamente',
id_cuestionario: savedCuestionario.id_cuestionario,
id_evento: eventoExistente.id_evento,
};
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
async asociarBanner(id: number, banner: string) {
const cuestionario = await this.cuestionarioRepository.findOne({
where: { id_cuestionario: id },
});
if (!cuestionario) {
throw new NotFoundException(`Cuestionario con ID ${id} no encontrado`);
}
// Actualizar el banner del cuestionario
cuestionario.banner = banner;
return this.cuestionarioRepository.save(cuestionario);
}
async getCuestionarioOrFail(id_cuestionario: number): Promise<Cuestionario> {
const cuestionario = await this.cuestionarioRepository.findOne({
where: { id_cuestionario: id_cuestionario },
relations: ['evento'],
});
if (!cuestionario) {
throw new NotFoundException(
`Cuestionario con ID ${id_cuestionario} no encontrado`,
);
}
return cuestionario;
}
findAll() {
return this.cuestionarioRepository.find();
}
async findOne(id: number) {
const cuestionario = await this.cuestionarioRepository.findOne({
where: { id_cuestionario: id },
});
if (!cuestionario) {
throw new NotFoundException(`Cuestionario con ID ${id} no encontrado`);
}
return cuestionario;
}
async findCompleto(id: number) {
// Obtener el cuestionario básico
const cuestionario = await this.cuestionarioRepository.findOne({
where: { id_cuestionario: id },
relations: ['evento'], // Incluir la relación con el evento
});
if (!cuestionario) {
throw new NotFoundException(`Cuestionario con ID ${id} no encontrado`);
}
// Para fines de demostración, usar valores hardcodeados
// para el tipo de cuestionario según get_formulario_feria.ts
const tipoCuestionario = {
id_tipo_cuestionario: 1,
tipo_cuestionario: 'Encuesta',
};
// Mapeador de ID de tipo de pregunta a nombres conocidos
const tiposPreguntaMap = {
1: { id_tipo: 1, tipo_pregunta: TipoPreguntaEnum.AbiertaParrafo },
2: { id_tipo: 2, tipo_pregunta: TipoPreguntaEnum.AbiertaRespuestaCorta },
3: { id_tipo: 3, tipo_pregunta: TipoPreguntaEnum.Cerrada },
4: { id_tipo: 4, tipo_pregunta: TipoPreguntaEnum.Multiple },
};
// Obtener las relaciones cuestionario-seccion
const cuestionarioSecciones = await this.cuestionarioSeccionRepository.find(
{
where: { id_cuestionario: id },
order: { posicion: 'ASC' },
},
);
// Obtener todas las secciones
const seccionIds = cuestionarioSecciones.map((cs) => cs.id_seccion);
const secciones = await this.seccionRepository.find({
where: { id_seccion: In(seccionIds) },
});
const seccionesFormateadas = await Promise.all(
cuestionarioSecciones.map(async (cs) => {
const seccion = secciones.find((s) => s.id_seccion === cs.id_seccion);
if (!seccion) return null;
// Obtener relaciones sección-pregunta
const seccionPreguntas = await this.seccionPreguntaRepository.find({
where: { id_seccion: seccion.id_seccion },
order: { posicion: 'ASC' },
});
// Obtener preguntas
const preguntaIds = seccionPreguntas.map((sp) => sp.id_pregunta);
const preguntas = await this.preguntaRepository.find({
where: { id_pregunta: In(preguntaIds) },
});
// Formatear cada pregunta según el formato requerido
const preguntasFormateadas = await Promise.all(
seccionPreguntas.map(async (sp) => {
const pregunta = preguntas.find(
(p) => p.id_pregunta === sp.id_pregunta,
);
if (!pregunta) return null;
// Usar el mapeo de tipos de pregunta definido arriba
const tipoPregunta = tiposPreguntaMap[
pregunta.id_tipo_pregunta
] || {
id_tipo: pregunta.id_tipo_pregunta,
tipo_pregunta: 'Desconocido',
};
// Obtener opciones para preguntas de tipo multiple/radio
const preguntaOpciones = await this.preguntaOpcionRepository.find({
where: { id_pregunta: pregunta.id_pregunta },
relations: ['opcion'],
order: { posicion: 'ASC' },
});
// Formatear las opciones según el formato requerido
const opcionesFormateadas = preguntaOpciones.map((po) => ({
id_pregunta_opcion: po.id_pregunta_opcion,
posicion: po.posicion,
id_opcion: po.opcion.id_opcion,
opcion: {
id_opcion: po.opcion.id_opcion,
opcion: po.opcion.opcion,
},
}));
// Construir objeto de pregunta según el formato requerido
return {
id_seccion_pregunta: sp.id_seccion_pregunta,
posicion: sp.posicion,
pregunta: {
id_pregunta: pregunta.id_pregunta,
pregunta: pregunta.pregunta,
contador_opcion: pregunta.contador_opcion,
obligatoria: pregunta.obligatoria,
id_tipo_pregunta: pregunta.id_tipo_pregunta,
validacion: pregunta.validacion,
tipo_pregunta: {
id_tipo: tipoPregunta.id_tipo,
tipo_pregunta: tipoPregunta.tipo_pregunta,
},
opciones: opcionesFormateadas,
},
};
}),
).then((results) => results.filter((p) => p !== null));
// Construir objeto de sección según el formato requerido
return {
id_cuestionario_seccion: cs.id_cuestionario_seccion,
posicion: cs.posicion,
seccion: {
id_seccion: seccion.id_seccion,
contador_pregunta: seccion.contador_pregunta,
descripcion: seccion.descripcion,
titulo: seccion.titulo,
},
preguntas: preguntasFormateadas,
};
}),
).then((results) => results.filter((s) => s !== null));
// Construir objeto final respetando el formato de get_formulario_feria.ts
return {
tipo_cuestionario: {
id_tipo_cuestionario: tipoCuestionario.id_tipo_cuestionario,
tipo_cuestionario: tipoCuestionario.tipo_cuestionario,
},
evento: cuestionario.evento
? {
id_evento: cuestionario.evento.id_evento,
nombre_evento: cuestionario.evento.nombre_evento,
descripcion_evento: cuestionario.evento.descripcion_evento,
banner: cuestionario.evento.banner,
tipo_evento: cuestionario.evento.tipo_evento,
fecha_inicio: cuestionario.evento.fecha_inicio
? cuestionario.evento.fecha_inicio.toISOString()
: null,
fecha_fin: cuestionario.evento.fecha_fin
? cuestionario.evento.fecha_fin.toISOString()
: null,
}
: null,
cuestionario: {
id_cuestionario: cuestionario.id_cuestionario,
nombre_form: cuestionario.nombre_form,
contador_secciones: cuestionario.contador_secciones,
descripcion: cuestionario.descripcion,
editable: cuestionario.editable,
fecha_inicio: cuestionario.fecha_inicio
? cuestionario.fecha_inicio.toISOString()
: null,
fecha_fin: cuestionario.fecha_fin
? cuestionario.fecha_fin.toISOString()
: null,
id_tipo_cuestionario: cuestionario.id_tipo_cuestionario,
id_evento: cuestionario.id_evento || null,
secciones: seccionesFormateadas,
},
};
}
async update(id: number, updateCuestionarioDto: UpdateCuestionarioDto) {
// Si el DTO incluye el campo "evento" (string), debemos procesarlo aparte
if (updateCuestionarioDto.evento) {
// Buscar o crear evento
let evento = await this.eventoRepository.findOne({
where: { nombre_evento: updateCuestionarioDto.evento },
});
if (!evento) {
// Crear el evento
const nuevoEvento = {
nombre_evento: updateCuestionarioDto.evento,
tipo_evento: 'Predeterminado',
fecha_inicio: new Date(),
fecha_fin: new Date(Date.now() + 86400000),
};
evento = await this.eventoRepository.save(nuevoEvento);
}
// Asignar el ID del evento al DTO de actualización
updateCuestionarioDto.id_evento = evento.id_evento;
// Eliminar la propiedad evento para evitar conflictos
delete updateCuestionarioDto.evento;
}
// Preparar los datos para la actualización
const updateData: any = { ...updateCuestionarioDto };
return this.cuestionarioRepository.update(id, updateData);
}
remove(id: number) {
return this.cuestionarioRepository.delete(id);
}
}