Compare commits
10 Commits
cupo_evento
...
email
| Author | SHA1 | Date | |
|---|---|---|---|
| d237c594ca | |||
| 42652f4fc1 | |||
| 7a712928bd | |||
| e098a52fd8 | |||
| 6d6eb825d2 | |||
| 357121500b | |||
| 4d6435ac8a | |||
| 569dbca11f | |||
| 0158b6af98 | |||
| 498e70e589 |
@@ -1,12 +1,22 @@
|
|||||||
PORT=5089
|
PORT=5089
|
||||||
|
|
||||||
DB_HOST=132.248.180.82
|
# DB_HOST=132.248.180.82
|
||||||
DB_USER=user_cedetec
|
# DB_USER=user_cedetec
|
||||||
DB_PASSWORD=c3t3d3c
|
# DB_PASSWORD=c3t3d3c
|
||||||
DB_NAME=Betelgeuse_Cedetec_Prueba
|
# DB_NAME=Betelgeuse_Cedetec_Prueba
|
||||||
DB_PORT=
|
# DB_PORT=
|
||||||
|
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_USER=root
|
||||||
|
DB_PASSWORD=Dosmiluno2001
|
||||||
|
DB_NAME=cedetec_proyectos
|
||||||
|
DB_PORT=3306
|
||||||
|
|
||||||
DB_HOST_DSC = 132.248.180.82
|
DB_HOST_DSC = 132.248.180.82
|
||||||
DB_USER_DSC = sites_user
|
DB_USER_DSC = sites_user
|
||||||
DB_PASS_DSC = F0rTest
|
DB_PASS_DSC = F0rTest
|
||||||
DB_NAME_DSC = sat
|
DB_NAME_DSC = sat
|
||||||
|
|
||||||
|
NODEMAILER_SERVICE = gmail
|
||||||
|
NODEMAILER_USER = cidwa1@pcpuma.acatlan.unam.mx
|
||||||
|
NODEMAILER_PASWORD = cidwaxd1,
|
||||||
+5
-1
@@ -8,4 +8,8 @@ DB_NAME=
|
|||||||
DB_HOST_DSC=
|
DB_HOST_DSC=
|
||||||
DB_USER_DSC=
|
DB_USER_DSC=
|
||||||
DB_PASS_DSC=
|
DB_PASS_DSC=
|
||||||
DB_NAME_DSC=
|
DB_NAME_DSC=
|
||||||
|
|
||||||
|
NODEMAILER_SERVICE=
|
||||||
|
NODEMAILER_USER=
|
||||||
|
NODEMAILER_PASWORD=
|
||||||
+1
-1
@@ -1,3 +1,4 @@
|
|||||||
|
.env
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist
|
/dist
|
||||||
/node_modules
|
/node_modules
|
||||||
@@ -34,4 +35,3 @@ lerna-debug.log*
|
|||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
.env
|
|
||||||
Generated
+4083
-1119
File diff suppressed because it is too large
Load Diff
+13
-1
@@ -26,24 +26,35 @@
|
|||||||
"@nestjs/jwt": "^10.0.2",
|
"@nestjs/jwt": "^10.0.2",
|
||||||
"@nestjs/passport": "^9.0.3",
|
"@nestjs/passport": "^9.0.3",
|
||||||
"@nestjs/platform-express": "^9.0.0",
|
"@nestjs/platform-express": "^9.0.0",
|
||||||
|
"@nestjs/serve-static": "^3.0.1",
|
||||||
"@nestjs/swagger": "^6.2.1",
|
"@nestjs/swagger": "^6.2.1",
|
||||||
"@nestjs/typeorm": "^9.0.1",
|
"@nestjs/typeorm": "^9.0.1",
|
||||||
|
"@types/multer": "^1.4.7",
|
||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
|
"blob-stream": "^0.1.3",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.0",
|
"class-validator": "^0.14.0",
|
||||||
|
"exceljs": "^4.3.0",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
|
"multer": "^1.4.5-lts.1",
|
||||||
"mysql2": "^3.1.2",
|
"mysql2": "^3.1.2",
|
||||||
|
"nodemailer": "^6.9.1",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
|
"pdf-lib": "^1.17.1",
|
||||||
|
"pdfkit": "^0.13.0",
|
||||||
"pg": "^8.9.0",
|
"pg": "^8.9.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"swagger-ui-express": "^4.6.1",
|
"swagger-ui-express": "^4.6.1",
|
||||||
"sybase": "^1.2.3",
|
"sybase": "^1.2.3",
|
||||||
"typeorm": "^0.3.12"
|
"typeorm": "^0.3.12",
|
||||||
|
"uuid": "^9.0.0",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@jridgewell/sourcemap-codec": "^1.4.14",
|
||||||
"@nestjs/cli": "^9.0.0",
|
"@nestjs/cli": "^9.0.0",
|
||||||
"@nestjs/schematics": "^9.0.0",
|
"@nestjs/schematics": "^9.0.0",
|
||||||
"@nestjs/testing": "^9.0.0",
|
"@nestjs/testing": "^9.0.0",
|
||||||
@@ -58,6 +69,7 @@
|
|||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"jest": "29.3.1",
|
"jest": "29.3.1",
|
||||||
|
"pdfmake": "^0.2.7",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.20",
|
||||||
"supertest": "^6.1.3",
|
"supertest": "^6.1.3",
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
INSERT INTO tipo_miembro(tipo_miembro) VALUES("Admin");
|
INSERT INTO tipo_miembro(tipo_miembro) VALUES("Admin");
|
||||||
INSERT INTO tipo_miembro(tipo_miembro) VALUES("Alumno");
|
INSERT INTO tipo_miembro(tipo_miembro) VALUES("Miembro");
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
INSERT INTO miembro (nombre, apellido_paterno, apellido_materno, id_tipo_miembro, email, password, descripcion, semestre, cuenta)
|
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', 421010301);
|
VALUES ('Jorge', 'Alvarado', 'Reyes', 1, 'Admin@unam.com', '$2b$10$1ExBjP1J1PET5N4m9Thv7O0l0nNjPsMYQW6.TZveaCFz0OkLh06Dy', 'Estudiante de Ingeniería en Sistemas', '4', 123456789);
|
||||||
|
|||||||
+18
-5
@@ -7,14 +7,12 @@ import { EventosModule } from './eventos/eventos.module';
|
|||||||
import { ParticipanteController } from './participante/participante.controller';
|
import { ParticipanteController } from './participante/participante.controller';
|
||||||
import { ParticipanteModule } from './participante/participante.module';
|
import { ParticipanteModule } from './participante/participante.module';
|
||||||
import { EventoParticipanteModule } from './evento-participante/evento-participante/evento-participante.module';
|
import { EventoParticipanteModule } from './evento-participante/evento-participante/evento-participante.module';
|
||||||
import { UsuarioModule } from './usuario/usuario.module';
|
|
||||||
import { AuthModule } from './auth/auth.module';
|
import { AuthModule } from './auth/auth.module';
|
||||||
import { PassportModule } from '@nestjs/passport';
|
import { PassportModule } from '@nestjs/passport';
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
import { Evento } from './eventos/evento.entity';
|
import { Evento } from './eventos/evento.entity';
|
||||||
import { Participante } from './participante/participante.entity';
|
import { Participante } from './participante/participante.entity';
|
||||||
import { EventoParticipante } from './evento-participante/evento-participante/eventoParticipante.entity';
|
import { EventoParticipante } from './evento-participante/evento-participante/eventoParticipante.entity';
|
||||||
import { Usuario } from './usuario/usuario.entity';
|
|
||||||
import { InscripcionDscModule } from './inscripcion-dsc/inscripcion-dsc.module';
|
import { InscripcionDscModule } from './inscripcion-dsc/inscripcion-dsc.module';
|
||||||
import { InscripcionAreaModule } from './inscripcion-area/inscripcion-area.module';
|
import { InscripcionAreaModule } from './inscripcion-area/inscripcion-area.module';
|
||||||
import { InscripcionStatusService } from './inscripcion-status/inscripcion-status.service';
|
import { InscripcionStatusService } from './inscripcion-status/inscripcion-status.service';
|
||||||
@@ -44,9 +42,21 @@ import { Contacto } from './contacto/entity/contacto.entity';
|
|||||||
import { Equipo } from './equipo/entity/equipo.entity';
|
import { Equipo } from './equipo/entity/equipo.entity';
|
||||||
import { EquipoEvento } from './equipo-evento/entity/equipo_evento.entity';
|
import { EquipoEvento } from './equipo-evento/entity/equipo_evento.entity';
|
||||||
import { EquipoMiembro } from './equipo-miembro/entity/equipo_miembro.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 { CarouselController } from './carousel/carousel.controller';
|
||||||
|
import { CarouselService } from './carousel/carousel.service';
|
||||||
|
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
ServeStaticModule.forRoot({
|
||||||
|
rootPath: join(__dirname, '..', 'public'),
|
||||||
|
exclude: ['/api*'], // Excluir la ruta "/api" de servir archivos estáticos
|
||||||
|
}),
|
||||||
ConfigModule.forRoot({
|
ConfigModule.forRoot({
|
||||||
envFilePath: '.env',
|
envFilePath: '.env',
|
||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
@@ -65,7 +75,6 @@ import { EquipoMiembro } from './equipo-miembro/entity/equipo_miembro.entity';
|
|||||||
Evento,
|
Evento,
|
||||||
Participante,
|
Participante,
|
||||||
EventoParticipante,
|
EventoParticipante,
|
||||||
Usuario,
|
|
||||||
/* Agregadas el 29 de febrero */
|
/* Agregadas el 29 de febrero */
|
||||||
Miembro,
|
Miembro,
|
||||||
InscripcionArea,
|
InscripcionArea,
|
||||||
@@ -91,7 +100,6 @@ import { EquipoMiembro } from './equipo-miembro/entity/equipo_miembro.entity';
|
|||||||
EventosModule,
|
EventosModule,
|
||||||
ParticipanteModule,
|
ParticipanteModule,
|
||||||
EventoParticipanteModule,
|
EventoParticipanteModule,
|
||||||
UsuarioModule,
|
|
||||||
AuthModule,
|
AuthModule,
|
||||||
PassportModule,
|
PassportModule,
|
||||||
JwtModule.register({}),
|
JwtModule.register({}),
|
||||||
@@ -106,13 +114,18 @@ import { EquipoMiembro } from './equipo-miembro/entity/equipo_miembro.entity';
|
|||||||
ProyectoModule,
|
ProyectoModule,
|
||||||
ProyectoActividadModule,
|
ProyectoActividadModule,
|
||||||
ActividadModule,
|
ActividadModule,
|
||||||
|
EmailModule,
|
||||||
|
MulterModule.register({
|
||||||
|
dest: './uploads', // directorio de destino para guardar los archivos cargados
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
controllers: [
|
controllers: [
|
||||||
AppController,
|
AppController,
|
||||||
ParticipanteController,
|
ParticipanteController,
|
||||||
InscripcionStatusController,
|
InscripcionStatusController,
|
||||||
|
CarouselController,
|
||||||
],
|
],
|
||||||
providers: [AppService, InscripcionStatusService],
|
providers: [AppService, InscripcionStatusService, CarouselService],
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
static port: number;
|
static port: number;
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { Body, Controller, Post, Request, UseGuards } from '@nestjs/common';
|
import { Body, Controller, Post, Request, UseGuards } from '@nestjs/common';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Usuario } from 'src/usuario/usuario.entity';
|
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { LoginUsuarioDto } from './dto/loginUsuario.dto';
|
import { LoginMiembroDto } from './dto/loginMiembro.dto';
|
||||||
import { RegistrarMiembroDto } from './dto/registrarMiembro.dto';
|
import { RegistrarMiembroDto } from './dto/registrarMiembro.dto';
|
||||||
import { RegistrarUsuarioDto } from './dto/registrarUsuario.dto';
|
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
@@ -20,7 +18,7 @@ export class AuthController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Post('login')
|
@Post('login')
|
||||||
login(@Body() LoginUsuario: LoginUsuarioDto) {
|
login(@Body() LoginUsuario: LoginMiembroDto) {
|
||||||
return this.authService.login(LoginUsuario);
|
return this.authService.login(LoginUsuario);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export class LoginMiembroDto {
|
|||||||
@IsEmail()
|
@IsEmail()
|
||||||
email: string
|
email: string
|
||||||
|
|
||||||
@MinLength(10)
|
@MinLength(5)
|
||||||
@MaxLength(15)
|
@MaxLength(15)
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import { IsEmail, MaxLength, MinLength } from "class-validator";
|
|
||||||
|
|
||||||
export class LoginUsuarioDto {
|
|
||||||
@IsEmail()
|
|
||||||
email: string
|
|
||||||
|
|
||||||
@MinLength(10)
|
|
||||||
@MaxLength(15)
|
|
||||||
password: string
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { PartialType } from '@nestjs/swagger';
|
import { PartialType } from '@nestjs/swagger';
|
||||||
import { IsEmail, IsNotEmpty, MaxLength, MinLength } from 'class-validator';
|
import { IsEmail, IsNotEmpty, MaxLength, MinLength } from 'class-validator';
|
||||||
import { LoginUsuarioDto } from './loginUsuario.dto';
|
import { LoginMiembroDto } from './loginMiembro.dto';
|
||||||
|
|
||||||
export class RegistrarMiembroDto extends PartialType(LoginUsuarioDto) {
|
export class RegistrarMiembroDto extends PartialType(LoginMiembroDto) {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
nombre: string;
|
nombre: string;
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
import { PartialType } from '@nestjs/swagger';
|
|
||||||
import { IsEmail, IsNotEmpty, MaxLength, MinLength } from 'class-validator';
|
|
||||||
import { LoginUsuarioDto } from './loginUsuario.dto';
|
|
||||||
|
|
||||||
export class RegistrarUsuarioDto extends PartialType(LoginUsuarioDto) {
|
|
||||||
@IsNotEmpty()
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
@IsNotEmpty()
|
|
||||||
lastName: string;
|
|
||||||
|
|
||||||
@IsEmail()
|
|
||||||
email: string;
|
|
||||||
|
|
||||||
@MinLength(10)
|
|
||||||
@MaxLength(15)
|
|
||||||
password: string;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { CarouselController } from './carousel.controller';
|
||||||
|
|
||||||
|
describe('CarouselController', () => {
|
||||||
|
let controller: CarouselController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [CarouselController],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
controller = module.get<CarouselController>(CarouselController);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Res,
|
||||||
|
UploadedFile,
|
||||||
|
UseInterceptors,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { FileInterceptor } from '@nestjs/platform-express';
|
||||||
|
import { Response } from 'express';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import { diskStorage } from 'multer';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
@Controller('carousel')
|
||||||
|
export class CarouselController {
|
||||||
|
private images: string[] = [];
|
||||||
|
|
||||||
|
@Post('/imagenes')
|
||||||
|
@UseInterceptors(
|
||||||
|
FileInterceptor('file', {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './public',
|
||||||
|
filename: function (req, file, cb) {
|
||||||
|
const directory = './public';
|
||||||
|
const filePath = `${directory}/${file.originalname}`;
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
cb(
|
||||||
|
new BadRequestException(
|
||||||
|
`Ya existe un archivo con el nombre: '${file.originalname}'. Si está seguro de que no es el mismo, cambie el nombre del archivo.`,
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
cb(null, file.originalname);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
fileFilter: function (req, file, cb) {
|
||||||
|
const filetypes = /jpeg|jpg|webp|png/;
|
||||||
|
const extname = filetypes.test(
|
||||||
|
path.extname(file.originalname).toLowerCase(),
|
||||||
|
);
|
||||||
|
const mimetype = filetypes.test(file.mimetype);
|
||||||
|
if (mimetype && extname) {
|
||||||
|
return cb(null, true);
|
||||||
|
}
|
||||||
|
cb(
|
||||||
|
new BadRequestException(
|
||||||
|
'Lo sentimos, para mejorar la calidad de las imagenes en el carousel solo se aceptan imagenes con terminación: .jpeg .jpg .png .webp',
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
async addImage(@UploadedFile() file) {
|
||||||
|
return { msg: 'Imagen guardada con exito :)' };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete('/imagenes/:nombreArchivo')
|
||||||
|
async deleteImage(@Param('nombreArchivo') nombreArchivo: string) {
|
||||||
|
try {
|
||||||
|
await fs.promises.unlink(`./public/${nombreArchivo}`);
|
||||||
|
return { message: 'Imagen eliminada exitosamente' };
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error('Error al eliminar la imagen');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/imagenes')
|
||||||
|
async getImages(@Res() res: Response) {
|
||||||
|
// Leer el directorio 'public' para obtener el nombre de todos los archivos
|
||||||
|
|
||||||
|
const fileNames = await fs.promises.readdir('./public');
|
||||||
|
// Generar la URL para cada archivo y agregarla a un arreglo
|
||||||
|
|
||||||
|
// Filtrar solo las imágenes con las terminaciones "jpg", "webp" y "png"
|
||||||
|
const imageNames = fileNames.filter((fileName) =>
|
||||||
|
['.jpg', '.webp', '.png'].includes(path.extname(fileName)),
|
||||||
|
);
|
||||||
|
|
||||||
|
const imageUrls = imageNames.map((imageName) => `public/${imageName}`);
|
||||||
|
// Devolver el arreglo de URLs como respuesta
|
||||||
|
return res.json(imageUrls);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { CarouselService } from './carousel.service';
|
||||||
|
|
||||||
|
describe('CarouselService', () => {
|
||||||
|
let service: CarouselService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [CarouselService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<CarouselService>(CarouselService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CarouselService {
|
||||||
|
|
||||||
|
uploadImage(file){
|
||||||
|
/* console.log(file) */
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ export class Area {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id_area: number
|
id_area: number
|
||||||
|
|
||||||
@Column({length:60, nullable:false})
|
@Column({length:20, nullable:false})
|
||||||
area: string
|
area: string
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export class Carrera {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id_carrera: number
|
id_carrera: number
|
||||||
|
|
||||||
@Column({ length:70, nullable: false})
|
@Column({ length:40, nullable: false})
|
||||||
carrera: string
|
carrera: string
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export class TipoMiembro {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id_tipo_miembro: number
|
id_tipo_miembro: number
|
||||||
|
|
||||||
@Column({length:60, nullable:false})
|
@Column({length:15, nullable:false})
|
||||||
tipo_miembro: string
|
tipo_miembro: string
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ export class Contacto {
|
|||||||
@Column({nullable:false})
|
@Column({nullable:false})
|
||||||
email: string
|
email: string
|
||||||
|
|
||||||
@Column()
|
@Column({length: 40})
|
||||||
horario: string
|
horario: string
|
||||||
|
|
||||||
@Column({nullable:true})
|
@Column({length: 75, nullable:true})
|
||||||
facebook: string
|
facebook: string
|
||||||
|
|
||||||
@Column({nullable: true})
|
@Column({length: 60, nullable: true})
|
||||||
linkedin: string
|
linkedin: string
|
||||||
|
|
||||||
@ManyToOne(
|
@ManyToOne(
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { IsEmail } from "class-validator"
|
||||||
|
|
||||||
|
export class EmailDto {
|
||||||
|
|
||||||
|
subject:string
|
||||||
|
|
||||||
|
text:string
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
interface Row {
|
||||||
|
Asistencia: number
|
||||||
|
Nombre: string
|
||||||
|
'Apellido Paterno': string
|
||||||
|
'Apellido Materno': string
|
||||||
|
Carrera: string
|
||||||
|
'Institución Procedencia': string
|
||||||
|
Email: string
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
Param,
|
||||||
|
ParseIntPipe,
|
||||||
|
Post,
|
||||||
|
Res,
|
||||||
|
UploadedFile,
|
||||||
|
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';
|
||||||
|
|
||||||
|
|
||||||
|
@Controller('email')
|
||||||
|
export class EmailController {
|
||||||
|
constructor(private readonly emailService: EmailService) {}
|
||||||
|
|
||||||
|
@Post('/evento/:id')
|
||||||
|
async sendEmail(
|
||||||
|
@Param('id', ParseIntPipe) id: number,
|
||||||
|
@Body() emailDto: EmailDto,
|
||||||
|
): Promise<any> {
|
||||||
|
return this.emailService.sendEmail(id, emailDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('constancias')
|
||||||
|
@UseInterceptors(FileInterceptor('file'))
|
||||||
|
async sendConstancias(@UploadedFile() file, @Body('nombreEvento') nombreEvento: string,) {
|
||||||
|
if(!file) {
|
||||||
|
throw new HttpException("No se ha cargado ningun archivo", HttpStatus.BAD_REQUEST)
|
||||||
|
}
|
||||||
|
/* console.log(file) */
|
||||||
|
return this.emailService.sendConstancias(file, nombreEvento);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports:[TypeOrmModule.forFeature([Participante])],
|
||||||
|
controllers:[EmailController],
|
||||||
|
providers:[EmailService]
|
||||||
|
})
|
||||||
|
export class EmailModule {}
|
||||||
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EmailService {
|
||||||
|
private transporter;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(Participante)
|
||||||
|
private participanteRepository: Repository<Participante>,
|
||||||
|
private configService: ConfigService,
|
||||||
|
) {
|
||||||
|
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) {
|
||||||
|
const participantes = await this.getEmailDeParticipantes(id);
|
||||||
|
participantes.map((res) => {
|
||||||
|
const emailDestinatario = res.email;
|
||||||
|
this.transporter.sendMail({
|
||||||
|
to: emailDestinatario,
|
||||||
|
subject: message.subject,
|
||||||
|
text: message.text,
|
||||||
|
});
|
||||||
|
/*console.log("Email enviado a: ", res)*/
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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, nombreEvento) {
|
||||||
|
/* console.log(file) */
|
||||||
|
const workbook = xlsx.read(file.buffer);
|
||||||
|
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||||
|
const data = xlsx.utils.sheet_to_json(worksheet);
|
||||||
|
|
||||||
|
for (const row of data as Row[]) {
|
||||||
|
const pdfDoc = await PDFDocument.create();
|
||||||
|
const page = pdfDoc.addPage();
|
||||||
|
page.setSize(792, 612);
|
||||||
|
|
||||||
|
const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
|
||||||
|
const fontSize = 30;
|
||||||
|
const text = 'Constancia de asistencia';
|
||||||
|
const textWidth = font.widthOfTextAtSize(text, fontSize);
|
||||||
|
const textHeight = font.heightAtSize(fontSize);
|
||||||
|
|
||||||
|
page.drawText(text, {
|
||||||
|
x: (page.getWidth() - textWidth) / 2,
|
||||||
|
y: (page.getHeight() - textHeight) / 2,
|
||||||
|
size: fontSize,
|
||||||
|
font: font,
|
||||||
|
color: rgb(0/255, 0/255, 0/255),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { width, height } = page.getSize();
|
||||||
|
page.drawText(
|
||||||
|
`Se le otorga la constancia por su asistencia al evento: ${nombreEvento}`,
|
||||||
|
{
|
||||||
|
x: 50,
|
||||||
|
y: height - 50,
|
||||||
|
size: 12,
|
||||||
|
font: await pdfDoc.embedFont('Helvetica'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
page.drawText(
|
||||||
|
`A ${row['Apellido Paterno']} ${row['Apellido Materno']} ${row.Nombre}`,
|
||||||
|
{
|
||||||
|
x: 50,
|
||||||
|
y: height - 80,
|
||||||
|
size: 12,
|
||||||
|
font: await pdfDoc.embedFont('Helvetica'),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const pdfBytes = await pdfDoc.save();
|
||||||
|
const attachment = {
|
||||||
|
filename: `Constancia ${nombreEvento} - ${row.Nombre}_${row['Apellido Paterno']}.pdf`,
|
||||||
|
content: pdfBytes,
|
||||||
|
};
|
||||||
|
/* const blob = new Blob([pdfBytes], { type: 'application/pdf' });
|
||||||
|
const url = URL.createObjectURL(blob); */
|
||||||
|
this.transporter.sendMail({
|
||||||
|
to: row.Email,
|
||||||
|
subject: `Constancia de asistencia a "${nombreEvento}"`,
|
||||||
|
text: `¡Un saludo ${row.Nombre}! Aquí está tu constancia de asistencia por el evento "${nombreEvento}". Agradecemos tu asistencia y constancia, esperamos seguir viéndote en eventos futuros.`,
|
||||||
|
attachments: [attachment],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ export class Equipo{
|
|||||||
@Column({length:50, nullable:true})
|
@Column({length:50, nullable:true})
|
||||||
nombre: string
|
nombre: string
|
||||||
|
|
||||||
@Column({length:250})
|
@Column({length:100})
|
||||||
descripcion:string
|
descripcion:string
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ export class RegistrarParticipanteDto {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
carrera: string;
|
carrera: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
institucion_procedencia: string;
|
||||||
|
|
||||||
|
|
||||||
@IsEmail()
|
@IsEmail()
|
||||||
email: string;
|
email: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,25 @@ export class EventoParticipanteService {
|
|||||||
id_evento: number,
|
id_evento: number,
|
||||||
registrarParticipanteDto: RegistrarParticipanteDto,
|
registrarParticipanteDto: RegistrarParticipanteDto,
|
||||||
) {
|
) {
|
||||||
/* console.log(id_evento);
|
|
||||||
console.log(registrarParticipanteDto); */
|
|
||||||
return this.participanteExiste(registrarParticipanteDto.email).then(
|
return this.participanteExiste(registrarParticipanteDto.email).then(
|
||||||
(res) => {
|
(res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
this.registrarEnEvento(id_evento, 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 {
|
} else {
|
||||||
this.participanteRepository
|
this.participanteRepository
|
||||||
.save(this.participanteRepository.create(registrarParticipanteDto))
|
.save(this.participanteRepository.create(registrarParticipanteDto))
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
export class actualizarEventoDto {
|
export class actualizarEventoDto {
|
||||||
nombre?: string;
|
nombre?: string;
|
||||||
tipo_evento?: string;
|
tipo_evento?: string;
|
||||||
organizadores?: string[];
|
organizadores?: string;
|
||||||
proyecto?: string[];
|
proyecto?: string;
|
||||||
modalidad?: string[];
|
modalidad?: string;
|
||||||
lugar?: string;
|
lugar?: string;
|
||||||
requisitos?: string;
|
requisitos?: string;
|
||||||
cuota_inscripcion?: number;
|
cuota_inscripcion?: number;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
export class crearEventoDto {
|
export class crearEventoDto {
|
||||||
nombre: string;
|
nombre: string;
|
||||||
tipo_evento: string;
|
tipo_evento: string;
|
||||||
organizadores: string[];
|
organizadores: string;
|
||||||
proyecto: string[];
|
proyecto: string;
|
||||||
modalidad: string[];
|
modalidad: string;
|
||||||
lugar: string;
|
lugar: string;
|
||||||
cupo: number;
|
cupo: number;
|
||||||
requisitos: string;
|
requisitos: string;
|
||||||
cuota_inscripcion: number;
|
cuota_inscripcion: number;
|
||||||
patrocinador: string;
|
patrocinador: string;
|
||||||
tipo_acreditacion: string;
|
tipo_acreditacion: string;
|
||||||
descripcion: string;
|
objetivo: string;
|
||||||
fecha_inicio: Date;
|
fecha_inicio: Date;
|
||||||
fecha_fin: Date;
|
fecha_fin: Date;
|
||||||
fecha_limite_inscripcion: Date;
|
fecha_limite_inscripcion: Date;
|
||||||
|
|||||||
@@ -14,41 +14,41 @@ export class Evento {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id_evento: number;
|
id_evento: number;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({length: 70, nullable: false })
|
||||||
nombre: string;
|
nombre: string;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({length: 15, nullable: false })
|
||||||
tipo_evento: string;
|
tipo_evento: string;
|
||||||
|
|
||||||
@Column("simple-array", {nullable: false})
|
@Column({length: 100,nullable: false})
|
||||||
organizadores: string[]
|
organizadores: string
|
||||||
|
|
||||||
@Column("simple-array", {nullable: false})
|
@Column({length:30 ,nullable: true})
|
||||||
proyecto: string[]
|
proyecto: string
|
||||||
|
|
||||||
@Column("simple-array", {nullable: false})
|
@Column({length: 40,nullable: false})
|
||||||
modalidad: string[]
|
modalidad: string
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({length: 60,nullable: false })
|
||||||
lugar: string;
|
lugar: string;
|
||||||
|
|
||||||
@Column({nullable: false})
|
@Column({nullable: false})
|
||||||
cupo: number;
|
cupo: number;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({length: 60, nullable: false })
|
||||||
requisitos: string;
|
requisitos: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({type:'decimal', precision: 7, scale: 2, nullable: true })
|
||||||
cuota_inscripcion: number;
|
cuota_inscripcion: number;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({length: 50, nullable: true })
|
||||||
patrocinador: string;
|
patrocinador: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({length: 40, nullable: true })
|
||||||
tipo_acreditacion: string;
|
tipo_acreditacion: string;
|
||||||
|
|
||||||
@Column({nullable: false})
|
@Column({length: 200 ,nullable: false})
|
||||||
descripcion: string
|
objetivo: string
|
||||||
|
|
||||||
@Column({ nullable: false, type: 'datetime' })
|
@Column({ nullable: false, type: 'datetime' })
|
||||||
fecha_inicio: Date;
|
fecha_inicio: Date;
|
||||||
@@ -59,10 +59,7 @@ export class Evento {
|
|||||||
@Column({ nullable: false, type: 'datetime' })
|
@Column({ nullable: false, type: 'datetime' })
|
||||||
fecha_limite_inscripcion: Date;
|
fecha_limite_inscripcion: Date;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({length:40 ,nullable: true })
|
||||||
evento_identificador: string;
|
|
||||||
|
|
||||||
@Column({ nullable: true })
|
|
||||||
horario: string;
|
horario: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, Res } from '@nestjs/common';
|
||||||
|
import { Response } from 'express';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
|
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
@@ -37,8 +38,29 @@ export class EventosController {
|
|||||||
return this.eventoService.deleteEventoParticipante(id)
|
return this.eventoService.deleteEventoParticipante(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id/participantes')
|
@Get(':id/cupos')
|
||||||
async getCupos(@Param('id', ParseIntPipe)id: number){
|
async getCupos(@Param('id', ParseIntPipe)id: number){
|
||||||
return this.eventoService.getCupos(id)
|
return this.eventoService.getCupos(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get(':id/participante')
|
||||||
|
async getParticipnates(@Param('id', ParseIntPipe)id:number){
|
||||||
|
return this.eventoService.getParticipantes(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
@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()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
|
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
|
||||||
|
import { Participante } from 'src/participante/participante.entity';
|
||||||
import { Evento } from './evento.entity';
|
import { Evento } from './evento.entity';
|
||||||
import { EventosController } from './eventos.controller';
|
import { EventosController } from './eventos.controller';
|
||||||
import { EventosService } from './eventos.service';
|
import { EventosService } from './eventos.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports:[TypeOrmModule.forFeature([Evento, EventoParticipante])],
|
imports:[TypeOrmModule.forFeature([Evento, EventoParticipante, Participante])],
|
||||||
controllers:[EventosController],
|
controllers:[EventosController],
|
||||||
providers:[EventosService]
|
providers:[EventosService]
|
||||||
})
|
})
|
||||||
|
|||||||
+131
-10
@@ -2,10 +2,12 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
|
import { EventoParticipante } from 'src/evento-participante/evento-participante/eventoParticipante.entity';
|
||||||
import { Participante } from 'src/participante/participante.entity';
|
import { Participante } from 'src/participante/participante.entity';
|
||||||
import { Repository } from 'typeorm';
|
import { Between, MoreThanOrEqual, Repository } from 'typeorm';
|
||||||
import { actualizarEventoDto } from './dto/actualizarEvento.dto';
|
import { actualizarEventoDto } from './dto/actualizarEvento.dto';
|
||||||
import { crearEventoDto } from './dto/crearEvento.dto';
|
import { crearEventoDto } from './dto/crearEvento.dto';
|
||||||
import { Evento } from './evento.entity';
|
import { Evento } from './evento.entity';
|
||||||
|
import * as ExcelJS from 'exceljs';
|
||||||
|
import { Response } from 'express';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EventosService {
|
export class EventosService {
|
||||||
@@ -13,6 +15,8 @@ export class EventosService {
|
|||||||
@InjectRepository(Evento) private eventoRepository: Repository<Evento>,
|
@InjectRepository(Evento) private eventoRepository: Repository<Evento>,
|
||||||
@InjectRepository(EventoParticipante)
|
@InjectRepository(EventoParticipante)
|
||||||
private eventoParticipanteRepository: Repository<EventoParticipante>,
|
private eventoParticipanteRepository: Repository<EventoParticipante>,
|
||||||
|
@InjectRepository(Participante)
|
||||||
|
private participanteRepository: Repository<Participante>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
getEventos() {
|
getEventos() {
|
||||||
@@ -61,16 +65,133 @@ export class EventosService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCupos(id: number){
|
async getCupos(id: number) {
|
||||||
const evento = this.getEventosPorId(id)
|
const evento = this.getEventosPorId(id);
|
||||||
if(!evento) throw new Error(`El evento con id:${id} no existe`)
|
if (!evento) throw new Error(`El evento con id:${id} no existe`);
|
||||||
const registrados = await this.eventoParticipanteRepository
|
const registrados = await this.eventoParticipanteRepository
|
||||||
.createQueryBuilder('ep')
|
.createQueryBuilder('ep')
|
||||||
.select('COUNT(ep.id_evento)', 'count')
|
.select('COUNT(ep.id_evento)', 'count')
|
||||||
.where('ep.id_evento = :eventoId', { eventoId: (await evento).id_evento })
|
.where('ep.id_evento = :eventoId', { eventoId: (await evento).id_evento })
|
||||||
.getRawOne();
|
.getRawOne();
|
||||||
const cupoOriginal = (await evento).cupo;
|
const cupoOriginal = (await evento).cupo;
|
||||||
const cupoDisponible = cupoOriginal - registrados.count;
|
const cupoDisponible = cupoOriginal - registrados.count;
|
||||||
return { registrados: registrados.count, cupoDisponible, cupoOriginal};
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export class InscripcionDscService {
|
|||||||
|
|
||||||
const qryEjemplo = `select platica from alumno_inscrito WHERE id_cuenta="${accountNumber}"`;
|
const qryEjemplo = `select platica from alumno_inscrito WHERE id_cuenta="${accountNumber}"`;
|
||||||
|
|
||||||
const [results] = await connection.query(qryEjemplo);
|
const [results] = await connection.query(userInformationQuery);
|
||||||
const resultsArray = JSON.parse(JSON.stringify(results));
|
const resultsArray = JSON.parse(JSON.stringify(results));
|
||||||
if (resultsArray.length === 0) return null;
|
if (resultsArray.length === 0) return null;
|
||||||
/* console.log('The solution is: ', resultsArray); */
|
/* console.log('The solution is: ', resultsArray); */
|
||||||
|
|||||||
+7
-1
@@ -1,9 +1,11 @@
|
|||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
|
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||||
|
import { join } from 'path';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
||||||
|
|
||||||
const config = new DocumentBuilder()
|
const config = new DocumentBuilder()
|
||||||
.addBearerAuth()
|
.addBearerAuth()
|
||||||
@@ -14,6 +16,10 @@ async function bootstrap() {
|
|||||||
const document = SwaggerModule.createDocument(app, config);
|
const document = SwaggerModule.createDocument(app, config);
|
||||||
SwaggerModule.setup('api', app, document);
|
SwaggerModule.setup('api', app, document);
|
||||||
|
|
||||||
|
app.useStaticAssets(join(__dirname, '..', 'public'), {
|
||||||
|
prefix: '/public/',
|
||||||
|
});
|
||||||
|
|
||||||
app.enableCors();
|
app.enableCors();
|
||||||
await app.listen(AppModule.port);
|
await app.listen(AppModule.port);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,26 +19,26 @@ export class Miembro {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id_miembro: number;
|
id_miembro: number;
|
||||||
|
|
||||||
@Column({ nullable: false, length: 50 })
|
@Column({ nullable: false, length: 40 })
|
||||||
nombre: string;
|
nombre: string;
|
||||||
|
|
||||||
@Column({ nullable: false, length: 50 })
|
@Column({ nullable: false, length: 30 })
|
||||||
apellido_paterno: string;
|
apellido_paterno: string;
|
||||||
|
|
||||||
@Column({ nullable: false, length: 50 })
|
@Column({ nullable: false, length: 30 })
|
||||||
apellido_materno: string;
|
apellido_materno: string;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({ nullable: false })
|
||||||
id_tipo_miembro: number;
|
id_tipo_miembro: number;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({length: 40, nullable: false })
|
||||||
@IsEmail()
|
@IsEmail()
|
||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({length: 180, nullable: false })
|
||||||
password: string;
|
password: string;
|
||||||
|
|
||||||
@Column({ length: 260, nullable:true})
|
@Column({ length: 200, nullable:true})
|
||||||
descripcion: string;
|
descripcion: string;
|
||||||
|
|
||||||
@Column({nullable: true})
|
@Column({nullable: true})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Controller, Get, UseGuards } from '@nestjs/common';
|
import { Controller, Delete, Get, Param, ParseIntPipe, UseGuards } from '@nestjs/common';
|
||||||
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
|
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
|
||||||
import { Miembro } from './entity/miembro.entity';
|
import { Miembro } from './entity/miembro.entity';
|
||||||
import { MiembroService } from './miembro.service';
|
import { MiembroService } from './miembro.service';
|
||||||
@@ -8,9 +8,18 @@ export class MiembroController {
|
|||||||
|
|
||||||
constructor(private readonly miembroService: MiembroService){}
|
constructor(private readonly miembroService: MiembroService){}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
|
||||||
@Get()
|
@Get()
|
||||||
getUsuarios(): Promise<Miembro[]>{
|
getUsuarios(): Promise<Miembro[]>{
|
||||||
return this.miembroService.getUsuarios()
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,4 +20,16 @@ export class MiembroService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMiembros(tipo: number){
|
||||||
|
return this.miembroRepository.find({
|
||||||
|
where:{
|
||||||
|
id_tipo_miembro: tipo
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteMiembro(id: number){
|
||||||
|
return this.miembroRepository.delete({id_miembro: id})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,34 +6,31 @@ export class Participante {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id_participante: number;
|
id_participante: number;
|
||||||
|
|
||||||
@Column({ type: String, nullable: false, length: 100 })
|
@Column({ type: String, nullable: false, length: 40 })
|
||||||
nombre: string;
|
nombre: string;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({ nullable: false, length: 30 })
|
||||||
apellido_paterno: string;
|
apellido_paterno: string;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({ nullable: false, length: 30 })
|
||||||
apellido_materno: string;
|
apellido_materno: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true, length: 12 })
|
||||||
telefono: string;
|
telefono: string;
|
||||||
|
|
||||||
@Column({ nullable: false })
|
@Column({ nullable: false, length: 40 })
|
||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
@Column({ nullable: true }) //
|
@Column({ nullable: true, length: 180}) //
|
||||||
password: string;
|
password: string;
|
||||||
|
|
||||||
@Column({ nullable: true }) //
|
@Column({length:20, nullable: true }) //
|
||||||
tipo: string;
|
tipo: string;
|
||||||
|
|
||||||
@Column({ nullable: true }) //
|
@Column({ nullable: true, length: 50})
|
||||||
estado: string;
|
|
||||||
|
|
||||||
@Column({ nullable: true })
|
|
||||||
institucion_procedencia: string;
|
institucion_procedencia: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true, length:50})
|
||||||
carrera: string;
|
carrera: string;
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
|
||||||
|
|
||||||
@Entity()
|
|
||||||
export class Usuario {
|
|
||||||
@PrimaryGeneratedColumn()
|
|
||||||
id_usuario: number;
|
|
||||||
|
|
||||||
@Column({ nullable: false })
|
|
||||||
nombre: string;
|
|
||||||
|
|
||||||
@Column({ nullable: false })
|
|
||||||
password: string;
|
|
||||||
|
|
||||||
@Column({nullable:false})
|
|
||||||
email:string
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { UsuarioService } from './usuario.service';
|
|
||||||
import { UsuarioController } from './usuarios.controller';
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
import { Usuario } from './usuario.entity';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports:[TypeOrmModule.forFeature([Usuario])],
|
|
||||||
providers: [UsuarioService],
|
|
||||||
controllers: [UsuarioController]
|
|
||||||
})
|
|
||||||
export class UsuarioModule {}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
|
||||||
import { Repository } from 'typeorm';
|
|
||||||
import { Usuario } from './usuario.entity';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class UsuarioService {
|
|
||||||
constructor(
|
|
||||||
@InjectRepository(Usuario) private usuarioRepository: Repository<Usuario>,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
getUsuarios(){
|
|
||||||
return this.usuarioRepository.find()
|
|
||||||
}
|
|
||||||
|
|
||||||
getUsuario(email: string) {
|
|
||||||
return this.usuarioRepository.findOne({
|
|
||||||
where: {
|
|
||||||
email,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Controller, Get, UseGuards } from '@nestjs/common';
|
|
||||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
|
||||||
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
|
|
||||||
import { Usuario } from './usuario.entity';
|
|
||||||
import { UsuarioService } from './usuario.service';
|
|
||||||
|
|
||||||
@ApiBearerAuth()
|
|
||||||
@Controller('usuarios')
|
|
||||||
export class UsuarioController {
|
|
||||||
|
|
||||||
constructor(private readonly usuarioService: UsuarioService){}
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
|
||||||
@Get()
|
|
||||||
getUsuarios(): Promise<Usuario[]>{
|
|
||||||
return this.usuarioService.getUsuarios()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user