From 11e7863d02a441697c144e20b784fb6e746b453e Mon Sep 17 00:00:00 2001 From: evenegas Date: Tue, 1 Apr 2025 19:10:59 -0600 Subject: [PATCH] =?UTF-8?q?se=20hizo=20el=20servicio=20de=20opci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/opcion/dto/create-opcion.dto.ts | 16 +- src/opcion/dto/update-opcion.dto.ts | 13 +- src/opcion/opcion.controller.ts | 30 ++-- src/opcion/opcion.module.ts | 10 ++ src/opcion/opcion.service.ts | 156 ++++++++++++++++-- src/tipo_pregunta/tipo_pregunta.controller.ts | 6 + src/tipo_pregunta/tipo_pregunta.service.ts | 16 ++ 7 files changed, 208 insertions(+), 39 deletions(-) diff --git a/src/opcion/dto/create-opcion.dto.ts b/src/opcion/dto/create-opcion.dto.ts index 69957f1..7964f47 100644 --- a/src/opcion/dto/create-opcion.dto.ts +++ b/src/opcion/dto/create-opcion.dto.ts @@ -1,11 +1,11 @@ -import { IsString, MaxLength } from "class-validator"; +import { IsString, IsNumber, IsNotEmpty, IsOptional } from 'class-validator'; export class CreateOpcionDto { - - - @IsString() - @MaxLength(50) - opcion: string; + @IsString() + @IsNotEmpty() + opcion: string; - -} + @IsNumber() + @IsOptional() + posicion?: number; +} \ No newline at end of file diff --git a/src/opcion/dto/update-opcion.dto.ts b/src/opcion/dto/update-opcion.dto.ts index 03e331e..67bbc79 100644 --- a/src/opcion/dto/update-opcion.dto.ts +++ b/src/opcion/dto/update-opcion.dto.ts @@ -1,4 +1,11 @@ -import { PartialType } from '@nestjs/mapped-types'; -import { CreateOpcionDto } from './create-opcion.dto'; +import { IsString, IsNumber, IsOptional } from 'class-validator'; -export class UpdateOpcionDto extends PartialType(CreateOpcionDto) {} +export class UpdateOpcionDto { + @IsString() + @IsOptional() + opcion?: string; + + @IsNumber() + @IsOptional() + posicion?: number; +} \ No newline at end of file diff --git a/src/opcion/opcion.controller.ts b/src/opcion/opcion.controller.ts index 635597a..b5f285f 100644 --- a/src/opcion/opcion.controller.ts +++ b/src/opcion/opcion.controller.ts @@ -2,33 +2,41 @@ import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/commo import { OpcionService } from './opcion.service'; import { CreateOpcionDto } from './dto/create-opcion.dto'; import { UpdateOpcionDto } from './dto/update-opcion.dto'; +import { Pregunta } from 'src/pregunta/entities/pregunta.entity'; @Controller('opcion') export class OpcionController { constructor(private readonly opcionService: OpcionService) {} - @Post() - create(@Body() createOpcionDto: CreateOpcionDto) { - return this.opcionService.create(createOpcionDto); + @Post() + async create( + @Param('PreguntaId')PreguntaId:number, + @Body() createOpcionDto: CreateOpcionDto) { + + return this.opcionService.create(PreguntaId,createOpcionDto); } @Get() - findAll() { - return this.opcionService.findAll(); + async findAll( + @Param('PreguntaId')PreguntaId:number + ) { + return this.opcionService.findAllByPregunta(PreguntaId); } @Get(':id') - findOne(@Param('id') id: string) { - return this.opcionService.findOne(+id); + async findOne( + @Param('preguntaId') preguntaId: number, + @Param('opcionId') OpcionId: number) { + return this.opcionService.findOne(preguntaId, OpcionId); } @Patch(':id') - update(@Param('id') id: string, @Body() updateOpcionDto: UpdateOpcionDto) { - return this.opcionService.update(+id, updateOpcionDto); + async pdate(@Param('preguntaId') preguntaId:number ,@Param('opcionId') id: number, @Body() updateOpcionDto: UpdateOpcionDto) { + return this.opcionService.update(preguntaId, id,updateOpcionDto); } @Delete(':id') - remove(@Param('id') id: string) { - return this.opcionService.remove(+id); + async remove(@Param('preguntaId') preguntaId:number ,@Param('opcionId') id: number) { + return this.opcionService.remove(preguntaId, id); } } diff --git a/src/opcion/opcion.module.ts b/src/opcion/opcion.module.ts index b638a8a..c3533d3 100644 --- a/src/opcion/opcion.module.ts +++ b/src/opcion/opcion.module.ts @@ -1,9 +1,19 @@ import { Module } from '@nestjs/common'; import { OpcionService } from './opcion.service'; import { OpcionController } from './opcion.controller'; +import { PreguntaModule } from 'src/pregunta/pregunta.module'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Opcion } from './entities/opcion.entity'; +import { TipoPregunta } from 'src/tipo_pregunta/entities/tipo_pregunta.entity'; @Module({ + imports: [ + TypeOrmModule.forFeature([Opcion]), + PreguntaModule, + TipoPregunta + ], controllers: [OpcionController], providers: [OpcionService], + exports: [OpcionService], }) export class OpcionModule {} diff --git a/src/opcion/opcion.service.ts b/src/opcion/opcion.service.ts index 9c44854..590b32e 100644 --- a/src/opcion/opcion.service.ts +++ b/src/opcion/opcion.service.ts @@ -1,36 +1,158 @@ -import { Injectable } from '@nestjs/common'; -import { CreateOpcionDto } from './dto/create-opcion.dto'; -import { UpdateOpcionDto } from './dto/update-opcion.dto'; -import { Opcion } from './entities/opcion.entity'; +import { Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; +import { Opcion } from './entities/opcion.entity'; + +import { Pregunta } from '../pregunta/entities/pregunta.entity'; +import { PreguntaOpcion } from 'src/pregunta_opcion/entities/pregunta_opcion.entity'; +import { CreateOpcionDto } from './dto/create-opcion.dto'; +import { UpdateOpcionDto } from './dto/update-opcion.dto'; @Injectable() export class OpcionService { constructor( @InjectRepository(Opcion) - private repository: Repository, - ){} + private readonly opcionRepository: Repository, + @InjectRepository(Pregunta) + private readonly preguntaRepository: Repository, + @InjectRepository(PreguntaOpcion) + private readonly preguntaOpcionRepository: Repository, + ) {} + async create(preguntaId: number, createOpcionDto: CreateOpcionDto) { + // Verificar que la pregunta exista y sea cerrada + const pregunta = await this.preguntaRepository.findOne({ + where: { id_pregunta: preguntaId }, + relations: ['tipo_pregunta'], + }); + if (!pregunta) { + throw new NotFoundException('Pregunta no encontrada'); + } - create():Promise { - return this.repository.save(this.repository.create()); + if (pregunta.id_tipo_pregunta.tipo_pregunta !== 'Cerrada') { + throw new Error('Solo se pueden agregar opciones a preguntas cerradas'); + } + + // Crear la opción + const opcion = this.opcionRepository.create({ + opcion: createOpcionDto.opcion, + }); + + const savedOpcion = await this.opcionRepository.save(opcion); + + // Crear la relación entre pregunta y opción + const preguntaOpcion = this.preguntaOpcionRepository.create({ + id_pregunta: { id_pregunta: preguntaId }, + id_opcion: savedOpcion, + posicion: createOpcionDto.posicion || 0, // Asignar posición + }); + + await this.preguntaOpcionRepository.save(preguntaOpcion); + + // Actualizar el contador de opciones en la pregunta + await this.preguntaRepository.increment( + { id_pregunta: preguntaId }, + 'contador_opcion', + 1 + ); + + return savedOpcion; } - findAll() { - return `This action returns all opcion`; + async findAllByPregunta(preguntaId: number) { + return this.preguntaOpcionRepository.find({ + where: { id_pregunta: { id_pregunta: preguntaId } }, + relations: ['opcion'], + order: { posicion: 'ASC' }, + }); } - findOne(id: number) { - return `This action returns a #${id} opcion`; + async findOne(preguntaId: number, OpcionId: number) { + const preguntaOpcion = await this.preguntaOpcionRepository.findOne({ + where: { + id_pregunta: { id_pregunta: preguntaId }, + id_opcion: { id_opcion: OpcionId }, + }, + relations: ['opcion'], + }); + + if (!preguntaOpcion) { + throw new NotFoundException('Opción no encontrada para esta pregunta'); + } + + return preguntaOpcion.id_opcion; } - update(id: number, updateOpcionDto: UpdateOpcionDto) { - return `This action updates a #${id} opcion`; + async update( + preguntaId: number, + id: number, + updateOpcionDto: UpdateOpcionDto + ) { + // Verificar que la relación exista + const preguntaOpcion = await this.preguntaOpcionRepository.findOne({ + where: { + id_pregunta: { id_pregunta: preguntaId }, + id_opcion: { id_opcion: id }, + }, + relations: ['opcion'], + }); + + if (!preguntaOpcion) { + throw new NotFoundException('Opción no encontrada para esta pregunta'); + } + + // Actualizar posición si se proporciona + if (updateOpcionDto.posicion !== undefined) { + await this.preguntaOpcionRepository.update( + { id_pregunta_opcion: preguntaOpcion.id_pregunta_opcion }, + { posicion: updateOpcionDto.posicion } + ); + } + + // Actualizar texto de la opción + if (updateOpcionDto.opcion) { + await this.opcionRepository.update( + { id_opcion: id }, + { opcion: updateOpcionDto.opcion } + ); + } + + return this.findOne(preguntaId, id); } - remove(id: number) { - return `This action removes a #${id} opcion`; + async remove(preguntaId: number, id: number) { + // Verificar que la relación exista + const preguntaOpcion = await this.preguntaOpcionRepository.findOne({ + where: { + id_pregunta: { id_pregunta: preguntaId }, + id_opcion: { id_opcion: id }, + }, + }); + + if (!preguntaOpcion) { + throw new NotFoundException('Opción no encontrada para esta pregunta'); + } + + // Eliminar la relación primero + await this.preguntaOpcionRepository.remove(preguntaOpcion); + + // Eliminar la opción (si no está siendo usada en otras preguntas) + const count = await this.preguntaOpcionRepository.count({ + where: { id_opcion: { id_opcion: id } }, + }); + + if (count === 0) { + await this.opcionRepository.delete(id); + } + + // Actualizar el contador de opciones en la pregunta + await this.preguntaRepository.decrement( + { id_pregunta: preguntaId }, + 'contador_opcion', + 1 + ); + + return { message: 'Opción eliminada correctamente' }; } -} +} \ No newline at end of file diff --git a/src/tipo_pregunta/tipo_pregunta.controller.ts b/src/tipo_pregunta/tipo_pregunta.controller.ts index e69de29..9e664b0 100644 --- a/src/tipo_pregunta/tipo_pregunta.controller.ts +++ b/src/tipo_pregunta/tipo_pregunta.controller.ts @@ -0,0 +1,6 @@ +import { Controller } from "@nestjs/common"; + +@Controller('tipo_pregunta') +export class TipoPreguntaController{ + +} \ No newline at end of file diff --git a/src/tipo_pregunta/tipo_pregunta.service.ts b/src/tipo_pregunta/tipo_pregunta.service.ts index e69de29..2c27e8b 100644 --- a/src/tipo_pregunta/tipo_pregunta.service.ts +++ b/src/tipo_pregunta/tipo_pregunta.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from "@nestjs/common"; +import { InjectRepository } from '@nestjs/typeorm'; +import { TipoPregunta } from "./entities/tipo_pregunta.entity"; +import { TipoCuestionario } from "src/tipo_cuestionario/entities/tipo_cuestionario.entity"; +import { Repository } from "typeorm"; + +@Injectable() +export class TipoPreguntaService{ + constructor( + @InjectRepository(TipoCuestionario) + private readonly tipoCuestionarioRepository: Repository + ){} + + + +} \ No newline at end of file