diff --git a/notas_santi.txt b/notas_santi.txt new file mode 100644 index 0000000..eca430e --- /dev/null +++ b/notas_santi.txt @@ -0,0 +1,128 @@ +import { Module } from '@nestjs/common'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; +import { AdminModule } from './admin/admin.module'; +import {TypeOrmModule } from '@nestjs/typeorm' +import { PostsModule } from './posts/posts.module'; +import { TipoUserModule } from './tipo_user/tipo_user.module'; +import { EventoModule } from './evento/evento.module'; +import { ParticipanteModule } from './participante/participante.module'; +import { QrModule } from './qr/qr.module'; +import { AdministradorModule } from './administrador/administrador.module'; +import { AsistenciaModule } from './asistencia/asistencia.module'; +import { ParticipanteEventoModule } from './participante_evento/participante_evento.module'; + + +@Module({ + imports: [ + TypeOrmModule.forRoot({ + type: 'mysql', + host: 'localhost', + port: 3306, //3306 + username: 'root', + password: 'admin', //admin + database: 'nestdb', + entities: [__dirname + '/**/*.entity{.ts,.js}'], + synchronize: true, + //extra + retryAttempts: 10, // Intentos para reconectar + retryDelay: 3000, // Tiempo entre reintentos + }), + AdminModule, + PostsModule, + EventoModule, + TipoUserModule, + ParticipanteModule, + QrModule, + AdministradorModule, + AsistenciaModule, + ParticipanteEventoModule, + ], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} + +// + +{ + "name": "nestjs-mysql", + "version": "0.0.1", + "description": "", + "author": "", + "private": true, + "license": "UNLICENSED", + "scripts": { + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "start": "nest start", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json" + }, + "dependencies": { + "@nestjs/common": "^11.0.1", + "@nestjs/core": "^11.0.1", + "@nestjs/platform-express": "^11.0.1", + "@nestjs/swagger": "^11.1.0", + "@nestjs/typeorm": "^11.0.0", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.1", + "jsonwebtoken": "^9.0.2", + "mysql2": "^3.13.0", + "reflect-metadata": "^0.2.2", + "rxjs": "^7.8.1", + "swagger-ui-express": "^5.0.1", + "typeorm": "^0.3.21" + }, + "devDependencies": { + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "^9.18.0", + "@nestjs/cli": "^11.0.0", + "@nestjs/schematics": "^11.0.0", + "@nestjs/testing": "^11.0.1", + "@swc/cli": "^0.6.0", + "@swc/core": "^1.10.7", + "@types/express": "^5.0.0", + "@types/jest": "^29.5.14", + "@types/node": "^22.10.7", + "@types/supertest": "^6.0.2", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.2", + "globals": "^16.0.0", + "jest": "^29.7.0", + "prettier": "^3.4.2", + "source-map-support": "^0.5.21", + "supertest": "^7.0.0", + "ts-jest": "^29.2.5", + "ts-loader": "^9.5.2", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" + } +} diff --git a/src/administrador/administrador.controller.ts b/src/administrador/administrador.controller.ts new file mode 100644 index 0000000..f0b8cb0 --- /dev/null +++ b/src/administrador/administrador.controller.ts @@ -0,0 +1,57 @@ +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common'; +import { AdministradorService } from './administrador.service'; +import { Administrador } from './administrador.entity'; +import { CreateAdministradorDto } from './dto/create-administrador.dto'; +import { UpdateAdministradorDto } from './dto/update.administrador.dto'; +import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger'; + +@ApiTags('Administradores') // Agrupa los endpoints en Swagger +@Controller('administrador') +export class AdministradorController { + + constructor(private administradorService: AdministradorService) {} + + @Get() + @ApiOperation({ summary: 'Obtener todos los administradores' }) + @ApiResponse({ status: 200, description: 'Lista de administradores obtenida correctamente.' }) + getAdministradores(): Promise { + return this.administradorService.getAdministradores(); + } + + @Get(':id') + @ApiOperation({ summary: 'Obtener un administrador por ID' }) + @ApiParam({ name: 'id', description: 'ID del administrador', example: 1 }) + @ApiResponse({ status: 200, description: 'Administrador obtenido correctamente.' }) + @ApiResponse({ status: 404, description: 'Administrador no encontrado.' }) + getAdministrador(@Param('id', ParseIntPipe) id: number) { + return this.administradorService.getAdministrador(id) + } + + @Post() + @ApiOperation({ summary: 'Registrar un nuevo administrador' }) + @ApiBody({ + description: 'Datos del administrador a registrar', + schema: { + type: 'object', + properties: { + id_tipo_user: { type: 'integer', example: 1 } + } + } + }) + @ApiResponse({ status: 201, description: 'Administrador registrado exitosamente.' }) + @ApiResponse({ status: 400, description: 'Datos inválidos.' }) + createAdministrador(@Body() newAdministrador: CreateAdministradorDto) { + return this.administradorService.createAdministrador(newAdministrador) + } + + @Delete(':id') + deleteAdministrador(@Param('id', ParseIntPipe) id: number) { + return this.administradorService.deleteAdministrador(id) + } + + @Patch(':id') + updateAdministrador(@Param('id', ParseIntPipe) id: number, @Body() administrador: UpdateAdministradorDto) { + return this.administradorService.updateAdministrador(id, administrador) + } + +} diff --git a/src/administrador/administrador.entity.ts b/src/administrador/administrador.entity.ts new file mode 100644 index 0000000..483ba96 --- /dev/null +++ b/src/administrador/administrador.entity.ts @@ -0,0 +1,28 @@ +import { TipoUser } from "src/tipo_user/tipo_user.entity"; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class Administrador { + @PrimaryGeneratedColumn() + id_admnistrador: number + + /* + @ManyToOne(() => TipoUser, (tipoUser) => tipoUser.administradores) + @JoinColumn({ name: "id_tipo_user" }) + tipoUser: TipoUser; + */ + //Relacion con tipo_user + @Column() + id_tipo_user: number + + @ManyToOne(() => TipoUser, (tipoUser) => tipoUser.administrador) + tipoUser: TipoUser[] + + /* + @OneToMany(() => Evento, (evento) => evento.administrador) + eventos: Evento[]; + + @OneToMany(() => Asistencia, (asistencia) => asistencia.administrador) + asistencias: Asistencia[]; + */ +} \ No newline at end of file diff --git a/src/administrador/administrador.module.ts b/src/administrador/administrador.module.ts new file mode 100644 index 0000000..17ed104 --- /dev/null +++ b/src/administrador/administrador.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { AdministradorService } from './administrador.service'; +import { AdministradorController } from './administrador.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Administrador } from './administrador.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Administrador])], + controllers: [AdministradorController], + providers: [AdministradorService], + exports: [AdministradorService], +}) +export class AdministradorModule {} diff --git a/src/administrador/administrador.service.ts b/src/administrador/administrador.service.ts new file mode 100644 index 0000000..2dce554 --- /dev/null +++ b/src/administrador/administrador.service.ts @@ -0,0 +1,79 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Administrador } from './administrador.entity'; +import { Repository } from 'typeorm'; +import { CreateAdministradorDto } from './dto/create-administrador.dto'; +import { UpdateAdministradorDto } from './dto/update.administrador.dto'; + +@Injectable() +export class AdministradorService { + + constructor( + @InjectRepository(Administrador) private administradorRepository: Repository + ) {} + + async createAdministrador(administrador: CreateAdministradorDto) { + + //revisar el where + const administradorFound = await this.administradorRepository.findOne({ + where: { + id_admnistrador: administrador.id_tipo_user + } + }) + + if (administradorFound) { + return new HttpException('Administrador already exists', HttpStatus.CONFLICT) + } + + + //Falta regresar el return + //return this.administradorRepository.save(administradorFound) + } + + getAdministradores() { + return this.administradorRepository.find({ + relations: ['tipoUser'] + }) + } + + async getAdministrador(id_admnistrador: number) { + const administradorFound = await this.administradorRepository.findOne({ + where: { + id_admnistrador + }, + relations: ['tipoUser'] + }) + + if (!Administrador) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return administradorFound + } + + async deleteAdministrador(id_admnistrador: number) { + const result = await this.administradorRepository.delete({ id_admnistrador }) + + if (result.affected === 0) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return result + } + + async updateAdministrador(id_admnistrador: number, administrador: UpdateAdministradorDto) { + const administradorFound = await this.administradorRepository.findOne({ + where: { + id_admnistrador + } + }) + + if (!administradorFound) { + return new HttpException('User not found', HttpStatus.NOT_FOUND) + } + + const updateAdministrador = Object.assign(administradorFound, administrador) + return this.administradorRepository.save(updateAdministrador) + } + +} diff --git a/src/administrador/dto/create-administrador.dto.ts b/src/administrador/dto/create-administrador.dto.ts new file mode 100644 index 0000000..fedb2b3 --- /dev/null +++ b/src/administrador/dto/create-administrador.dto.ts @@ -0,0 +1,3 @@ +export class CreateAdministradorDto { + id_tipo_user: number +} \ No newline at end of file diff --git a/src/administrador/dto/update.administrador.dto.ts b/src/administrador/dto/update.administrador.dto.ts new file mode 100644 index 0000000..f1355f2 --- /dev/null +++ b/src/administrador/dto/update.administrador.dto.ts @@ -0,0 +1,3 @@ +export class UpdateAdministradorDto { + id_tipo_user?: number +} \ No newline at end of file diff --git a/src/asistencia/asistencia.controller.ts b/src/asistencia/asistencia.controller.ts new file mode 100644 index 0000000..1107ab8 --- /dev/null +++ b/src/asistencia/asistencia.controller.ts @@ -0,0 +1,37 @@ +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common'; +import { AsistenciaService } from './asistencia.service'; +import { Asistencia } from './asistencia.entity'; +import { CreateAsistenciaDto } from './dto/create-asistencia.dto'; +import { UpdateAsistenciaDto } from './dto/update.asistencia.dto'; + +@Controller('asistencia') +export class AsistenciaController { + + constructor(private asistenciaService: AsistenciaService) {} + + @Get() + getAsistencias(): Promise { + return this.asistenciaService.getAsistencias() + } + + @Get(':id') + getAsistencia(@Param('id', ParseIntPipe) id: number) { + return this.asistenciaService.getAsistencia(id) + } + + @Post() + createAsistencia(@Body() newAsistencia: CreateAsistenciaDto) { + return this.asistenciaService.createAsistencia(newAsistencia) + } + + @Delete() + deleteAsistencia(@Param('id', ParseIntPipe) id: number) { + return this.asistenciaService.deleteAsistencia(id) + } + + @Patch(':id') + updateAsistencia(@Param('id', ParseIntPipe) id: number, @Body() asistencia: UpdateAsistenciaDto) { + return this.asistenciaService.updateAsistencia(id, asistencia) + } + +} diff --git a/src/asistencia/asistencia.entity.ts b/src/asistencia/asistencia.entity.ts new file mode 100644 index 0000000..83c5dc5 --- /dev/null +++ b/src/asistencia/asistencia.entity.ts @@ -0,0 +1,41 @@ +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class Asistencia { + @PrimaryGeneratedColumn() + id_asistecia: number + + //({type: 'datetime', default: () => 'CURRENT_TIMESTAMP' } + @Column({type: 'datetime', default: () => 'CURRENT_TIMESTAMP'}) + fecha_asistencia: Date + + @Column() + metodo: boolean + + @Column() + estado: boolean + + //relaciones con las otras tablas + @Column() + id_participante: number + + @Column() + id_evento: number + + @Column() + id_administrador: number + + /* + @ManyToOne(() => Administrador, (admin) => admin.asistencias) + @JoinColumn({ name: "id_administrador" }) + administrador: Administrador; + + @ManyToOne(() => Evento, (evento) => evento.asistencias) + @JoinColumn({ name: "id_evento" }) + evento: Evento; + + @ManyToOne(() => Participante, (participante) => participante.asistencias) + @JoinColumn({ name: "id_participante" }) + participante: Participante; + */ +} \ No newline at end of file diff --git a/src/asistencia/asistencia.module.ts b/src/asistencia/asistencia.module.ts new file mode 100644 index 0000000..f16c339 --- /dev/null +++ b/src/asistencia/asistencia.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { AsistenciaService } from './asistencia.service'; +import { AsistenciaController } from './asistencia.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Asistencia } from './asistencia.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Asistencia])], + controllers: [AsistenciaController], + providers: [AsistenciaService] +}) +export class AsistenciaModule {} diff --git a/src/asistencia/asistencia.service.ts b/src/asistencia/asistencia.service.ts new file mode 100644 index 0000000..1732a79 --- /dev/null +++ b/src/asistencia/asistencia.service.ts @@ -0,0 +1,77 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Asistencia } from './asistencia.entity'; +import { Repository } from 'typeorm'; +import { CreateAsistenciaDto } from './dto/create-asistencia.dto'; +import { UpdateAsistenciaDto } from './dto/update.asistencia.dto'; + +@Injectable() +export class AsistenciaService { + + constructor( + @InjectRepository(Asistencia) private asistenciaRepository: Repository + ) {} + + async createAsistencia(asistencia: CreateAsistenciaDto) { + + const asistenciaFound = await this.asistenciaRepository.findOne({ + where: { + fecha_asistencia: asistencia.fecha_asistencia, + metodo: asistencia.metodo, + estado: asistencia.estdao + } + }) + + if (asistenciaFound) { + return new HttpException('User already exists', HttpStatus.CONFLICT) + } + + return this.asistenciaRepository.save(asistencia) + } + + getAsistencias() { + return this.asistenciaRepository.find({}) + } + + async getAsistencia(id_asistecia: number) { + const asistenciaFound = await this.asistenciaRepository.findOne({ + where: { + id_asistecia + } + }) + + if (!asistenciaFound) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return asistenciaFound + } + + async deleteAsistencia(id_asistecia: number) { + const result = await this.asistenciaRepository.delete({ id_asistecia }) + + if (result.affected === 0) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return result + } + + + async updateAsistencia(id_asistecia: number, asistencia: UpdateAsistenciaDto) { + const asistenciaFound = await this.asistenciaRepository.findOne({ + where: { + id_asistecia + } + }) + + if (!asistenciaFound) { + return new HttpException('User not found', HttpStatus.NOT_FOUND) + } + + const updateAsistencia = Object.assign(asistenciaFound, asistencia) + return this.asistenciaRepository.save(updateAsistencia) + } + + +} diff --git a/src/asistencia/dto/create-asistencia.dto.ts b/src/asistencia/dto/create-asistencia.dto.ts new file mode 100644 index 0000000..e3da47e --- /dev/null +++ b/src/asistencia/dto/create-asistencia.dto.ts @@ -0,0 +1,5 @@ +export class CreateAsistenciaDto { + fecha_asistencia: Date + metodo: boolean + estdao: boolean +} \ No newline at end of file diff --git a/src/asistencia/dto/update.asistencia.dto.ts b/src/asistencia/dto/update.asistencia.dto.ts new file mode 100644 index 0000000..23588e4 --- /dev/null +++ b/src/asistencia/dto/update.asistencia.dto.ts @@ -0,0 +1,5 @@ +export class UpdateAsistenciaDto { + fecha_asistencia?: Date + metodo?: boolean + estado?: boolean +} \ No newline at end of file diff --git a/src/docs/docs.module.ts b/src/docs/docs.module.ts new file mode 100644 index 0000000..90d1820 --- /dev/null +++ b/src/docs/docs.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { SwaggerModule } from '@nestjs/swagger'; +import { swaggerConfig } from './swagger.config'; +import { INestApplication } from '@nestjs/common'; + +@Module({}) +export class DocsModule { + static setupSwagger(app: INestApplication) { + const document = SwaggerModule.createDocument(app, swaggerConfig); + SwaggerModule.setup('api-docs', app, document); + } +} diff --git a/src/docs/swagger.config.ts b/src/docs/swagger.config.ts new file mode 100644 index 0000000..e0e99a1 --- /dev/null +++ b/src/docs/swagger.config.ts @@ -0,0 +1,11 @@ +import { DocumentBuilder } from '@nestjs/swagger'; + +export const swaggerConfig = new DocumentBuilder() + .setTitle('Sistema de Registro de Usuarios y Eventos') + .setDescription('API para gestionar usuarios, eventos, asistencia y códigos QR') + .setVersion('1.0') + .addTag('Usuarios') + .addTag('Eventos') + .addTag('Asistencia') + .addTag('QR') + .build(); diff --git a/src/evento/dto/create-evento.dto.ts b/src/evento/dto/create-evento.dto.ts new file mode 100644 index 0000000..5fa9fd6 --- /dev/null +++ b/src/evento/dto/create-evento.dto.ts @@ -0,0 +1,11 @@ +export class CreateEventoDto { + tipo_evento: string; + + nombre_evento: string; + + fecha_inicio: Date; + + fecha_fin: Date; + + //agregar el id del administrador +} \ No newline at end of file diff --git a/src/evento/dto/update.evento.dto.ts b/src/evento/dto/update.evento.dto.ts new file mode 100644 index 0000000..f85579b --- /dev/null +++ b/src/evento/dto/update.evento.dto.ts @@ -0,0 +1,6 @@ +export class UpdateEventoDto { + tipo_evento?: string + nombre_evento: string + fecha_inicio?: Date + fecha_fin?: Date +} \ No newline at end of file diff --git a/src/evento/evento.controller.ts b/src/evento/evento.controller.ts new file mode 100644 index 0000000..0586840 --- /dev/null +++ b/src/evento/evento.controller.ts @@ -0,0 +1,37 @@ +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common'; +import { EventoService } from './evento.service'; +import { Evento } from './evento.entity'; +import { CreateEventoDto } from './dto/create-evento.dto'; +import { UpdateEventoDto } from './dto/update.evento.dto'; + +@Controller('evento') +export class EventoController { + constructor(private eventoService: EventoService) {} + + @Get() + getEventos(): Promise { + return this.eventoService.getEventos() + } + + @Get(':id') + getEvento(@Param('id', ParseIntPipe) id: number) { + return this.eventoService.getEvento(id) + } + + @Post() + createEvento(@Body() newEvento: CreateEventoDto) { + return this.eventoService.createEvento(newEvento) + } + + @Delete(':id') + deleteEvento(@Param('id', ParseIntPipe) id: number) { + return this.eventoService.deleteEvento(id) + } + //@Param(':id', ParseIntPipe) id: number, @Body() tipoUser: UpdateTipoUserDto + @Patch() + updateEvento(@Param(':id', ParseIntPipe) id: number, @Body() evento: UpdateEventoDto) { + return this.eventoService.updateEvento(id, evento) + } + + +} diff --git a/src/evento/evento.entity.ts b/src/evento/evento.entity.ts new file mode 100644 index 0000000..90e04a1 --- /dev/null +++ b/src/evento/evento.entity.ts @@ -0,0 +1,38 @@ +import { ParticipanteEvento } from "src/participante_evento/participante_evento.entity"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class Evento { + @PrimaryGeneratedColumn() + id_evento: number + + @Column() + tipo_evento: string + + @Column() + nombre_evento: string + + @Column({type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + fecha_inicio: Date + + @Column({type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + fecha_fin: Date + + /* falta hacer la relacion + @Column() + id_administrador: number + + @ManyToOne(() => Administrador, (admin) => admin.eventos) + @JoinColumn({ name: "id_administrador" }) + administrador: Administrador; + + @OneToMany(() => ParticipanteEvento, (pe) => pe.evento) + participantes: ParticipanteEvento[]; + + @OneToMany(() => Asistencia, (asistencia) => asistencia.evento) + asistencias: Asistencia[]; + */ + + @OneToMany(() => ParticipanteEvento, (participanteEvento) => participanteEvento.evento) + participantes: ParticipanteEvento[]; +} \ No newline at end of file diff --git a/src/evento/evento.module.ts b/src/evento/evento.module.ts new file mode 100644 index 0000000..5c3605e --- /dev/null +++ b/src/evento/evento.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { EventoService } from './evento.service'; +import { EventoController } from './evento.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Evento } from './evento.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Evento])], + controllers: [EventoController], + providers: [EventoService] +}) +export class EventoModule {} diff --git a/src/evento/evento.service.ts b/src/evento/evento.service.ts new file mode 100644 index 0000000..eaf5d9f --- /dev/null +++ b/src/evento/evento.service.ts @@ -0,0 +1,73 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { Evento } from './evento.entity'; +import { CreateEventoDto } from './dto/create-evento.dto'; +import { UpdateEventoDto } from './dto/update.evento.dto'; + +@Injectable() +export class EventoService { + constructor( + @InjectRepository(Evento) private eventoRepository: Repository, + ) {} + + async createEvento(evento: CreateEventoDto) { + const eventoFound = await this.eventoRepository.findOne({ + where: { + nombre_evento: evento.nombre_evento, + tipo_evento: evento.tipo_evento + } + }) + + if (eventoFound) + return new HttpException('Evento already exists', HttpStatus.CONFLICT) + + const createEvento = this.eventoRepository.create(evento) + + return this.eventoRepository.save(createEvento) + } + + getEventos() { + return this.eventoRepository.find({ + relations: ['participantes'] + }) + } + + async getEvento(id_evento: number) { + const eventoFound = await this.eventoRepository.findOne({ + where: { + id_evento + }, + relations: ['participantes'] + }) + + if (!eventoFound) + return new HttpException('Evento not found', HttpStatus.NOT_FOUND); + + return eventoFound + } + + async deleteEvento(id_evento: number) { + const result = await this.eventoRepository.delete({ id_evento }) + + if (result.affected === 0) { + return new HttpException('Evento not found', HttpStatus.NOT_FOUND); + } + + return result + } + + async updateEvento(id_evento: number, evento: UpdateEventoDto) { + const eventoFound = await this.eventoRepository.findOne({ + where: { + id_evento + } + }) + + if (!eventoFound) + return new HttpException('Evento not found', HttpStatus.NOT_FOUND) + + const updateEvento = Object.assign(eventoFound, evento) + return this.eventoRepository.save(updateEvento) + } +} diff --git a/src/participante/dto/create-participante.dto.ts b/src/participante/dto/create-participante.dto.ts new file mode 100644 index 0000000..3aae94f --- /dev/null +++ b/src/participante/dto/create-participante.dto.ts @@ -0,0 +1,7 @@ +import { IsEmail } from "class-validator"; + +export class CreateParticipanteDto { + @IsEmail() + correo: string + id_tipo_user: number +} \ No newline at end of file diff --git a/src/participante/dto/update.participante.dto.ts b/src/participante/dto/update.participante.dto.ts new file mode 100644 index 0000000..9cc03ba --- /dev/null +++ b/src/participante/dto/update.participante.dto.ts @@ -0,0 +1,3 @@ +export class UpdateParticipanteDto { + correo: string +} \ No newline at end of file diff --git a/src/participante/participante.controller.ts b/src/participante/participante.controller.ts new file mode 100644 index 0000000..f688879 --- /dev/null +++ b/src/participante/participante.controller.ts @@ -0,0 +1,60 @@ +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common'; +import { Participante } from './participante.entity'; +import { ParticipanteService } from './participante.service'; +import { CreateParticipanteDto } from './dto/create-participante.dto'; +import { UpdateParticipanteDto } from './dto/update.participante.dto'; +import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger'; + +@ApiTags('Participantes') // Agrupa los endpoints en Swagger +@Controller('participante') +export class ParticipanteController { + constructor(private participanteService: ParticipanteService) {} + + @ApiOperation({ summary: 'Obtener todos los participantes' }) + @ApiResponse({ status: 200, description: 'Lista de participantes obtenida correctamente.' }) + @Get() + getParticipantes(): Promise { + return this.participanteService.getParticipantes() + } + + @Get(':id') + @ApiOperation({ summary: 'Obtener un participante por ID' }) + @ApiParam({ name: 'id', description: 'ID del participante', example: 1 }) + @ApiResponse({ status: 200, description: 'Participante obtenido correctamente.' }) + @ApiResponse({ status: 404, description: 'Participante no encontrado.' }) + getParticipante(@Param('id', ParseIntPipe) id: number) { + return this.participanteService.getParticipante(id); + } + + @Post() + @ApiOperation({ summary: 'Registrar un nuevo participante' }) + @ApiBody({ + description: 'Datos del participante a registrar', + schema: { + type: 'object', + properties: { + correo: { type: 'string', example: 'user@example.com' }, + id_tipo_user: { type: 'integer', example: 2 } + } + } + }) + @ApiResponse({ status: 201, description: 'Participante registrado exitosamente.' }) + @ApiResponse({ status: 400, description: 'Datos inválidos.' }) + createParticipante(@Body() newParticipante: CreateParticipanteDto) { + return this.participanteService.createParticipante(newParticipante); + } + + @Delete(':id') + deleteParticipante(@Param('id', ParseIntPipe) id: number) { + return this.participanteService.deleteParticipante(id) + } + + + @Patch(':id') + updateParticipante(@Param('correo') id: number, @Body() participante: UpdateParticipanteDto) { + return this.participanteService.updateParticipante(id, participante); + } + + + +} diff --git a/src/participante/participante.entity.ts b/src/participante/participante.entity.ts new file mode 100644 index 0000000..1bd1fd0 --- /dev/null +++ b/src/participante/participante.entity.ts @@ -0,0 +1,34 @@ +import { ParticipanteEvento } from "src/participante_evento/participante_evento.entity"; +import { TipoUser } from "src/tipo_user/tipo_user.entity"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class Participante { + @PrimaryGeneratedColumn() + id_participante: number + + @Column() + correo: string + + @Column() + id_tipo_user: number + + //Relacion con tipo usuario + @ManyToOne(() => TipoUser, tipoUser => tipoUser.participante) + @JoinColumn({ name: 'participante_id' }) //nombre de la relacion + tipo_user: TipoUser[] + + /* + @ManyToOne(() => Administrador, (admin) => admin.eventos) + @JoinColumn({ name: "id_administrador" }) + administrador: Administrador; + + @OneToMany(() => ParticipanteEvento, (pe) => pe.evento) + participantes: ParticipanteEvento[]; + + @OneToMany(() => Asistencia, (asistencia) => asistencia.evento) + asistencias: Asistencia[]; + */ + + +} \ No newline at end of file diff --git a/src/participante/participante.module.ts b/src/participante/participante.module.ts new file mode 100644 index 0000000..912cd0c --- /dev/null +++ b/src/participante/participante.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { ParticipanteService } from './participante.service'; +import { ParticipanteController } from './participante.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Participante } from './participante.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Participante])], + controllers: [ParticipanteController], + providers: [ParticipanteService], + exports: [ParticipanteService], +}) +export class ParticipanteModule {} diff --git a/src/participante/participante.service.ts b/src/participante/participante.service.ts new file mode 100644 index 0000000..9eed97e --- /dev/null +++ b/src/participante/participante.service.ts @@ -0,0 +1,74 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Participante } from './participante.entity'; +import { Repository } from 'typeorm'; +import { CreateParticipanteDto } from './dto/create-participante.dto'; +import { UpdateAdminDto } from 'src/admin/dto/update.admin.dto'; +import { UpdateParticipanteDto } from './dto/update.participante.dto'; + +@Injectable() +export class ParticipanteService { + + constructor( + @InjectRepository(Participante) private participanteRepository: Repository + ) {} + + async createParticipante(participante: CreateParticipanteDto) { + const participanteFound = await this.participanteRepository.findOne({ + where: { + correo: participante.correo + } + }) + + if (participanteFound) + return new HttpException('Participante already exists', HttpStatus.CONFLICT) + + return this.participanteRepository.save(participante) + } + + getParticipantes() { + return this.participanteRepository.find({ + relations: ['tipo_user'] + }) + } + + async getParticipante(id_participante: number) { + const participanteFound = await this.participanteRepository.findOne({ + where: { + id_participante + }, + relations: ['tipo_user'] + }) + + if (!participanteFound) + return new HttpException('Participante not found', HttpStatus.NOT_FOUND); + + return participanteFound; + } + + async deleteParticipante(id_participante: number) { + const result = await this.participanteRepository.delete({ id_participante }) + + if (result.affected === 0) { + return new HttpException('Participante not found', HttpStatus.NOT_FOUND); + } + + return result; + } + + async updateParticipante(id_participante: number, participante: UpdateParticipanteDto) { + const participanteFound = await this.participanteRepository.findOne({ + where: { + id_participante + } + }); + + if (!participanteFound) { + return new HttpException('Participante not found', HttpStatus.NOT_FOUND) + } + + const updateParticipante = Object.assign(participanteFound, participante) + return this.participanteRepository.save(updateParticipante) + } + +} diff --git a/src/participante_evento/dto/create-participante_evento.dto.ts b/src/participante_evento/dto/create-participante_evento.dto.ts new file mode 100644 index 0000000..44b8994 --- /dev/null +++ b/src/participante_evento/dto/create-participante_evento.dto.ts @@ -0,0 +1,5 @@ +export class CreateParticipanteEventoDto { + id_participante: number + + id_evento: number +} \ No newline at end of file diff --git a/src/participante_evento/dto/update.participante_evento.dto.ts b/src/participante_evento/dto/update.participante_evento.dto.ts new file mode 100644 index 0000000..020e021 --- /dev/null +++ b/src/participante_evento/dto/update.participante_evento.dto.ts @@ -0,0 +1,6 @@ +export class UpdateParticipanteEventoDto { + id_participante?: number + id_evento?: number + fecha_inscripcion?: Date + estatus?: boolean +} \ No newline at end of file diff --git a/src/participante_evento/participante_evento.controller.ts b/src/participante_evento/participante_evento.controller.ts new file mode 100644 index 0000000..9d128e8 --- /dev/null +++ b/src/participante_evento/participante_evento.controller.ts @@ -0,0 +1,36 @@ +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common'; +import { ParticipanteEventoService } from './participante_evento.service'; +import { ParticipanteEvento } from './participante_evento.entity'; +import { CreateParticipanteEventoDto } from './dto/create-participante_evento.dto'; +import { UpdateParticipanteEventoDto } from './dto/update.participante_evento.dto'; + +@Controller('participante-evento') +export class ParticipanteEventoController { + + constructor(private participanteEventoService: ParticipanteEventoService) {} + + @Get() + getParticipantesEvento(): Promise { + return this.participanteEventoService.getParticipantesEvento() + } + + @Get(':id') + getParticipanteEvento(@Param('id', ParseIntPipe) id: number) { + return this.participanteEventoService.getParticipanteEvento(id) + } + + @Post() + createParticipanteEvento(@Body() newParticipanteEvento: CreateParticipanteEventoDto) { + return this.participanteEventoService.createParticipanteEvento(newParticipanteEvento) + } + + @Delete(':id') + deleteParticipanteEvento(@Param('id', ParseIntPipe) id: number) { + return this.participanteEventoService.deleteParticipanteEvento(id) + } + + @Patch(':id') + updateParticipanteEvento(@Param('id', ParseIntPipe) id_participante: number, id_evento: number, @Body() participanteEvento: UpdateParticipanteEventoDto) { + return this.participanteEventoService.updateParticipanteEvento(id_participante, id_evento, participanteEvento) + } +} diff --git a/src/participante_evento/participante_evento.entity.ts b/src/participante_evento/participante_evento.entity.ts new file mode 100644 index 0000000..4e2b206 --- /dev/null +++ b/src/participante_evento/participante_evento.entity.ts @@ -0,0 +1,33 @@ +import { Evento } from "src/evento/evento.entity"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class ParticipanteEvento { + @PrimaryColumn() + id_participante: number + @PrimaryColumn() + id_evento: number + + @Column() + fecha_inscripcion: Date + + @Column() + estatus: boolean + + /* + @OneToOne(() => Qr, (qr) => qr.participanteEvento) + qr: Qr; + + @ManyToOne(() => Participante, (participante) => participante.eventos) + @JoinColumn({ name: "id_participante" }) + participante: Participante; + + @ManyToOne(() => Evento, (evento) => evento.participantes) + @JoinColumn({ name: "id_evento" }) + evento: Evento; + */ + + @ManyToOne(() => Evento, (evento) => evento.participantes) + @JoinColumn({ name: "id_evento" }) + evento: Evento; +} \ No newline at end of file diff --git a/src/participante_evento/participante_evento.module.ts b/src/participante_evento/participante_evento.module.ts new file mode 100644 index 0000000..6febf0a --- /dev/null +++ b/src/participante_evento/participante_evento.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { ParticipanteEventoService } from './participante_evento.service'; +import { ParticipanteEventoController } from './participante_evento.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { ParticipanteEvento } from './participante_evento.entity'; +import { Evento } from 'src/evento/evento.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([ParticipanteEvento]), Evento], + controllers: [ParticipanteEventoController], + providers: [ParticipanteEventoService] +}) +export class ParticipanteEventoModule {} diff --git a/src/participante_evento/participante_evento.service.ts b/src/participante_evento/participante_evento.service.ts new file mode 100644 index 0000000..b0a6b93 --- /dev/null +++ b/src/participante_evento/participante_evento.service.ts @@ -0,0 +1,77 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ParticipanteEvento } from './participante_evento.entity'; +import { Repository } from 'typeorm'; +import { CreateParticipanteEventoDto } from './dto/create-participante_evento.dto'; +import { UpdateParticipanteEventoDto } from './dto/update.participante_evento.dto'; + +@Injectable() +export class ParticipanteEventoService { + + constructor( + @InjectRepository(ParticipanteEvento) private participanteEventoRepository: Repository + ) {} + + async createParticipanteEvento(participanteEvento: CreateParticipanteEventoDto) { + + const participante_eventoFound = await this.participanteEventoRepository.findOne({ + where: { + id_participante: participanteEvento.id_participante, + id_evento: participanteEvento.id_evento + } + }) + + if (participante_eventoFound) { + return new HttpException('Participante already exists in this event', HttpStatus.CONFLICT) + } + + return this.participanteEventoRepository.save(participanteEvento) + } + + getParticipantesEvento() { + return this.participanteEventoRepository.find({ + relations: ['evento'] + }) + } + + async getParticipanteEvento(id_participante: number) { + const participante_eventoFound = await this.participanteEventoRepository.findOne({ + where: { + id_participante + }, + relations: ['evento'] + }) + + if (!participante_eventoFound) { + return new HttpException('Participante not found', HttpStatus.NOT_FOUND); + } + + return participante_eventoFound + } + + async deleteParticipanteEvento(id_participante: number) { + const result = await this.participanteEventoRepository.delete({ id_participante }) + + if (result.affected === 0) { + return new HttpException('Participante not found', HttpStatus.NOT_FOUND); + } + + return result + } + + async updateParticipanteEvento(id_participante: number, id_evento: number, participante_evento: UpdateParticipanteEventoDto) { + const participante_eventoFound = await this.participanteEventoRepository.findOne({ + where: { + id_participante, + id_evento + } + }) + + if (!participante_eventoFound) { + return new HttpException('Participante not found', HttpStatus.NOT_FOUND) + } + + return this.participanteEventoRepository.save(participante_evento) + } + +} diff --git a/src/qr/dto/create-qr.dto.ts b/src/qr/dto/create-qr.dto.ts new file mode 100644 index 0000000..b2fac5a --- /dev/null +++ b/src/qr/dto/create-qr.dto.ts @@ -0,0 +1,6 @@ +export class CreateQrDto { + id_participante_evento: number + fecha_creacion: Date + decha_vencimiento: Date + activo: boolean +} \ No newline at end of file diff --git a/src/qr/dto/update.qr.dto.ts b/src/qr/dto/update.qr.dto.ts new file mode 100644 index 0000000..6f59cf1 --- /dev/null +++ b/src/qr/dto/update.qr.dto.ts @@ -0,0 +1,5 @@ +export class UpdateQrDto { + fecha_creacion?: Date + fecha_vencimiento: Date + activo?: boolean +} \ No newline at end of file diff --git a/src/qr/qr.controller.ts b/src/qr/qr.controller.ts new file mode 100644 index 0000000..e09a48e --- /dev/null +++ b/src/qr/qr.controller.ts @@ -0,0 +1,36 @@ +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common'; +import { QrService } from './qr.service'; +import { Qr } from './qr.entity'; +import { CreateQrDto } from './dto/create-qr.dto'; +import { UpdateQrDto } from './dto/update.qr.dto'; + +@Controller('qr') +export class QrController { + + constructor(private qrService: QrService) {} + + @Get() + getQrs(): Promise { + return this.qrService.getQrs(); + } + + @Get(':id') + getQr(@Param('id', ParseIntPipe) id: number) { + return this.qrService.getQr(id); + } + + @Post() //en el body ValidationPipe + createQr(@Body() newQr: CreateQrDto) { + return this.qrService.createQr(newQr) + } + + @Delete(':id') + deleteQr(@Param('id', ParseIntPipe) id:number) { + return this.qrService.deleteQr(id); + } + + @Patch(':id') + updateQr(@Param('id', ParseIntPipe) id: number, @Body() qr: UpdateQrDto) { + return this.qrService.updateQr(id, qr) + } +} diff --git a/src/qr/qr.entity.ts b/src/qr/qr.entity.ts new file mode 100644 index 0000000..9d6b3ac --- /dev/null +++ b/src/qr/qr.entity.ts @@ -0,0 +1,25 @@ +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class Qr { + @PrimaryGeneratedColumn() + id_qr: number + + /* + @OneToOne(() => ParticipanteEvento, (pe) => pe.qr) + @JoinColumn({ name: "id_participante_evento" }) + participanteEvento: ParticipanteEvento; + */ + + @Column({type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + fecha_creacion: Date + + @Column({type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + fecha_vencimiento: Date + + @Column() + activo: boolean + + //Relacion con id_participante_evento + +} \ No newline at end of file diff --git a/src/qr/qr.module.ts b/src/qr/qr.module.ts new file mode 100644 index 0000000..1a6040e --- /dev/null +++ b/src/qr/qr.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { QrService } from './qr.service'; +import { QrController } from './qr.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Qr } from './qr.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Qr])], + controllers: [QrController], + providers: [QrService] +}) +export class QrModule {} diff --git a/src/qr/qr.service.ts b/src/qr/qr.service.ts new file mode 100644 index 0000000..65af8d2 --- /dev/null +++ b/src/qr/qr.service.ts @@ -0,0 +1,73 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { Qr } from './qr.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { CreateQrDto } from './dto/create-qr.dto'; +import { UpdateQrDto } from './dto/update.qr.dto'; + +@Injectable() +export class QrService { + + constructor( + @InjectRepository(Qr) private qrRepository: Repository + ) {} + + async createQr(qr: CreateQrDto) { + const qrFound = await this.qrRepository.findOne({ + where: { + id_qr: qr.id_participante_evento + } + }) + + if (qrFound) { + return new HttpException('Qr already exists', HttpStatus.CONFLICT) + } + + return this.qrRepository.save(qr) + } + + getQrs() { + return this.qrRepository.find({}) + } + + async getQr(id_qr) { + const qrFound = await this.qrRepository.findOne({ + where: { + id_qr + } + }) + + if (!qrFound) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return qrFound + } + + async deleteQr(id_qr: number) { + const result = await this.qrRepository.delete({ id_qr }) + + if (result.affected === 0) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return result + } + + async updateQr(id_qr: number, qr: UpdateQrDto) { + const qrFound = await this.qrRepository.findOne({ + where: { + id_qr + } + }) + + if (!qrFound) { + return new HttpException('User not found', HttpStatus.NOT_FOUND) + } + + const updateQr = Object.assign(qrFound, qr) + return this.qrRepository.save(updateQr) + } + + +} diff --git a/src/tipo_user/dto/create-tipo-user.dto.ts b/src/tipo_user/dto/create-tipo-user.dto.ts new file mode 100644 index 0000000..4ab9314 --- /dev/null +++ b/src/tipo_user/dto/create-tipo-user.dto.ts @@ -0,0 +1,7 @@ +export class CreateTipoUserDto { + tipo: string + nombre: string + apellido_p: string + apellido_m: string + correo?: string +} \ No newline at end of file diff --git a/src/tipo_user/dto/update.tipo_user.dto.ts b/src/tipo_user/dto/update.tipo_user.dto.ts new file mode 100644 index 0000000..26dbfac --- /dev/null +++ b/src/tipo_user/dto/update.tipo_user.dto.ts @@ -0,0 +1,6 @@ +export class UpdateTipoUserDto { + tipo?: string + nombre?: string + apellido_p?: string + apellido_m: string +} \ No newline at end of file diff --git a/src/tipo_user/tipo_user.controller.ts b/src/tipo_user/tipo_user.controller.ts new file mode 100644 index 0000000..abed59a --- /dev/null +++ b/src/tipo_user/tipo_user.controller.ts @@ -0,0 +1,63 @@ +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common'; +import { TipoUserService } from './tipo_user.service'; +import { TipoUser } from './tipo_user.entity'; +import { CreateTipoUserDto } from './dto/create-tipo-user.dto'; +import { UpdateTipoUserDto } from './dto/update.tipo_user.dto'; +import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger'; + +@ApiTags('Tipo de Usuario') // Agrupa los endpoints en Swagger +@Controller('tipo-user') +export class TipoUserController { + + constructor(private tipoUserService: TipoUserService) {} + + @ApiOperation({ summary: 'Obtener todos los tipos de usuario' }) + @ApiResponse({ status: 200, description: 'Lista de tipos de usuario obtenida correctamente.' }) + @Get() + getTipoUsers(): Promise { + return this.tipoUserService.getTipoUsers(); + } + + @Get(':id') + @ApiOperation({ summary: 'Obtener un tipo de usuario por ID' }) + @ApiParam({ name: 'id', description: 'ID del tipo de usuario', example: 1 }) + @ApiResponse({ status: 200, description: 'Tipo de usuario obtenido correctamente.' }) + @ApiResponse({ status: 404, description: 'Tipo de usuario no encontrado.' }) + getTipoUser(@Param('id', ParseIntPipe) id: number) { + return this.tipoUserService.getTipoUser(id); + } + + @Post() + @ApiOperation({ + summary: 'Crear un tipo de usuario', + description: 'Este endpoint permite registrar un nuevo tipo de usuario en el sistema.', + }) + @ApiBody({ + description: 'Datos del tipo de usuario', + schema: { + type: 'object', + properties: { + tipo: { type: 'string', example: 'Administrador' }, + nombre: { type: 'string', example: 'Juan' }, + apellido_p: { type: 'string', example: 'Pérez' }, + apellido_m: { type: 'string', example: 'Gómez' }, + }, + }, + }) + @ApiResponse({ status: 201, description: 'Tipo de usuario creado correctamente.' }) + @ApiResponse({ status: 400, description: 'Datos inválidos en la solicitud.' }) + + createTipoUser(@Body() newTipoUser: CreateTipoUserDto) { + return this.tipoUserService.createTipoUser(newTipoUser) + } + + @Delete(':id') + deleteTipoUser(@Param('id', ParseIntPipe) id:number) { + return this.tipoUserService.deleteTipoUser(id) + } + + @Patch() + updateTipoUser(@Param(':id', ParseIntPipe) id: number, @Body() tipoUser: UpdateTipoUserDto) { + return this.tipoUserService.updateTipoUser(id, tipoUser) + } +} diff --git a/src/tipo_user/tipo_user.entity.ts b/src/tipo_user/tipo_user.entity.ts new file mode 100644 index 0000000..a20976e --- /dev/null +++ b/src/tipo_user/tipo_user.entity.ts @@ -0,0 +1,28 @@ +import { Administrador } from "src/administrador/administrador.entity"; +import { Participante } from "src/participante/participante.entity"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class TipoUser { + @PrimaryGeneratedColumn() + id_tipo_user: number; + + @Column() + tipo: string; + + @Column() + nombre: string; + + @Column({nullable: true}) + apellido_p: string; + + @Column({nullable: true}) + apellido_m: string; + + @OneToMany(() => Participante, participante => participante.tipo_user) + participante: Participante[] + + @OneToMany(() => Administrador, administrador => administrador.tipoUser) + administrador: Administrador[] + +} \ No newline at end of file diff --git a/src/tipo_user/tipo_user.module.ts b/src/tipo_user/tipo_user.module.ts new file mode 100644 index 0000000..2caf76b --- /dev/null +++ b/src/tipo_user/tipo_user.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { TipoUserService } from './tipo_user.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { TipoUser } from './tipo_user.entity'; +import { TipoUserController } from './tipo_user.controller'; +import { Administrador } from 'src/administrador/administrador.entity'; +import { Participante } from 'src/participante/participante.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([TipoUser, Administrador, Participante])], + controllers: [TipoUserController], + providers: [TipoUserService], + exports: [TipoUserService] + +}) +export class TipoUserModule {} diff --git a/src/tipo_user/tipo_user.service.ts b/src/tipo_user/tipo_user.service.ts new file mode 100644 index 0000000..f86d4a4 --- /dev/null +++ b/src/tipo_user/tipo_user.service.ts @@ -0,0 +1,126 @@ +import { BadRequestException, HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { TipoUser } from './tipo_user.entity'; +import { Repository } from 'typeorm'; +import { CreateTipoUserDto } from './dto/create-tipo-user.dto'; +import { UpdateTipoUserDto } from './dto/update.tipo_user.dto'; +import { Participante } from 'src/participante/participante.entity'; +import { Administrador } from 'src/administrador/administrador.entity'; + +@Injectable() +export class TipoUserService { + + constructor( + @InjectRepository(TipoUser) private tipoUserRepository: Repository, + @InjectRepository(Participante) private participanteRepository: Repository, + @InjectRepository(Administrador) private administradorRepository: Repository, + ) {} + + /* + //Funcion para registrar usuario + async registrarUsuario(dto: CreateTipoUserDto) { + // Crear el registro en tipo_user + const tipoUser = this.tipoUserRepository.create({ + tipo: dto.tipo, + nombre: dto.nombre, + apellido_p: dto.apellido_p, + apellido_m: dto.apellido_m, + }); + + await this.tipoUserRepository.save(tipoUser); + + // Si es participante, insertar en participante + if (dto.tipo === 'participante') { + if (!dto.correo) { + throw new BadRequestException('El correo es obligatorio para participantes'); + } + + const participante = this.participanteRepository.create({ + correo: dto.correo, + tipo_user: tipoUser, // Relación con tipo_user + }); + + await this.participanteRepository.save(participante); + } + + // Si es administrador, insertar en administrador + if (dto.tipo === 'administrador') { + const administrador = this.administradorRepository.create({ + tipoUser: tipoUser, // Relación con tipo_user + }); + + await this.administradorRepository.save(administrador); + } + + return { message: 'Usuario registrado correctamente' }; + } + } + */ + + async createTipoUser(tipoUser: CreateTipoUserDto) { + // falta hacer la validacion + + const tipo_userFound = await this.tipoUserRepository.findOne({ + where: { + nombre: tipoUser.nombre, + tipo: tipoUser.tipo, + //id_tipo_user: + } + }) + + if(tipo_userFound) { + return new HttpException('Tipo User already exict', HttpStatus.NOT_FOUND); + } + + const tipo_user = this.tipoUserRepository.create(tipoUser) + + return this.tipoUserRepository.save(tipo_user) + } + + getTipoUsers() { + return this.tipoUserRepository.find({ + relations: ['participante', 'administrador'] + }) + } + + async getTipoUser(id: number) { + const tipo_userFound = await this.tipoUserRepository.findOne({ + where: { + id_tipo_user: id + }, + relations: ['participante', 'administrador'] + }); + + if(!tipo_userFound) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return tipo_userFound; + } + + async deleteTipoUser(id_tipo_user: number) { + const result = await this.tipoUserRepository.delete({ id_tipo_user }) + + if(result.affected === 0) { + return new HttpException('User not found', HttpStatus.NOT_FOUND); + } + + return result + } + + async updateTipoUser(id_tipo_user: number, tipo_user: UpdateTipoUserDto) { + const tipo_userFound = await this.tipoUserRepository.findOne({ + where: { + id_tipo_user + } + }) + + if(!tipo_userFound) { + return new HttpException('User not found', HttpStatus.NOT_FOUND) + } + + const updateTipoUser = Object.assign(tipo_userFound, tipo_user) + return this.tipoUserRepository.save(updateTipoUser) + } + +}