Files
cedetec_api_nest/src/eventos/eventos.service.ts
T
2026-08-09 21:50:53 -06:00

203 lines
6.2 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { EventoParticipante } from '../evento-participante/evento-participante/eventoParticipante.entity';
import { Participante } from '../participante/participante.entity';
import { Between, MoreThanOrEqual, Repository } from 'typeorm';
import { actualizarEventoDto } from './dto/actualizarEvento.dto';
import { crearEventoDto } from './dto/crearEvento.dto';
import { Evento } from './evento.entity';
import * as ExcelJS from 'exceljs';
import { Response } from 'express';
@Injectable()
export class EventosService {
constructor(
@InjectRepository(Evento) private eventoRepository: Repository<Evento>,
@InjectRepository(EventoParticipante)
private eventoParticipanteRepository: Repository<EventoParticipante>,
@InjectRepository(Participante)
private participanteRepository: Repository<Participante>,
) {}
getEventos() {
return this.eventoRepository.find({
order: {
fecha_inicio: 'DESC',
},
});
}
public getEventosPorId(id: number) {
return this.eventoRepository.findOne({
where: {
id_evento: id,
},
});
}
postEvento(evento: crearEventoDto) {
const nuevoEvento = this.eventoRepository.create(evento);
return this.eventoRepository.save(nuevoEvento);
}
updateEvento(id: number, actualizacion: actualizarEventoDto) {
return this.eventoRepository.update({ id_evento: id }, actualizacion);
}
deleteParticipantes(id: number) {
this.eventoParticipanteRepository.delete({ id_evento: id });
}
deleteEvento(id: number) {
this.eventoRepository.delete({ id_evento: id });
}
async deleteEventoParticipante(id: number) {
const queryRunner =
this.eventoRepository.manager.connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
await this.deleteParticipantes(id);
await this.deleteEvento(id);
await queryRunner.commitTransaction();
} catch (err) {
await queryRunner.rollbackTransaction();
throw err;
} finally {
await queryRunner.release();
}
}
async getCupos(id: number) {
const evento = this.getEventosPorId(id);
if (!evento) throw new Error(`El evento con id:${id} no existe`);
const registrados = await this.eventoParticipanteRepository
.createQueryBuilder('ep')
.select('COUNT(ep.id_evento)', 'count')
.where('ep.id_evento = :eventoId', { eventoId: (await evento).id_evento })
.getRawOne();
const cupoOriginal = (await evento).cupo;
const cupoDisponible = cupoOriginal - registrados.count;
return { registrados: registrados.count, cupoDisponible, cupoOriginal };
}
async getParticipantes(idEvento: number) {
const participantes = await this.participanteRepository
.createQueryBuilder('participante')
.innerJoin('participante.eventosParticipante', 'eventoParticipante')
.innerJoin('eventoParticipante.evento', 'evento')
.where('evento.id_evento = :idEvento', { idEvento })
.select([
'participante.nombre',
'participante.apellido_paterno',
'participante.apellido_materno',
'participante.carrera',
'participante.email',
'participante.institucion_procedencia',
])
.getMany();
return participantes;
}
async exportarParticipantes(idEvento: number, res: Response): Promise<void> {
const participantes: Participante[] = await this.getParticipantes(idEvento);
/*console.log(participantes);*/
// Crear el workbook y la worksheet
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Participantes');
// Definir las columnas
worksheet.columns = [
{
header: 'Asistencia',
key: 'asistencia',
width: 10,
style: { alignment: { horizontal: 'center' } },
},
{
header: 'Nombre',
key: 'nombre',
width: 20,
style: { alignment: { horizontal: 'center' } },
},
{
header: 'Apellido Paterno',
key: 'apellido_paterno',
width: 20,
style: { alignment: { horizontal: 'center' } },
},
{
header: 'Apellido Materno',
key: 'apellido_materno',
width: 20,
style: { alignment: { horizontal: 'center' } },
},
{
header: 'Carrera',
key: 'carrera',
width: 20,
style: { alignment: { horizontal: 'center' } },
},
{
header: 'Email',
key: 'email',
width: 35,
style: { alignment: { horizontal: 'center' } },
},
{
header: 'Institución Procedencia',
key: 'institucion_procedencia',
width: 30,
style: { alignment: { horizontal: 'center' } },
},
];
// Agregar los datos a la worksheet
participantes.forEach((participante) => {
worksheet.addRow({
asistencia: '',
nombre: participante.nombre,
apellido_paterno: participante.apellido_paterno,
apellido_materno: participante.apellido_materno,
carrera: participante.carrera,
email: participante.email,
institucion_procedencia: participante.institucion_procedencia,
});
});
/* console.log(workbook.description); */
// Generar el archivo Excel y guardarlo en el servidor
const fileName = `participantes-${idEvento}.xlsx`;
// Configurar la respuesta HTTP para descargar el archivo
res.setHeader(
'Content-Type',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
);
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
// Escribir el archivo Excel en la respuesta HTTP
const buffer = await workbook.xlsx.writeBuffer();
res.send(buffer);
}
getEventosDisponibles() {
const hoy = new Date();
return this.eventoRepository.find({
where: {
fecha_fin: MoreThanOrEqual(hoy),
},
});
}
geteventosDisponiblesMasDosDias() {
const hoy = new Date();
return this.eventoRepository
.createQueryBuilder('evento')
.where(`DATE_ADD(evento.fecha_fin, INTERVAL 3 DAY) >= :hoy`, { hoy })
.andWhere('fecha_fin <= :hoy', { hoy })
.getMany();
}
}