develop #9

Merged
jalvarado merged 49 commits from develop into master 2023-08-04 15:42:54 +00:00
107 changed files with 8840 additions and 1183 deletions
+15
View File
@@ -0,0 +1,15 @@
PORT=
DB_HOST=
DB_USER=
DB_PASSWORD=
DB_NAME=
DB_HOST_DSC=
DB_USER_DSC=
DB_PASS_DSC=
DB_NAME_DSC=
NODEMAILER_SERVICE=
NODEMAILER_USER=
NODEMAILER_PASWORD=
+3 -1
View File
@@ -1,3 +1,4 @@
.env
# compiled output
/dist
/node_modules
@@ -32,4 +33,5 @@ lerna-debug.log*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/extensions.json
+6286 -1153
View File
File diff suppressed because it is too large Load Diff
+32 -1
View File
@@ -21,18 +21,48 @@
},
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/config": "^2.3.1",
"@nestjs/core": "^9.0.0",
"@nestjs/jwt": "^10.0.2",
"@nestjs/passport": "^9.0.3",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/serve-static": "^3.0.1",
"@nestjs/swagger": "^6.2.1",
"@nestjs/typeorm": "^9.0.1",
"@types/multer": "^1.4.7",
"bcrypt": "^5.1.0",
"blob-stream": "^0.1.3",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"date-fns": "^2.30.0",
"exceljs": "^4.3.0",
"moment": "^2.29.4",
"multer": "^1.4.5-lts.1",
"mysql2": "^3.1.2",
"nodemailer": "^6.9.1",
"passport": "^0.6.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pdf-lib": "^1.17.1",
"pdfkit": "^0.13.0",
"pg": "^8.9.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0"
"rxjs": "^7.2.0",
"swagger-ui-express": "^4.6.1",
"sybase": "^1.2.3",
"typeorm": "^0.3.12",
"uuid": "^9.0.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@jridgewell/sourcemap-codec": "^1.4.14",
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "29.2.4",
"@types/node": "18.11.18",
"@types/passport-local": "^1.0.35",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
@@ -40,6 +70,7 @@
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "29.3.1",
"pdfmake": "^0.2.7",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
View File
+2
View File
@@ -0,0 +1,2 @@
INSERT INTO tipo_miembro(tipo_miembro) VALUES("Admin");
INSERT INTO tipo_miembro(tipo_miembro) VALUES("Miembro");
+2
View File
@@ -0,0 +1,2 @@
INSERT INTO miembro (nombre, apellido_paterno, apellido_materno, id_tipo_miembro, email, password, descripcion, semestre, cuenta)
VALUES ('Jorge', 'Alvarado', 'Reyes', 1, 'Admin@unam.com', '$2b$10$1ExBjP1J1PET5N4m9Thv7O0l0nNjPsMYQW6.TZveaCFz0OkLh06Dy', 'Estudiante de Ingeniería en Sistemas', '4', 123456789);
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ActividadController } from './actividad.controller';
describe('ActividadController', () => {
let controller: ActividadController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ActividadController],
}).compile();
controller = module.get<ActividadController>(ActividadController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
+4
View File
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('actividad')
export class ActividadController {}
+9
View File
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { ActividadController } from './actividad.controller';
import { ActividadService } from './actividad.service';
@Module({
controllers: [ActividadController],
providers: [ActividadService]
})
export class ActividadModule {}
+18
View File
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ActividadService } from './actividad.service';
describe('ActividadService', () => {
let service: ActividadService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ActividadService],
}).compile();
service = module.get<ActividadService>(ActividadService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
+4
View File
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class ActividadService {}
-22
View File
@@ -1,22 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});
+131 -4
View File
@@ -1,10 +1,137 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { EventosModule } from './eventos/eventos.module';
import { ParticipanteController } from './participante/participante.controller';
import { ParticipanteModule } from './participante/participante.module';
import { EventoParticipanteModule } from './evento-participante/evento-participante/evento-participante.module';
import { AuthModule } from './auth/auth.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { Evento } from './eventos/evento.entity';
import { Participante } from './participante/participante.entity';
import { EventoParticipante } from './evento-participante/evento-participante/eventoParticipante.entity';
import { InscripcionDscModule } from './inscripcion-dsc/inscripcion-dsc.module';
import { InscripcionAreaModule } from './inscripcion-area/inscripcion-area.module';
import { InscripcionStatusService } from './inscripcion-status/inscripcion-status.service';
import { InscripcionStatusController } from './inscripcion-status/inscripcion-status.controller';
import { InscripcionStatusModule } from './inscripcion-status/inscripcion-status.module';
import { PeriodoModule } from './periodo/periodo.module';
import { InscripcionUsuarioModule } from './inscripcion-usuario/inscripcion-usuario.module';
import { MiembroModule } from './miembro/miembro.module';
import { Miembro } from './miembro/entity/miembro.entity';
import { InscripcionArea } from './inscripcion-area/entity/inscripcion_area.entity';
import { InscripcionDSC } from './inscripcion-dsc/entity/inscripcion_dsc.entity';
import { InscripcionStatus } from './inscripcion-status/entity/inscripcion_status.entity';
import { InscripcionUsuario } from './inscripcion-usuario/entity/inscripcion_usuario.entity';
import { Area } from './catalogos/area.entity';
import { TipoMiembro } from './catalogos/tipo-miembro.entity';
import { Carrera } from './catalogos/carrera.entity';
import { Periodo } from './periodo/entity/periodo.entity';
import { MiembroProyectoModule } from './miembro-proyecto/miembro-proyecto.module';
import { MiembroContactoModule } from './miembro-contacto/miembro-contacto.module';
import { ProyectoModule } from './proyecto/proyecto.module';
import { ProyectoActividadModule } from './proyecto-actividad/proyecto-actividad.module';
import { ActividadModule } from './actividad/actividad.module';
import { MiembroProyecto } from './miembro-proyecto/entity/miembro_proyecto.entity';
import { MiembroContacto } from './miembro-contacto/entity/miembro_contacto.entity';
import { Proyecto } from './proyecto/entity/proyecto.entity';
import { Contacto } from './contacto/entity/contacto.entity';
import { Equipo } from './equipo/entity/equipo.entity';
import { EquipoEvento } from './equipo-evento/entity/equipo_evento.entity';
import { EquipoMiembro } from './equipo-miembro/entity/equipo_miembro.entity';
import { EmailService } from './email/email.service';
import { EmailController } from './email/email.controller';
import { EmailModule } from './email/email.module';
import { MulterModule } from '@nestjs/platform-express';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { CarruselModule } from './carrusel/carrusel.module';
import { Carrusel } from './entities/carrusel.entity';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
exclude: ['/api*'], // Excluir la ruta "/api" de servir archivos estáticos
}),
ConfigModule.forRoot({
envFilePath: '.env',
isGlobal: true,
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
type: 'mariadb',
host: configService.get('DB_HOST'),
port: configService.get('DB_PORT'),
username: configService.get('DB_USER'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: [
Evento,
Participante,
EventoParticipante,
/* Agregadas el 29 de febrero */
Miembro,
InscripcionArea,
InscripcionDSC,
InscripcionStatus,
InscripcionUsuario,
Area,
TipoMiembro,
Carrera,
Periodo,
/* Agregadas el 1 de marzo */
MiembroProyecto,
MiembroContacto,
Proyecto,
Contacto,
Equipo,
EquipoEvento,
EquipoMiembro,
/* Agregado el 2 de junio */
Carrusel
],
synchronize: true,
}),
}),
EventosModule,
ParticipanteModule,
EventoParticipanteModule,
AuthModule,
PassportModule,
JwtModule.register({}),
InscripcionDscModule,
InscripcionAreaModule,
InscripcionStatusModule,
PeriodoModule,
InscripcionUsuarioModule,
MiembroModule,
MiembroProyectoModule,
MiembroContactoModule,
ProyectoModule,
ProyectoActividadModule,
ActividadModule,
EmailModule,
MulterModule.register({
dest: './uploads', // directorio de destino para guardar los archivos cargados
}),
CarruselModule,
],
controllers: [
AppController,
ParticipanteController,
InscripcionStatusController,
],
providers: [AppService, InscripcionStatusService],
})
export class AppModule {}
export class AppModule {
static port: number;
constructor(private readonly configService: ConfigService) {
AppModule.port = this.configService.get('PORT');
}
}
+24
View File
@@ -0,0 +1,24 @@
import { Body, Controller, Post, Request, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AuthService } from './auth.service';
import { LoginMiembroDto } from './dto/loginMiembro.dto';
import { RegistrarMiembroDto } from './dto/registrarMiembro.dto';
@Controller('auth')
export class AuthController {
constructor(
private authService: AuthService,
) /* @InjectRepository(Usuario) private usuarioRepository: Repository<Usuario> */ {}
@Post('registro')
registrarUsuario(@Body() registrarMiembro: RegistrarMiembroDto) {
return this.authService.registrar(registrarMiembro);
}
@Post('login')
login(@Body() LoginUsuario: LoginMiembroDto) {
return this.authService.login(LoginUsuario);
}
}
+26
View File
@@ -0,0 +1,26 @@
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { jwtStrategy } from './jwt.strategy';
import { AuthController } from './auth.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './jwt.constants';
import { MiembroModule } from 'src/miembro/miembro.module';
import { MiembroService } from 'src/miembro/miembro.service';
import { Miembro } from 'src/miembro/entity/miembro.entity';
@Module({
imports: [
MiembroModule,
PassportModule,
TypeOrmModule.forFeature([Miembro]),
JwtModule.register({
secret: jwtConstants.secret,
signOptions: { expiresIn: '5h' },
}),
],
providers: [AuthService, jwtStrategy, MiembroService, jwtStrategy],
controllers: [AuthController],
})
export class AuthModule {}
+67
View File
@@ -0,0 +1,67 @@
import { HttpException, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';
import { hash } from 'bcrypt';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { compare } from 'bcrypt';
import { jwtConstants } from './jwt.constants';
import { LoginMiembroDto } from './dto/loginMiembro.dto';
import { Miembro } from 'src/miembro/entity/miembro.entity';
import { RegistrarMiembroDto } from './dto/registrarMiembro.dto';
@Injectable()
export class AuthService {
constructor(
private jwtService: JwtService,
@InjectRepository(Miembro) private miembroRepository: Repository<Miembro>,
) {}
async registrar(registrarMiembro: RegistrarMiembroDto) {
const { email, password } = registrarMiembro;
if (await this.miembroRepository.findOne({ where: { email } })) {
throw new HttpException('El usuario ya existe', 403);
}
const plainToHash = await hash(password, 10);
registrarMiembro = { ...registrarMiembro, password: plainToHash };
return this.miembroRepository.save(
this.miembroRepository.create(registrarMiembro),
);
}
async login(loginMiembro: LoginMiembroDto) {
const { email, password } = loginMiembro;
const usuario = await this.miembroRepository.findOne({ where: { email } });
if (!usuario) throw new HttpException('Usuario no encontrado', 404);
const checkPassword = await compare(password, (await usuario).password);
if (!checkPassword) throw new HttpException('Contraseña incorrecta', 403);
const payload = {
id_usuario: usuario.id_miembro,
id_tipoMiembro: usuario.id_tipo_miembro,
name: usuario.nombre,
};
/* console.log(payload); */
const token = this.jwtService.sign(payload); //firma el token
/* console.log(token); */
const data = {
user: {
usuario: usuario.nombre,
id: usuario.id_miembro,
email: usuario.email,
},
token,
};
return data;
}
}
+11
View File
@@ -0,0 +1,11 @@
import { IsEmail, MaxLength, MinLength } from "class-validator"
export class LoginMiembroDto {
@IsEmail()
email: string
@MinLength(5)
@MaxLength(15)
password: string
}
+33
View File
@@ -0,0 +1,33 @@
import { PartialType } from '@nestjs/swagger';
import { IsEmail, IsNotEmpty, MaxLength, MinLength } from 'class-validator';
import { LoginMiembroDto } from './loginMiembro.dto';
export class RegistrarMiembroDto extends PartialType(LoginMiembroDto) {
@IsNotEmpty()
nombre: string;
@IsNotEmpty()
apellido_paterno: string;
@IsNotEmpty()
apellido_materno: string;
@IsNotEmpty()
id_tipo_miembro: number;
@MinLength(10)
@MaxLength(15)
password: string;
descripcion: string
id_carrera: number
semestre: string
@IsNotEmpty()
cuenta: number
@IsEmail()
email: string;
}
+6
View File
@@ -0,0 +1,6 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
+3
View File
@@ -0,0 +1,3 @@
export const jwtConstants = {
secret: "SemillaSecreta"
}
+19
View File
@@ -0,0 +1,19 @@
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { jwtConstants } from './jwt.constants';
@Injectable()
export class jwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
});
}
async validate(payload: any) {
return { userId: payload.sub , username: payload.username };
}
}
+68
View File
@@ -0,0 +1,68 @@
import {
Body,
Controller,
Delete,
Get,
Param,
ParseIntPipe,
Post,
Res,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { CarruselService } from './carrusel.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { actualizarContador, contador } from './utils';
import * as path from 'path';
import { carruselDto } from './dto/carruselDto.dto';
@Controller('carrusel')
export class CarruselController {
constructor(private carruselService: CarruselService) {}
@Post('addImage')
@UseInterceptors(
FileInterceptor('imagen', {
storage: diskStorage({
destination: './public/carrusel',
filename: function (req, file, cb) {
actualizarContador();
const { ext } = path.parse(file.originalname);
const filename = `carrusel${contador}${ext}`;
return cb(null, filename);
},
}),
fileFilter: function (req, file, cb) {
if (!file.originalname.match(/\.(jpg|jpeg|png|webp)$/)) {
return {
message:
'Lo sentimos los archivos permitidos para usar el carrusel son jpg jpeg png webp',
};
}
cb(null, true);
},
}),
)
addImagenToCarrusel(
@Body() carruselDto: carruselDto,
@UploadedFile() file,
@Res() res,
) {
return this.carruselService.addImagenToCarrusel(
carruselDto,
file.filename,
res,
);
}
@Delete('delete/:id')
deleteImagenByRuta(@Param('id', ParseIntPipe) id: number) {
return this.carruselService.deleteImagenByRuta(id);
}
@Get('imagenes')
getAllImagenes() {
return this.carruselService.getAllImages();
}
}
+12
View File
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { CarruselController } from './carrusel.controller';
import { CarruselService } from './carrusel.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Carrusel } from 'src/entities/carrusel.entity';
@Module({
imports: [TypeOrmModule.forFeature([Carrusel])],
controllers: [CarruselController],
providers: [CarruselService],
})
export class CarruselModule {}
+59
View File
@@ -0,0 +1,59 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Carrusel } from 'src/entities/carrusel.entity';
import { Repository } from 'typeorm';
import { carruselDto } from './dto/carruselDto.dto';
import * as fs from 'fs';
import { Response } from 'express';
@Injectable()
export class CarruselService {
constructor(
@InjectRepository(Carrusel)
private carruselRepository: Repository<Carrusel>,
) {}
addImagenToCarrusel(
carruselDto: carruselDto,
filename,
res: Response,
): Promise<Carrusel> {
carruselDto.ruta = `/public/carrusel/${filename}`;
const carruselCreate = this.carruselRepository.create(carruselDto);
return this.carruselRepository
.save(carruselCreate)
.then((carrusel) => {
res
.status(201)
.json({ message: 'Imagen agregada correctamente', carrusel });
return carrusel;
})
.catch((error) => {
res.status(500).json({
message: 'Error al agregar la imagen',
error,
});
throw error;
});
}
async deleteImagenByRuta(id: number) {
try {
const res = await this.carruselRepository.findOne({
where: { id_imagen_carrusel: id },
});
await fs.promises.unlink(`./${res.ruta}`);
return this.carruselRepository.delete({ id_imagen_carrusel: id });
} catch (error) {
console.error('Error:', error);
throw error;
}
}
getAllImages(): Promise<Carrusel[]> {
return this.carruselRepository.find()
}
}
+9
View File
@@ -0,0 +1,9 @@
import { IsNotEmpty } from "class-validator";
export class carruselDto {
@IsNotEmpty()
ruta: string
@IsNotEmpty()
link: string
}
+5
View File
@@ -0,0 +1,5 @@
export let contador = 0
export const actualizarContador = () => {
contador++
}
+17
View File
@@ -0,0 +1,17 @@
import { InscripcionArea } from "src/inscripcion-area/entity/inscripcion_area.entity";
import { Column, Entity, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Area {
@PrimaryGeneratedColumn()
id_area: number
@Column({length:20, nullable:false})
area: string
@OneToMany(
() => InscripcionArea, (inscripcionArea) => inscripcionArea.area
)
inscripcionArea: InscripcionArea[]
}
+16
View File
@@ -0,0 +1,16 @@
import { Miembro } from "src/miembro/entity/miembro.entity";
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Carrera {
@PrimaryGeneratedColumn()
id_carrera: number
@Column({ length:40, nullable: false})
carrera: string
@OneToMany(
() => Miembro, (miembro) => miembro.carrera
)
miembro: Miembro
}
+16
View File
@@ -0,0 +1,16 @@
import { Miembro } from "src/miembro/entity/miembro.entity";
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class TipoMiembro {
@PrimaryGeneratedColumn()
id_tipo_miembro: number
@Column({length:15, nullable:false})
tipo_miembro: string
@OneToMany(
() => Miembro, (miembro) => miembro.tipoMiembro
)
miembro: Miembro[]
}
+27
View File
@@ -0,0 +1,27 @@
import { MiembroContacto } from "src/miembro-contacto/entity/miembro_contacto.entity";
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Contacto {
@PrimaryGeneratedColumn()
id_contacto: number
@Column({nullable:false})
email: string
@Column({length: 40})
horario: string
@Column({length: 75, nullable:true})
facebook: string
@Column({length: 60, nullable: true})
linkedin: string
@ManyToOne(
() => MiembroContacto, (miembroContacto) => miembroContacto.contacto
)
@JoinColumn({name: "id_contacto"})
miembroContacto: MiembroContacto
}
Binary file not shown.
+8
View File
@@ -0,0 +1,8 @@
import { IsEmail } from "class-validator"
export class EmailDto {
subject:string
text:string
}
+9
View File
@@ -0,0 +1,9 @@
interface Row {
Asistencia: number
Nombre: string
'Apellido Paterno': string
'Apellido Materno': string
Carrera: string
'Institución Procedencia': string
Email: string
}
+18
View File
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EmailController } from './email.controller';
describe('EmailController', () => {
let controller: EmailController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [EmailController],
}).compile();
controller = module.get<EmailController>(EmailController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
+51
View File
@@ -0,0 +1,51 @@
import {
Body,
Controller,
HttpException,
HttpStatus,
Param,
ParseIntPipe,
Post,
Res,
UploadedFile,
UseGuards,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { EmailDto } from './dto/emailDto.dto';
import { EmailService } from './email.service';
import { Response } from 'express';
import * as xlsx from 'xlsx';
import { AuthGuard } from '@nestjs/passport';
@Controller('email')
export class EmailController {
constructor(private readonly emailService: EmailService) {}
@UseGuards(AuthGuard('jwt'))
@Post('/evento/:id')
async sendEmail(
@Param('id', ParseIntPipe) id: number,
@Body() emailDto: EmailDto,
@Res() res,
): Promise<any> {
return this.emailService.sendEmail(id, emailDto, res);
}
@UseGuards(AuthGuard('jwt'))
@Post('constancias/:id')
@UseInterceptors(FileInterceptor('file'))
async sendConstancias(
@UploadedFile() file,
@Param('id', ParseIntPipe) id: number,
@Res() res,
) {
if (!file) {
throw new HttpException(
'No se ha cargado ningun archivo',
HttpStatus.BAD_REQUEST,
);
}
return this.emailService.sendConstancias(file, id, res);
}
}
+16
View File
@@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EventosModule } from 'src/eventos/eventos.module';
import { Participante } from 'src/participante/participante.entity';
import { EmailController } from './email.controller';
import { EmailService } from './email.service';
import { EventosService } from 'src/eventos/eventos.service';
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
import { Evento } from 'src/eventos/evento.entity';
@Module({
imports:[TypeOrmModule.forFeature([Participante, EventoParticipante, Evento])],
controllers:[EmailController],
providers:[EmailService, EventosService]
})
export class EmailModule {}
+18
View File
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EmailService } from './email.service';
describe('EmailService', () => {
let service: EmailService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [EmailService],
}).compile();
service = module.get<EmailService>(EmailService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
+179
View File
@@ -0,0 +1,179 @@
import {
HttpException,
HttpStatus,
Inject,
Injectable,
Res,
UploadedFile,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm';
import * as nodemailer from 'nodemailer';
import { EventosService } from 'src/eventos/eventos.service';
import { Participante } from 'src/participante/participante.entity';
import { Repository } from 'typeorm';
import { EmailDto } from './dto/emailDto.dto';
import * as xlsx from 'xlsx';
import * as pdfMake from 'pdfmake/build/pdfmake';
import * as pdfFonts from 'pdfmake/build/vfs_fonts';
/* import * as PDFDocument from 'pdfkit'; */
import * as fs from 'fs';
import * as path from 'path';
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
import { Response } from 'express';
import { format } from 'date-fns';
@Injectable()
export class EmailService {
private transporter;
constructor(
@InjectRepository(Participante)
private participanteRepository: Repository<Participante>,
private configService: ConfigService,
private readonly eventoService: EventosService,
) {
this.transporter = nodemailer.createTransport({
service: this.configService.get('NODEMAILER_SERVICE'),
auth: {
user: this.configService.get<string>('NODEMAILER_USER'),
pass: this.configService.get<string>('NODEMAILER_PASWORD'),
},
});
}
async sendEmail(id: number, message: EmailDto, res: Response) {
const participantes = await this.getEmailDeParticipantes(id);
participantes.map((res) => {
const emailDestinatario = res.email;
this.transporter.sendMail({
to: emailDestinatario,
subject: message.subject,
text: message.text,
});
});
return res.status(201).json({ message: 'Correos enviados con exito' });
}
async getEmailDeParticipantes(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.email'])
.getMany();
return participantes;
}
async sendConstancias(file, id_evento, res: Response) {
//traemos la info del evento
const evento = await this.eventoService.getEventosPorId(id_evento);
const workbook = xlsx.read(file.buffer);
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
const data = xlsx.utils.sheet_to_json(worksheet);
// Carga el PDF pre-diseñado
const existingPdfBytes = fs.readFileSync('src/email/DisenoConstancia.pdf');
for (let i = 0; i < data.length; i++) {
const row = data[i] as Row;
if(row.Email == undefined){
return res.status(400).json({ message: `El correo del renglon ${ i + 2} puede estar vacio o ser undefined`, solucion: `Seleccione el renglon donde ocurre el problema y borre todo lo de este renglon, Aunque parezca que el renglon esta vacio puede que haya un espacio en algun campo y esto genera que el sistema haga la lectura de este renglon`});
}
// Carga el PDF pre-diseñado en un documento PDF editable
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const pagina = pdfDoc.getPages();
const primeraPagina = pagina[0];
// Obtén el ancho y alto de la página
const { width, height } = primeraPagina.getSize();
// Obtén la fuente del texto
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
// Configura el tamaño del texto
const fontSize = 26;
const nombreParticipante = `${row['Apellido Paterno']} ${row['Apellido Materno']} ${row.Nombre}`;
// Calcula la anchura del texto del nombre del participante
const textWidth = font.widthOfTextAtSize(nombreParticipante, fontSize);
const centerX = (width - textWidth) / 2;
const centerY = (height - fontSize) / 2;
// Dibuja el texto centrado en la página
primeraPagina.drawText(nombreParticipante, {
x: centerX,
y: centerY + 70,
size: fontSize,
color: rgb(0, 0, 0),
});
const nombreCurso = `${evento.nombre}`;
// Calcula la anchura del texto del nombre del evento
const nombreCursoWidth = font.widthOfTextAtSize(nombreCurso, fontSize);
const centerXNombreCurso = (width - nombreCursoWidth) / 2;
const centerYNombreCurso = (height - fontSize) / 2;
primeraPagina.drawText(nombreCurso, {
x: centerXNombreCurso,
y: centerYNombreCurso - 17,
size: fontSize,
color: rgb(0, 0, 0),
});
const fechaCurso = `del ${this.formatoFecha(
evento.fecha_inicio,
)} al ${this.formatoFecha(evento.fecha_fin)}`;
// Calcula la anchura del texto del nombre del participante
const fechaCursoWidth = font.widthOfTextAtSize(fechaCurso, 20);
const centerXFechaCurso = (width - fechaCursoWidth) / 2;
const centerYFechaCurso = (height - 20) / 2;
primeraPagina.drawText(fechaCurso, {
x: centerXFechaCurso,
y: centerYFechaCurso - 55,
size: 20,
color: rgb(0, 0, 0),
});
// Guarda el PDF modificado en forma de bytes
const pdfBytes = await pdfDoc.save();
// Crea el objeto de adjunto con el nombre y contenido del PDF
const attachment = {
filename: `Constancia ${evento.nombre} - ${row.Nombre}_${row['Apellido Paterno']}.pdf`,
content: pdfBytes,
};
// Crea el objeto Blob y la URL para el PDF
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
// Envía el correo electrónico con la constancia adjunta
this.transporter.sendMail({
to: row.Email,
subject: `Constancia de asistencia a "${evento.nombre}"`,
text: `¡Un saludo ${row.Nombre}! Aquí está tu constancia de asistencia por el evento "${evento.nombre}". Agradecemos tu asistencia y constancia, esperamos seguir viéndote en eventos futuros.`,
attachments: [attachment],
});
}
return res.status(200).json({ message: 'Constancias enviadas con éxito' });
}
formatoFecha(fecha: Date) {
const fechaLimpia = format(fecha, 'dd/MM/yyyy');
return fechaLimpia;
}
}
+15
View File
@@ -0,0 +1,15 @@
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Carrusel {
@PrimaryGeneratedColumn()
id_imagen_carrusel: number
@Column({length: 40})
ruta: string
/* "/public/carrusel/carrusel1.jpg" */
@Column({length: 60})
link: string
/* "https://www.acatlan.unam.mx/" */
}
@@ -0,0 +1,27 @@
import { Equipo } from "src/equipo/entity/equipo.entity";
import { Evento } from "src/eventos/evento.entity";
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class EquipoEvento {
@PrimaryGeneratedColumn()
id_equipo_evento: number
@Column()
id_equipo: number
@Column()
id_evento: number
@ManyToOne(
() => Equipo, (equipo) => equipo.equipoEvento
)
@JoinColumn({name: "id_equipo"})
equipo: Equipo[]
@ManyToOne(
() => Evento, (evento) => evento.equipoEvento
)
@JoinColumn({name: "id_evento"})
evento: Evento
}
@@ -0,0 +1,27 @@
import { Equipo } from "src/equipo/entity/equipo.entity";
import { Miembro } from "src/miembro/entity/miembro.entity";
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class EquipoMiembro {
@PrimaryGeneratedColumn()
id_equipo_miembro:number
@Column()
id_equipo:number
@Column()
id_miembro:number
@ManyToOne(
() => Miembro, (miembro) => miembro.equipoMiembro
)
@JoinColumn({name:"id_miembro"})
miembro: Miembro[]
@ManyToOne(
() => Equipo,(equipo) => equipo.equipoMiembro
)
@JoinColumn({name: "id_equipo"})
equipo: Equipo[]
}
+25
View File
@@ -0,0 +1,25 @@
import { EquipoEvento } from "src/equipo-evento/entity/equipo_evento.entity";
import { EquipoMiembro } from "src/equipo-miembro/entity/equipo_miembro.entity";
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Equipo{
@PrimaryGeneratedColumn()
id_equipo: number
@Column({length:50, nullable:true})
nombre: string
@Column({length:100})
descripcion:string
@OneToMany(
() => EquipoMiembro, (equipoMiembro) => equipoMiembro.miembro
)
equipoMiembro: EquipoMiembro
@OneToMany(
() => EquipoEvento, (equipoEvento) => equipoEvento.evento
)
equipoEvento: EquipoEvento
}
@@ -0,0 +1,15 @@
import { IsNotEmpty, IsNumber } from "class-validator"
export class registrarEnEvento {
@IsNumber()
@IsNotEmpty()
id_eventoParticipante: number
@IsNumber()
@IsNotEmpty()
id_evento: number
@IsNumber()
@IsNotEmpty()
id_participante: number
}
@@ -0,0 +1,27 @@
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
export class RegistrarParticipanteDto {
@IsString()
@IsNotEmpty()
nombre: string;
@IsString()
@IsNotEmpty()
apellido_paterno: string;
@IsString()
@IsNotEmpty()
apellido_materno: string;
@IsString()
@IsNotEmpty()
carrera: string;
@IsString()
@IsNotEmpty()
institucion_procedencia: string;
@IsEmail()
email: string;
}
@@ -0,0 +1,16 @@
import { Body, Controller, Param, ParseIntPipe, Post } from '@nestjs/common';
import { RegistrarParticipanteDto } from './dto/registrarParticipanteDto.dto';
import { EventoParticipanteService } from './evento-participante.service';
import { EventoParticipante } from './eventoParticipante.entity';
@Controller('evento-participante')
export class EventoParticipanteController {
constructor(private readonly eventoParticipanteService: EventoParticipanteService){}
@Post(':id')
regitrarParticipante(@Param("id", ParseIntPipe)id: number, @Body() datos: RegistrarParticipanteDto){
return this.eventoParticipanteService.registrarParticipante(id, datos)
}
}
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Participante } from 'src/participante/participante.entity';
import { EventoParticipanteController } from './evento-participante.controller';
import { EventoParticipanteService } from './evento-participante.service';
import { EventoParticipante } from './eventoParticipante.entity';
@Module({
imports:[TypeOrmModule.forFeature([EventoParticipante,Participante])],
controllers: [EventoParticipanteController],
providers: [EventoParticipanteService]
})
export class EventoParticipanteModule {}
@@ -0,0 +1,78 @@
import { Body, ConflictException, Injectable, Param } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { RegistrarParticipanteDto } from './dto/registrarParticipanteDto.dto';
import { Evento } from 'src/eventos/evento.entity';
import { EventoParticipante } from './eventoParticipante.entity';
import { Participante } from 'src/participante/participante.entity';
import { info } from 'console';
import { registrarEnEvento } from './dto/registrarEnEvento.dto';
@Injectable()
export class EventoParticipanteService {
constructor(
@InjectRepository(Participante)
private participanteRepository: Repository<Participante>,
@InjectRepository(EventoParticipante)
private eventoParticipanteRepository: Repository<EventoParticipante>,
) {}
participanteExiste(email: string) {
return this.participanteRepository.findOne({ where: { email } });
}
async registrarEnEvento(
id_evento: number,
registrarParticipanteDto: RegistrarParticipanteDto,
) {
const participante = await this.participanteExiste(
registrarParticipanteDto.email,
);
/* console.log(id_evento);
console.log(participante); */
const registro = new EventoParticipante();
registro.id_evento = id_evento;
registro.id_participante = participante.id_participante;
return this.eventoParticipanteRepository.save(
this.eventoParticipanteRepository.create(registro),
);
}
registrarParticipante(
id_evento: number,
registrarParticipanteDto: RegistrarParticipanteDto,
) {
return this.participanteExiste(registrarParticipanteDto.email).then(
(res) => {
if (res) {
res.nombre = registrarParticipanteDto.nombre;
res.apellido_paterno = registrarParticipanteDto.apellido_paterno;
res.apellido_materno = registrarParticipanteDto.apellido_materno;
res.carrera = registrarParticipanteDto.carrera;
res.institucion_procedencia =
registrarParticipanteDto.institucion_procedencia;
//si el correo ya existe en la base de datos solo se le cambia el nombre, apellidos, carrera e institucion
return this.participanteRepository
.save(res)
.then((participanteActualizado) => {
this.registrarEnEvento(id_evento, participanteActualizado);
return participanteActualizado;
});
} else {
this.participanteRepository
.save(this.participanteRepository.create(registrarParticipanteDto))
.then((res) => {
this.registrarEnEvento(id_evento, res);
});
}
},
);
}
}
@@ -0,0 +1,26 @@
import { Evento } from 'src/eventos/evento.entity';
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, PrimaryGeneratedColumn } from 'typeorm';
import { Participante } from '../../participante/participante.entity';
@Entity()
export class EventoParticipante {
@PrimaryGeneratedColumn()
id_eventoParticipante: number
@Column({type: Number, nullable:false})
id_evento: number
@Column({type:Number, nullable:false})
id_participante: number
@ManyToOne(() => Evento, (evento) => evento.eventoParticipantes)
@JoinColumn({ name: 'id_evento' })
evento: Evento;
@ManyToOne(
() => Participante,
(participante) => participante.eventosParticipante,
)
@JoinColumn({ name: 'id_participante' })
participante: Participante;
}
+16
View File
@@ -0,0 +1,16 @@
export class actualizarEventoDto {
nombre?: string;
tipo_evento?: string;
organizadores?: string;
proyecto?: string;
modalidad?: string;
lugar?: string;
requisitos?: string;
cuota_inscripcion?: number;
patrocinador?: string;
tipo_acreditacion?: string;
descripcion?: string;
fecha_inicio?: Date;
fecha_fin?: Date;
fecha_limite_inscripcion?: Date;
}
+17
View File
@@ -0,0 +1,17 @@
export class crearEventoDto {
nombre: string;
tipo_evento: string;
organizadores: string;
proyecto: string;
modalidad: string;
lugar: string;
cupo: number;
requisitos: string;
cuota_inscripcion: number;
patrocinador: string;
tipo_acreditacion: string;
objetivo: string;
fecha_inicio: Date;
fecha_fin: Date;
fecha_limite_inscripcion: Date;
}
+79
View File
@@ -0,0 +1,79 @@
import { EquipoEvento } from 'src/equipo-evento/entity/equipo_evento.entity';
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
import {
Column,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity()
export class Evento {
@PrimaryGeneratedColumn()
id_evento: number;
@Column({length: 70, nullable: false })
nombre: string;
@Column({length: 15, nullable: false })
tipo_evento: string;
@Column({length: 100,nullable: false})
organizadores: string
@Column({length:30 ,nullable: true})
proyecto: string
@Column({length: 40,nullable: false})
modalidad: string
@Column({length: 60,nullable: false })
lugar: string;
@Column({nullable: false})
cupo: number;
@Column({length: 60, nullable: false })
requisitos: string;
@Column({type:'decimal', precision: 7, scale: 2, nullable: true })
cuota_inscripcion: number;
@Column({length: 50, nullable: true })
patrocinador: string;
@Column({length: 40, nullable: true })
tipo_acreditacion: string;
@Column({length: 200 ,nullable: false})
objetivo: string
@Column({ nullable: false, type: 'datetime' })
fecha_inicio: Date;
@Column({ nullable: false, type: 'datetime' })
fecha_fin: Date;
@Column({ nullable: false, type: 'datetime' })
fecha_limite_inscripcion: Date;
@Column({length:40 ,nullable: true })
horario: string;
@Column({ nullable: true })
estado: boolean;
@OneToMany(
() => EventoParticipante,
(eventoParticipante) => eventoParticipante.evento,
)
eventoParticipantes: EventoParticipante[];
@OneToMany(
() => EquipoEvento, (equipoEvento) => equipoEvento.evento
)
equipoEvento: EquipoEvento
}
+72
View File
@@ -0,0 +1,72 @@
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, Res, UseGuards } from '@nestjs/common';
import { Response } from 'express';
import { InjectRepository } from '@nestjs/typeorm';
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
import { Repository } from 'typeorm';
import { actualizarEventoDto } from './dto/actualizarEvento.dto';
import { crearEventoDto } from './dto/crearEvento.dto';
import { Evento } from './evento.entity';
import { EventosService } from './eventos.service';
import { AuthGuard } from '@nestjs/passport';
@Controller('eventos')
export class EventosController {
constructor(private readonly eventoService: EventosService){}
@Get()
getEventos(): Promise<Evento[]>{
return this.eventoService.getEventos()
}
@Get(':id')
getEventosPorId(@Param('id', ParseIntPipe)id: number):Promise<Evento>{
return this.eventoService.getEventosPorId(id)
}
@UseGuards(AuthGuard('jwt'))
@Post()
postEvento(@Body() nuevoEvento: crearEventoDto){
return this.eventoService.postEvento(nuevoEvento)
}
@UseGuards(AuthGuard('jwt'))
@Patch(':id')
patchEvento(@Param('id', ParseIntPipe)id:number, @Body() actualizacion: actualizarEventoDto){
return this.eventoService.updateEvento(id,actualizacion)
}
@UseGuards(AuthGuard('jwt'))
@Delete(':id')
deleteEvento(@Param('id', ParseIntPipe)id: number){
return this.eventoService.deleteEventoParticipante(id)
}
@Get(':id/cupos')
async getCupos(@Param('id', ParseIntPipe)id: number){
return this.eventoService.getCupos(id)
}
@UseGuards(AuthGuard('jwt'))
@Get(':id/participante')
async getParticipnates(@Param('id', ParseIntPipe)id:number){
return this.eventoService.getParticipantes(id)
}
@UseGuards(AuthGuard('jwt'))
@Get(':id/exportExcel')
async exportarExcel (@Param('id', ParseIntPipe)id:number ,@Res() res: Response){
this.eventoService.exportarParticipantes(id, res)
}
@Post('disponibles')
getEventosDisponibles (){
return this.eventoService.getEventosDisponibles()
}
@Post('disponibles/pendientesDconstancia')
getEventosDisponiblesPendientes(){
return this.eventoService.geteventosDisponiblesMasDosDias()
}
}
+14
View File
@@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
import { Participante } from 'src/participante/participante.entity';
import { Evento } from './evento.entity';
import { EventosController } from './eventos.controller';
import { EventosService } from './eventos.service';
@Module({
imports:[TypeOrmModule.forFeature([Evento, EventoParticipante, Participante])],
controllers:[EventosController],
providers:[EventosService]
})
export class EventosModule {}
+197
View File
@@ -0,0 +1,197 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
import { Participante } from 'src/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();
}
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();
}
}
@@ -0,0 +1,31 @@
import { Area } from 'src/catalogos/area.entity';
import { InscripcionDSC } from 'src/inscripcion-dsc/entity/inscripcion_dsc.entity';
import {
Column,
Entity,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity()
export class InscripcionArea {
@PrimaryGeneratedColumn()
id_inscripcionArea: number;
@Column()
id_inscripcion: number;
@Column()
id_area: number;
@ManyToOne(() => Area, (area) => area.inscripcionArea)
@JoinColumn({ name: 'id_area' })
area: Area;
@ManyToOne(
() => InscripcionDSC, (inscripcionDsc) => inscripcionDsc.inscripcionArea
)
@JoinColumn({name:"id_inscripcion"})
inscripcionDsc: InscripcionDSC
}
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('inscripcion-area')
export class InscripcionAreaController {}
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { InscripcionAreaController } from './inscripcion-area.controller';
import { InscripcionAreaService } from './inscripcion-area.service';
@Module({
controllers: [InscripcionAreaController],
providers: [InscripcionAreaService]
})
export class InscripcionAreaModule {}
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class InscripcionAreaService {}
@@ -0,0 +1,68 @@
import { InscripcionArea } from 'src/inscripcion-area/entity/inscripcion_area.entity';
import { InscripcionStatus } from 'src/inscripcion-status/entity/inscripcion_status.entity';
import { InscripcionUsuario } from 'src/inscripcion-usuario/entity/inscripcion_usuario.entity';
import { Periodo } from 'src/periodo/entity/periodo.entity';
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class InscripcionDSC {
@PrimaryGeneratedColumn()
id_inscripcion: number;
@Column({ default: 2})
validacion: number;
@Column({ nullable: false, default: false})
confirmacion: boolean;
@Column({ length: 5, unique: true, default: null})
folio: string;
@Column({ default: null})
monto: number;
@Column({ default: null})
hizoPago: boolean;
@Column({ length: 100, default: null})
rutaTicket: string;
@Column({ length: 6, default: null})
extension: string;
@Column({ default: null})
fechaInscripcion: Date;
@Column({ default: null})
fechaFin: Date;
@Column({nullable:false})
id_status: number;
@Column({nullable: false})
id_periodo: number;
@OneToMany(
() => InscripcionArea,
(inscripcionArea) => inscripcionArea.inscripcionDsc,
)
inscripcionArea: InscripcionArea[];
@ManyToOne(
() => InscripcionStatus, (inscripcionStatus) => inscripcionStatus.inscripcionDsc
)
@JoinColumn({name: "id_status"})
inscripcionStatus: InscripcionStatus
@ManyToOne(
() => Periodo, (periodo) => periodo.inscripcionDsc
)
@JoinColumn({name: "id_periodo"})
periodo: Periodo
@OneToMany(
() => InscripcionUsuario, (inscripcionUsuario) => inscripcionUsuario.inscripcionDsc
)
inscripcionUsuario: InscripcionUsuario[]
}
@@ -0,0 +1,59 @@
import {
Body,
Controller,
Post,
} from '@nestjs/common';
import { InscripcionDscService } from './inscripcion-dsc.service';
@Controller('inscripcion-dsc')
export class InscripcionDscController {
constructor(private readonly inscripcionService: InscripcionDscService) {}
@Post('confirmacion')
async confirmacionDsc(@Body() body: any) {
const { accountNumber } = body;
const userVerification = await this.inscripcionService.userVerification(accountNumber);
/* console.log(userVerification) */
if(!userVerification){
return {
error: true,
msj: 'El usuario no se encuentra inscrito',
desc: '',
};
}
const userInformation = userVerification;
/* console.log(userInformation[0].confirmacion) */
try{
/* console.log("verificando confirmacion:", userInformation);
*/ if (userInformation[0].confirmacion) {
return {
error: true,
msj: 'El usuario ya hizo la confirmación anteriormente',
desc: '',
};
}
} catch (err) {
return console.log(err);
}
try {
const confirmationResponse =
await this.inscripcionService.userConfirmation(accountNumber);
return {
error: false,
msj: 'Usuario confirmado exitosamente',
data: confirmationResponse,
};
} catch (err) {
return {
error: true,
msj: `No se pudo realizar la confirmación del usuario`,
desc: `${err}`,
};
}
}
}
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { InscripcionDscController } from './inscripcion-dsc.controller';
import { InscripcionDscService } from './inscripcion-dsc.service';
@Module({
controllers: [InscripcionDscController],
providers: [InscripcionDscService]
})
export class InscripcionDscModule {}
@@ -0,0 +1,83 @@
import { Injectable } from '@nestjs/common';
import { createConnection } from 'mysql2/promise';
@Injectable()
export class InscripcionDscService {
async userVerification(accountNumber: string) {
try {
const connection = await createConnection({
host: process.env.DB_HOST_DSC,
user: process.env.DB_USER_DSC,
password: process.env.DB_PASS_DSC,
database: process.env.DB_NAME_DSC,
});
const userInformationQuery = `SELECT A.id_cuenta, nombre, if(AI.platica=true,1,0) as confirmacion FROM alumno A
JOIN alumno_inscrito AI ON (A.id_cuenta = AI.id_cuenta)
JOIN periodo P ON (P.id_periodo = AI.id_periodo)
WHERE A.id_cuenta = "${accountNumber}" and P.activo=true`;
const qryEjemplo = `SELECT * FROM alumno WHERE id_cuenta="${accountNumber}";`;
const [results] = await connection.query(userInformationQuery);
const resultsArray = JSON.parse(JSON.stringify(results));
if (resultsArray.length === 0) return null;
/* console.log('The solution is: ', resultsArray); */
return results;
} catch (error) {
throw error;
}
}
async userConfirmation(accountNumber: string): Promise<any> {
try {
const connection = await createConnection({
host: process.env.DB_HOST_DSC,
user: process.env.DB_USER_DSC,
password: process.env.DB_PASS_DSC,
database: process.env.DB_NAME_DSC,
});
const userInformationQuery = `UPDATE alumno_inscrito SET platica=true
WHERE id_cuenta="${accountNumber}" and id_periodo=(SELECT id_periodo FROM periodo WHERE activo=true)`;
const qryEjemplo = `select platica from alumno_inscrito WHERE id_cuenta="${accountNumber}"`;
const [results] = await connection.query(userInformationQuery);
const resultsArray = JSON.parse(JSON.stringify(results));
if (resultsArray.length === 0) return null;
/* console.log('The solution is: ', resultsArray); */
return results;
} catch (error) {
throw error;
}
/* const { accountNumber } = data;
try {
this.validarNumeroCuenta(accountNumber);
} catch (error) {
throw error;
}
let userConfirmationQuery = `UPDATE alumno_inscrito SET platica=true
WHERE id_cuenta="${accountNumber}" and id_periodo=(SELECT id_periodo FROM periodo WHERE activo=true)`;
try {
const responseUserConfirmation = await connection.query(
userConfirmationQuery,
);
return responseUserConfirmation;
} catch (error) {
throw error;
}
} */
}
validarNumeroCuenta = (numeroCuenta) => {
if (typeof numeroCuenta !== 'string' || numeroCuenta.length > 9)
return numeroCuenta;
};
}
@@ -0,0 +1,17 @@
import { InscripcionDSC } from 'src/inscripcion-dsc/entity/inscripcion_dsc.entity';
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class InscripcionStatus {
@PrimaryGeneratedColumn()
id_inscripcion_status: number;
@Column({ nullable: false})
id_status: number;
@Column({ nullable: false})
status: number;
@OneToMany(() => InscripcionDSC, (inscripcionDsc) => inscripcionDsc.inscripcionStatus)
inscripcionDsc: InscripcionDSC[];
}
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('inscripcion-status')
export class InscripcionStatusController {}
@@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class InscripcionStatusModule {}
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class InscripcionStatusService {}
@@ -0,0 +1,29 @@
import { InscripcionDSC } from "src/inscripcion-dsc/entity/inscripcion_dsc.entity";
import { Miembro } from "src/miembro/entity/miembro.entity";
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class InscripcionUsuario {
@PrimaryGeneratedColumn()
id_inscripcion_usuario: number
@Column({nullable: false})
id_miembro: number
@Column({nullable: false})
id_inscripcion: number
@ManyToOne(
() => InscripcionDSC, (inscripcionDsc) => inscripcionDsc.inscripcionUsuario
)
@JoinColumn({name: "id_inscripcion"})
inscripcionDsc: InscripcionDSC
@ManyToOne(
() => Miembro, (miebro) => miebro.inscripcionUsuario
)
@JoinColumn({name: "id_miembro"})
miembro: Miembro[]
}
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('inscripcion-usuario')
export class InscripcionUsuarioController {}
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { InscripcionUsuarioController } from './inscripcion-usuario.controller';
import { InscripcionUsuarioService } from './inscripcion-usuario.service';
@Module({
controllers: [InscripcionUsuarioController],
providers: [InscripcionUsuarioService]
})
export class InscripcionUsuarioModule {}
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class InscripcionUsuarioService {}
+20 -2
View File
@@ -1,8 +1,26 @@
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { join } from 'path';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const config = new DocumentBuilder()
.addBearerAuth()
.setTitle('Documentacion')
.setDescription('des')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
app.useStaticAssets(join(__dirname, '..', 'public'), {
prefix: '/public/',
});
app.enableCors();
await app.listen(AppModule.port);
}
bootstrap();
@@ -0,0 +1,26 @@
import { Contacto } from "src/contacto/entity/contacto.entity";
import { Miembro } from "src/miembro/entity/miembro.entity";
import { Column, Entity, JoinColumn, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class MiembroContacto {
@PrimaryGeneratedColumn()
id_miembro_contacto: number
@Column()
id_miembro: number
@Column()
id_contacto: number
/* @OneToMany(
() => Miembro, (miembro) => miembro.miembroContacto
)
miembro: Miembro[] */
@OneToMany(
() => Contacto, (contacto) => contacto.miembroContacto
)
@JoinColumn({name: "id_contacto"})
contacto: Contacto
}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { MiembroContactoController } from './miembro-contacto.controller';
describe('MiembroContactoController', () => {
let controller: MiembroContactoController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [MiembroContactoController],
}).compile();
controller = module.get<MiembroContactoController>(MiembroContactoController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('miembro-contacto')
export class MiembroContactoController {}
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { MiembroContactoController } from './miembro-contacto.controller';
import { MiembroContactoService } from './miembro-contacto.service';
@Module({
controllers: [MiembroContactoController],
providers: [MiembroContactoService]
})
export class MiembroContactoModule {}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { MiembroContactoService } from './miembro-contacto.service';
describe('MiembroContactoService', () => {
let service: MiembroContactoService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [MiembroContactoService],
}).compile();
service = module.get<MiembroContactoService>(MiembroContactoService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class MiembroContactoService {}
@@ -0,0 +1,26 @@
import { Miembro } from "src/miembro/entity/miembro.entity";
import { Proyecto } from "src/proyecto/entity/proyecto.entity";
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class MiembroProyecto {
@PrimaryGeneratedColumn()
id_miembro_proyecto: number
@Column()
id_proyecto: number
@Column()
id_miembro: number
@ManyToOne(
() => Miembro, (miembro) => miembro.miembroProyecto
)
@JoinColumn({name: "id_miembro"})
miembro: Miembro[]
@OneToMany(
() => Proyecto, (proyecto) => proyecto.miembroProyecto
)
proyecto: Proyecto[]
}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { MiembroProyectoController } from './miembro-proyecto.controller';
describe('MiembroProyectoController', () => {
let controller: MiembroProyectoController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [MiembroProyectoController],
}).compile();
controller = module.get<MiembroProyectoController>(MiembroProyectoController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('miembro-proyecto')
export class MiembroProyectoController {}
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { MiembroProyectoController } from './miembro-proyecto.controller';
import { MiembroProyectoService } from './miembro-proyecto.service';
@Module({
controllers: [MiembroProyectoController],
providers: [MiembroProyectoService]
})
export class MiembroProyectoModule {}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { MiembroProyectoService } from './miembro-proyecto.service';
describe('MiembroProyectoService', () => {
let service: MiembroProyectoService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [MiembroProyectoService],
}).compile();
service = module.get<MiembroProyectoService>(MiembroProyectoService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class MiembroProyectoService {}
+82
View File
@@ -0,0 +1,82 @@
import { IsEmail } from 'class-validator';
import { Carrera } from 'src/catalogos/carrera.entity';
import { TipoMiembro } from 'src/catalogos/tipo-miembro.entity';
import { EquipoMiembro } from 'src/equipo-miembro/entity/equipo_miembro.entity';
import { InscripcionUsuario } from 'src/inscripcion-usuario/entity/inscripcion_usuario.entity';
import { MiembroContacto } from 'src/miembro-contacto/entity/miembro_contacto.entity';
import { MiembroProyecto } from 'src/miembro-proyecto/entity/miembro_proyecto.entity';
import {
Column,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity()
export class Miembro {
@PrimaryGeneratedColumn()
id_miembro: number;
@Column({ nullable: false, length: 40 })
nombre: string;
@Column({ nullable: false, length: 30 })
apellido_paterno: string;
@Column({ nullable: false, length: 30 })
apellido_materno: string;
@Column({ nullable: false })
id_tipo_miembro: number;
@Column({length: 40, nullable: false })
@IsEmail()
email: string;
@Column({length: 180, nullable: false })
password: string;
@Column({ length: 200, nullable:true})
descripcion: string;
@Column({nullable: true})
id_carrera: number;
@Column({ length: 40, nullable:true})
semestre: string;
@Column({ nullable: false })
cuenta: number;
@OneToMany(
() => InscripcionUsuario,
(inscripcionUsuario) => inscripcionUsuario.miembro,
)
inscripcionUsuario: InscripcionUsuario[];
@ManyToOne(() => TipoMiembro, (tipoMiembro) => tipoMiembro.miembro)
@JoinColumn({ name: 'id_tipo_miembro' })
tipoMiembro: TipoMiembro;
@ManyToOne(() => Carrera, (carrera) => carrera.miembro)
@JoinColumn({ name: 'id_carrera' })
carrera: Carrera;
/* @ManyToOne(
() => MiembroContacto, (miembroContacto) => miembroContacto.miembro
)
@JoinColumn({name: "id_miembro"})
miembroContacto: MiembroContacto */
@OneToMany(
() => MiembroProyecto, (miembroProyecto) => miembroProyecto.miembro
)
miembroProyecto: MiembroProyecto
@OneToMany(
() => EquipoMiembro, (equipoMiembro) => equipoMiembro.miembro
)
equipoMiembro: EquipoMiembro
}
+25
View File
@@ -0,0 +1,25 @@
import { Controller, Delete, Get, Param, ParseIntPipe, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
import { Miembro } from './entity/miembro.entity';
import { MiembroService } from './miembro.service';
@Controller('miembro')
export class MiembroController {
constructor(private readonly miembroService: MiembroService){}
@Get()
getUsuarios(): Promise<Miembro[]>{
return this.miembroService.getUsuarios()
}
@Get(':tipo')
getMiembros(@Param('tipo', ParseIntPipe)tipo: number): Promise<Miembro[]>{
return this.miembroService.getMiembros(tipo)
}
@Delete(':id')
deleteMiembro(@Param('id', ParseIntPipe)id: number){
return this.miembroService.deleteMiembro(id)
}
}
+12
View File
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Miembro } from './entity/miembro.entity';
import { MiembroController } from './miembro.controller';
import { MiembroService } from './miembro.service';
@Module({
imports:[TypeOrmModule.forFeature([Miembro])],
controllers: [MiembroController],
providers: [MiembroService]
})
export class MiembroModule {}
+35
View File
@@ -0,0 +1,35 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Miembro } from './entity/miembro.entity';
@Injectable()
export class MiembroService {
constructor(
@InjectRepository(Miembro) private miembroRepository: Repository<Miembro>,
) {}
getUsuarios(){
return this.miembroRepository.find()
}
getUsuario(email: string) {
return this.miembroRepository.findOne({
where: {
email,
},
});
}
getMiembros(tipo: number){
return this.miembroRepository.find({
where:{
id_tipo_miembro: tipo
}
})
}
deleteMiembro(id: number){
return this.miembroRepository.delete({id_miembro: id})
}
}
@@ -0,0 +1,5 @@
import { Controller, Post } from '@nestjs/common';
import { ParticipanteService } from './participante.service';
@Controller('participante')
export class ParticipanteController {}
+41
View File
@@ -0,0 +1,41 @@
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
@Entity()
export class Participante {
@PrimaryGeneratedColumn()
id_participante: number;
@Column({ type: String, nullable: false, length: 40 })
nombre: string;
@Column({ nullable: false, length: 30 })
apellido_paterno: string;
@Column({ nullable: false, length: 30 })
apellido_materno: string;
@Column({ nullable: true, length: 12 })
telefono: string;
@Column({ nullable: false, length: 40 })
email: string;
@Column({ nullable: true, length: 180}) //
password: string;
@Column({length:20, nullable: true }) //
tipo: string;
@Column({ nullable: true, length: 50})
institucion_procedencia: string;
@Column({ nullable: true, length:50})
carrera: string;
@OneToMany(
() => EventoParticipante,
(eventoParticipante) => eventoParticipante.participante,
)
eventosParticipante: EventoParticipante[];
}
+12
View File
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ParticipanteController } from './participante.controller';
import { Participante } from './participante.entity';
import { ParticipanteService } from './participante.service';
@Module({
imports:[TypeOrmModule.forFeature([Participante])],
controllers:[ParticipanteController],
providers: [ParticipanteService]
})
export class ParticipanteModule {}
+34
View File
@@ -0,0 +1,34 @@
import { ConflictException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { RegistrarParticipanteDto } from '../evento-participante/evento-participante/dto/registrarParticipanteDto.dto';
import { Participante } from './participante.entity';
@Injectable()
export class ParticipanteService {
constructor(
@InjectRepository(Participante)
private participanteRepository: Repository<Participante>,
) {}
async participanteExiste(email: string): Promise<Participante> {
/* const participante = await this.participanteRepository.findOne({
where: { correo: correo },
});
return participante !== undefined; */
return this.participanteRepository.findOne({ where: { email } });
}
async registrarParticipante(registrarParticipanteDto: RegistrarParticipanteDto) {
return this.participanteExiste(registrarParticipanteDto.email).then(
(participante) => {
if (participante) {
throw new ConflictException('Este usuario ya está registrado');
}
return this.participanteRepository.save(
this.participanteRepository.create(),
);
},
);
}
}
+17
View File
@@ -0,0 +1,17 @@
import { InscripcionDSC } from "src/inscripcion-dsc/entity/inscripcion_dsc.entity";
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Periodo {
@PrimaryGeneratedColumn()
id_periodo: number
@Column()
activo: number
@OneToMany(
() => InscripcionDSC, (inscripcionDsc) => inscripcionDsc.periodo
)
inscripcionDsc: InscripcionDSC[]
}
+4
View File
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('periodo')
export class PeriodoController {}
+9
View File
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { PeriodoController } from './periodo.controller';
import { PeriodoService } from './periodo.service';
@Module({
controllers: [PeriodoController],
providers: [PeriodoService]
})
export class PeriodoModule {}
+4
View File
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class PeriodoService {}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ProyectoActividadController } from './proyecto-actividad.controller';
describe('ProyectoActividadController', () => {
let controller: ProyectoActividadController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ProyectoActividadController],
}).compile();
controller = module.get<ProyectoActividadController>(ProyectoActividadController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
@@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('proyecto-actividad')
export class ProyectoActividadController {}
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { ProyectoActividadController } from './proyecto-actividad.controller';
import { ProyectoActividadService } from './proyecto-actividad.service';
@Module({
controllers: [ProyectoActividadController],
providers: [ProyectoActividadService]
})
export class ProyectoActividadModule {}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ProyectoActividadService } from './proyecto-actividad.service';
describe('ProyectoActividadService', () => {
let service: ProyectoActividadService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ProyectoActividadService],
}).compile();
service = module.get<ProyectoActividadService>(ProyectoActividadService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

Some files were not shown because too many files have changed in this diff Show More