From 282f921e4362d52a7b8a55b7d66834a4de98a661 Mon Sep 17 00:00:00 2001 From: miguel Date: Wed, 18 Jun 2025 12:41:30 -0600 Subject: [PATCH] Refactor code structure for improved readability and maintainability --- .../docs/cuestionario.examples.ts | 6 ++-- .../cuestionario_respondido.service.ts | 12 +++---- src/evento/dto/update.evento.dto.ts | 6 +++- src/evento/evento.controller.ts | 5 ++- src/evento/evento.service.ts | 31 ++++++++++++++---- .../participante_evento.service.ts | 2 +- src/pregunta/entities/pregunta.entity.ts | 1 + .../entities/trabajadore.entity.ts | 2 +- ...eg => banner-1750269883742-220110679.jpeg} | Bin 9 files changed, 46 insertions(+), 19 deletions(-) rename uploads/banners/{banner-1750119255813-528833393.jpeg => banner-1750269883742-220110679.jpeg} (100%) diff --git a/src/cuestionario/docs/cuestionario.examples.ts b/src/cuestionario/docs/cuestionario.examples.ts index 5bc4214..0e4010c 100644 --- a/src/cuestionario/docs/cuestionario.examples.ts +++ b/src/cuestionario/docs/cuestionario.examples.ts @@ -102,13 +102,13 @@ export const ejemploCuestionarioTrabajador = { validacion: TiposValidacion.COMUNIDAD_TRABAJADOR, }, { - titulo: 'Número de trabajador', + titulo: 'RFC', tipo: 'Abierta (Respuesta corta)', obligatoria: false, - validacion: TiposValidacion.CUENTA_TRABAJADOR, + validacion: TiposValidacion.RFC, }, { - titulo: 'Correo electrónico institucional', + titulo: 'Correo electrónico', tipo: 'Abierta (Respuesta corta)', obligatoria: true, validacion: TiposValidacion.CORREO_INSTITUCIONAL, diff --git a/src/cuestionario_respondido/cuestionario_respondido.service.ts b/src/cuestionario_respondido/cuestionario_respondido.service.ts index f702a1d..ed33e89 100644 --- a/src/cuestionario_respondido/cuestionario_respondido.service.ts +++ b/src/cuestionario_respondido/cuestionario_respondido.service.ts @@ -450,7 +450,7 @@ export class CuestionarioRespondidoService { return `This action removes a #${id} cuestionarioRespondido`; } - async generarReporteRespuestas(idCuestionario: number): Promise { + /* async generarReporteRespuestas(idCuestionario: number): Promise { const cuestionario = await this.cuestionarioRepository.findOne({ where: { id_cuestionario: idCuestionario }, relations: ['evento'], @@ -543,9 +543,9 @@ export class CuestionarioRespondidoService { } return csv; - } + } */ - /* async generarReporteRespuestas(idCuestionario: number): Promise { + async generarReporteRespuestas(idCuestionario: number): Promise { // Buscar el cuestionario para validar que existe const cuestionario = await this.cuestionarioRepository.findOne({ where: { id_cuestionario: idCuestionario }, @@ -586,12 +586,12 @@ export class CuestionarioRespondidoService { pe.fecha_asistencia FROM cuestionario_respondido cr JOIN participante p ON cr.id_participante = p.id_participante - LEFT JOIN participante_evento pe ON p.id_participante = pe.id_participante AND pe.id_evento = ? + LEFT JOIN participante_evento pe ON p.id_participante = pe.id_participante AND pe.id_cuestionario = ? WHERE cr.id_cuestionario = ? ORDER BY cr.fecha_respuesta DESC `, [ - cuestionario.evento ? cuestionario.evento.id_evento : null, + cuestionario.evento ? cuestionario.id_cuestionario : null, idCuestionario, ], ); @@ -711,5 +711,5 @@ export class CuestionarioRespondidoService { .join('\n'); return csvContent; - } */ + } } diff --git a/src/evento/dto/update.evento.dto.ts b/src/evento/dto/update.evento.dto.ts index 8f89f69..d567e22 100644 --- a/src/evento/dto/update.evento.dto.ts +++ b/src/evento/dto/update.evento.dto.ts @@ -8,9 +8,13 @@ export class UpdateEventoDto { tipo_evento?: string; @IsString() - @IsNotEmpty({ message: 'El nombre del evento es obligatorio' }) + @IsOptional() nombre_evento: string; + @IsString() + @IsOptional() + descripcion_evento: string; + @IsOptional() @Type(() => Date) @IsDate({ message: 'La fecha de inicio debe ser una fecha válida' }) diff --git a/src/evento/evento.controller.ts b/src/evento/evento.controller.ts index d77a7a4..f202559 100644 --- a/src/evento/evento.controller.ts +++ b/src/evento/evento.controller.ts @@ -7,6 +7,7 @@ import { ParseIntPipe, Patch, Post, + UnprocessableEntityException, UploadedFile, UseInterceptors, } from '@nestjs/common'; @@ -87,7 +88,9 @@ export class EventoController { @UploadedFile() file: Express.Multer.File, ) { if (!file) { - throw new Error('No se ha recibido un archivo válido'); + throw new UnprocessableEntityException( + 'No se ha subido ningún archivo o el archivo no es válido.', + ); } return this.eventoService.asociarBanner(id, file.filename); diff --git a/src/evento/evento.service.ts b/src/evento/evento.service.ts index ea2199d..a50ce57 100644 --- a/src/evento/evento.service.ts +++ b/src/evento/evento.service.ts @@ -9,6 +9,8 @@ import { MoreThan, Repository } from 'typeorm'; import { Evento } from './entities/evento.entity'; import { CreateEventoDto } from './dto/create-evento.dto'; import { UpdateEventoDto } from './dto/update.evento.dto'; +import { join } from 'path'; +import { existsSync, unlinkSync } from 'fs'; @Injectable() export class EventoService { @@ -40,6 +42,26 @@ export class EventoService { async asociarBanner(id: number, filename: string) { const evento = await this.getEventoOrFail(id); + // Si ya tiene un banner anterior, eliminarlo + if (evento.banner) { + const bannerPath = join( + __dirname, + '..', + '..', + 'uploads', + 'banners', + evento.banner, + ); + if (existsSync(bannerPath)) { + try { + unlinkSync(bannerPath); + } catch (err) { + console.error(`Error al eliminar el banner anterior: ${err.message}`); + } + } + } + + // Asociar el nuevo banner evento.banner = filename; return this.eventoRepository.save(evento); } @@ -76,9 +98,9 @@ export class EventoService { }, relations: ['cuestionarios'], // solo los cuestionarios, sin secciones }); - + return eventos; - } + } async getEventoOrFail(id_evento: number): Promise { const eventoFound = await this.eventoRepository.findOne({ @@ -125,10 +147,7 @@ export class EventoService { }); } - async getCuestionarioEvento( - id_evento: number, - id_cuestionario: number, - ) { + async getCuestionarioEvento(id_evento: number, id_cuestionario: number) { const evento = await this.eventoRepository.findOne({ where: { id_evento }, relations: ['cuestionarios'], diff --git a/src/participante_evento/participante_evento.service.ts b/src/participante_evento/participante_evento.service.ts index 83b8f74..2b1d71e 100644 --- a/src/participante_evento/participante_evento.service.ts +++ b/src/participante_evento/participante_evento.service.ts @@ -72,7 +72,7 @@ export class ParticipanteEventoService { id_participante, id_cuestionario: id_evento, }, - relations: ['evento', 'participante'], + relations: ['participante'], }); if (!participante_eventoFound) { diff --git a/src/pregunta/entities/pregunta.entity.ts b/src/pregunta/entities/pregunta.entity.ts index 8b54cc8..4ba1d32 100644 --- a/src/pregunta/entities/pregunta.entity.ts +++ b/src/pregunta/entities/pregunta.entity.ts @@ -26,6 +26,7 @@ export enum TiposValidacion { GENERO = 'genero', CARRERA = 'carrera', INSTITUCION = 'institucion', + RFC = 'rfc', } @Entity() diff --git a/src/trabajadores/entities/trabajadore.entity.ts b/src/trabajadores/entities/trabajadore.entity.ts index a2d1206..75f1df8 100644 --- a/src/trabajadores/entities/trabajadore.entity.ts +++ b/src/trabajadores/entities/trabajadore.entity.ts @@ -5,7 +5,7 @@ export class RegistroTrabajador { @PrimaryGeneratedColumn() id_trabajador: number; - @Column({ type: 'varchar', length: 20, unique: true }) + @Column({ type: 'varchar', length: 20, unique: true, nullable: true }) numero_trabajador: string; @Column({ type: 'varchar', length: 13, unique: true }) diff --git a/uploads/banners/banner-1750119255813-528833393.jpeg b/uploads/banners/banner-1750269883742-220110679.jpeg similarity index 100% rename from uploads/banners/banner-1750119255813-528833393.jpeg rename to uploads/banners/banner-1750269883742-220110679.jpeg