registrar el evento cuando se crea en el formulario
This commit is contained in:
@@ -11,6 +11,8 @@ import { Opcion } from '../opcion/entities/opcion.entity';
|
|||||||
import { PreguntaOpcion } from '../pregunta_opcion/entities/pregunta_opcion.entity';
|
import { PreguntaOpcion } from '../pregunta_opcion/entities/pregunta_opcion.entity';
|
||||||
import { TipoPregunta } from '../tipo_pregunta/entities/tipo_pregunta.entity';
|
import { TipoPregunta } from '../tipo_pregunta/entities/tipo_pregunta.entity';
|
||||||
import { TipoCuestionario } from '../tipo_cuestionario/entities/tipo_cuestionario.entity';
|
import { TipoCuestionario } from '../tipo_cuestionario/entities/tipo_cuestionario.entity';
|
||||||
|
import { Evento } from '../evento/evento.entity';
|
||||||
|
import { EventoService } from '../evento/evento.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -23,11 +25,12 @@ import { TipoCuestionario } from '../tipo_cuestionario/entities/tipo_cuestionari
|
|||||||
Opcion,
|
Opcion,
|
||||||
PreguntaOpcion,
|
PreguntaOpcion,
|
||||||
TipoPregunta,
|
TipoPregunta,
|
||||||
TipoCuestionario
|
TipoCuestionario,
|
||||||
|
Evento
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
controllers: [CuestionarioController],
|
controllers: [CuestionarioController],
|
||||||
providers: [CuestionarioService],
|
providers: [CuestionarioService, EventoService],
|
||||||
exports: [TypeOrmModule, CuestionarioService]
|
exports: [TypeOrmModule, CuestionarioService]
|
||||||
})
|
})
|
||||||
export class CuestionarioModule {}
|
export class CuestionarioModule {}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import { Opcion } from '../opcion/entities/opcion.entity';
|
|||||||
import { PreguntaOpcion } from '../pregunta_opcion/entities/pregunta_opcion.entity';
|
import { PreguntaOpcion } from '../pregunta_opcion/entities/pregunta_opcion.entity';
|
||||||
import { TipoPregunta } from '../tipo_pregunta/entities/tipo_pregunta.entity';
|
import { TipoPregunta } from '../tipo_pregunta/entities/tipo_pregunta.entity';
|
||||||
import { TipoCuestionario } from '../tipo_cuestionario/entities/tipo_cuestionario.entity';
|
import { TipoCuestionario } from '../tipo_cuestionario/entities/tipo_cuestionario.entity';
|
||||||
|
import { Evento } from '../evento/evento.entity';
|
||||||
|
import { EventoService } from '../evento/evento.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CuestionarioService {
|
export class CuestionarioService {
|
||||||
@@ -32,7 +34,10 @@ export class CuestionarioService {
|
|||||||
private preguntaOpcionRepository: Repository<PreguntaOpcion>,
|
private preguntaOpcionRepository: Repository<PreguntaOpcion>,
|
||||||
@InjectRepository(TipoPregunta)
|
@InjectRepository(TipoPregunta)
|
||||||
private tipoPreguntaRepository: Repository<TipoPregunta>,
|
private tipoPreguntaRepository: Repository<TipoPregunta>,
|
||||||
|
@InjectRepository(Evento)
|
||||||
|
private eventoRepository: Repository<Evento>,
|
||||||
private dataSource: DataSource,
|
private dataSource: DataSource,
|
||||||
|
private eventoService: EventoService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async create(createCuestionarioDto: CreateCuestionarioDto) {
|
async create(createCuestionarioDto: CreateCuestionarioDto) {
|
||||||
@@ -41,6 +46,33 @@ export class CuestionarioService {
|
|||||||
await queryRunner.startTransaction();
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Verificar si se especificó un evento y búscarlo/crearlo
|
||||||
|
let idEvento: number | undefined = undefined;
|
||||||
|
|
||||||
|
if (createCuestionarioDto.evento) {
|
||||||
|
// Buscar si el evento ya existe
|
||||||
|
let evento = await this.eventoRepository.findOne({
|
||||||
|
where: { nombre_evento: createCuestionarioDto.evento }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Si no existe, crearlo
|
||||||
|
if (!evento) {
|
||||||
|
const nuevoEvento = {
|
||||||
|
nombre_evento: createCuestionarioDto.evento,
|
||||||
|
tipo_evento: 'Predeterminado',
|
||||||
|
fecha_inicio: createCuestionarioDto.fecha_inicio || new Date(),
|
||||||
|
fecha_fin: createCuestionarioDto.fecha_fin || new Date(Date.now() + 86400000) // 1 día después si no hay fecha
|
||||||
|
};
|
||||||
|
|
||||||
|
evento = await queryRunner.manager.save(Evento, nuevoEvento);
|
||||||
|
console.log(`Evento creado: ${evento.nombre_evento}, ID: ${evento.id_evento}`);
|
||||||
|
} else {
|
||||||
|
console.log(`Evento encontrado: ${evento.nombre_evento}, ID: ${evento.id_evento}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
idEvento = evento.id_evento;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. Crear cuestionario
|
// 1. Crear cuestionario
|
||||||
const cuestionario = new Cuestionario();
|
const cuestionario = new Cuestionario();
|
||||||
cuestionario.nombre_form = createCuestionarioDto.nombre_form;
|
cuestionario.nombre_form = createCuestionarioDto.nombre_form;
|
||||||
@@ -50,6 +82,11 @@ export class CuestionarioService {
|
|||||||
cuestionario.id_tipo_cuestionario = createCuestionarioDto.id_tipo_cuestionario;
|
cuestionario.id_tipo_cuestionario = createCuestionarioDto.id_tipo_cuestionario;
|
||||||
cuestionario.contador_secciones = createCuestionarioDto.secciones?.length || 0;
|
cuestionario.contador_secciones = createCuestionarioDto.secciones?.length || 0;
|
||||||
cuestionario.editable = true;
|
cuestionario.editable = true;
|
||||||
|
|
||||||
|
// Asociar el cuestionario con el evento si existe
|
||||||
|
if (idEvento !== undefined) {
|
||||||
|
cuestionario.id_evento = idEvento;
|
||||||
|
}
|
||||||
|
|
||||||
const savedCuestionario = await queryRunner.manager.save(cuestionario);
|
const savedCuestionario = await queryRunner.manager.save(cuestionario);
|
||||||
|
|
||||||
@@ -172,7 +209,8 @@ export class CuestionarioService {
|
|||||||
async findCompleto(id: number) {
|
async findCompleto(id: number) {
|
||||||
// Obtener el cuestionario básico
|
// Obtener el cuestionario básico
|
||||||
const cuestionario = await this.cuestionarioRepository.findOne({
|
const cuestionario = await this.cuestionarioRepository.findOne({
|
||||||
where: { id_cuestionario: id }
|
where: { id_cuestionario: id },
|
||||||
|
relations: ['evento'] // Incluir la relación con el evento
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!cuestionario) {
|
if (!cuestionario) {
|
||||||
@@ -294,6 +332,13 @@ export class CuestionarioService {
|
|||||||
id_tipo_cuestionario: tipoCuestionario.id_tipo_cuestionario,
|
id_tipo_cuestionario: tipoCuestionario.id_tipo_cuestionario,
|
||||||
tipo_cuestionario: tipoCuestionario.tipo_cuestionario
|
tipo_cuestionario: tipoCuestionario.tipo_cuestionario
|
||||||
},
|
},
|
||||||
|
evento: cuestionario.evento ? {
|
||||||
|
id_evento: cuestionario.evento.id_evento,
|
||||||
|
nombre_evento: cuestionario.evento.nombre_evento,
|
||||||
|
tipo_evento: cuestionario.evento.tipo_evento,
|
||||||
|
fecha_inicio: cuestionario.evento.fecha_inicio ? cuestionario.evento.fecha_inicio.toISOString() : null,
|
||||||
|
fecha_fin: cuestionario.evento.fecha_fin ? cuestionario.evento.fecha_fin.toISOString() : null
|
||||||
|
} : null,
|
||||||
cuestionario: {
|
cuestionario: {
|
||||||
id_cuestionario: cuestionario.id_cuestionario,
|
id_cuestionario: cuestionario.id_cuestionario,
|
||||||
nombre_form: cuestionario.nombre_form,
|
nombre_form: cuestionario.nombre_form,
|
||||||
@@ -304,13 +349,43 @@ export class CuestionarioService {
|
|||||||
fecha_fin: cuestionario.fecha_fin ? cuestionario.fecha_fin.toISOString() : null,
|
fecha_fin: cuestionario.fecha_fin ? cuestionario.fecha_fin.toISOString() : null,
|
||||||
id_cuestionario_original: cuestionario.id_cuestionario_original,
|
id_cuestionario_original: cuestionario.id_cuestionario_original,
|
||||||
id_tipo_cuestionario: cuestionario.id_tipo_cuestionario,
|
id_tipo_cuestionario: cuestionario.id_tipo_cuestionario,
|
||||||
|
id_evento: cuestionario.id_evento || null,
|
||||||
secciones: seccionesFormateadas
|
secciones: seccionesFormateadas
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: number, updateCuestionarioDto: UpdateCuestionarioDto) {
|
async update(id: number, updateCuestionarioDto: UpdateCuestionarioDto) {
|
||||||
return this.cuestionarioRepository.update(id, updateCuestionarioDto);
|
// Si el DTO incluye el campo "evento" (string), debemos procesarlo aparte
|
||||||
|
if (updateCuestionarioDto.evento) {
|
||||||
|
// Buscar o crear evento
|
||||||
|
let evento = await this.eventoRepository.findOne({
|
||||||
|
where: { nombre_evento: updateCuestionarioDto.evento }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!evento) {
|
||||||
|
// Crear el evento
|
||||||
|
const nuevoEvento = {
|
||||||
|
nombre_evento: updateCuestionarioDto.evento,
|
||||||
|
tipo_evento: 'Predeterminado',
|
||||||
|
fecha_inicio: new Date(),
|
||||||
|
fecha_fin: new Date(Date.now() + 86400000)
|
||||||
|
};
|
||||||
|
|
||||||
|
evento = await this.eventoRepository.save(nuevoEvento);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asignar el ID del evento al DTO de actualización
|
||||||
|
updateCuestionarioDto.id_evento = evento.id_evento;
|
||||||
|
|
||||||
|
// Eliminar la propiedad evento para evitar conflictos
|
||||||
|
delete updateCuestionarioDto.evento;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preparar los datos para la actualización
|
||||||
|
const updateData: any = { ...updateCuestionarioDto };
|
||||||
|
|
||||||
|
return this.cuestionarioRepository.update(id, updateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(id: number) {
|
remove(id: number) {
|
||||||
|
|||||||
@@ -1,28 +1,66 @@
|
|||||||
import { CreateSeccionDto } from '../../seccion/dto/create-seccion.dto';
|
import { CreateSeccionDto } from '../../seccion/dto/create-seccion.dto';
|
||||||
import { IsArray, IsDateString, IsNotEmpty, IsNumber, IsOptional, IsString, ValidateNested } from 'class-validator';
|
import { IsArray, IsDateString, IsNotEmpty, IsNumber, IsOptional, IsString, ValidateNested } from 'class-validator';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class CreateCuestionarioDto {
|
export class CreateCuestionarioDto {
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Nombre del formulario',
|
||||||
|
example: 'Registro para la Feria de la Sexualidad - FES Acatlán'
|
||||||
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsString()
|
@IsString()
|
||||||
nombre_form: string;
|
nombre_form: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Descripción del formulario',
|
||||||
|
example: 'Formulario de registro para la feria...',
|
||||||
|
required: false
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
descripcion?: string;
|
descripcion?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Fecha de inicio',
|
||||||
|
example: '2025-03-26T00:00:00',
|
||||||
|
required: false
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
fecha_inicio?: Date;
|
fecha_inicio?: Date;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Fecha de fin',
|
||||||
|
example: '2025-03-31T23:59:59',
|
||||||
|
required: false
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
fecha_fin?: Date;
|
fecha_fin?: Date;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID del tipo de cuestionario',
|
||||||
|
example: 1
|
||||||
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
id_tipo_cuestionario: number;
|
id_tipo_cuestionario: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Nombre del evento asociado',
|
||||||
|
example: 'Feria de la Sexualidad',
|
||||||
|
required: false
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
evento?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Secciones del cuestionario',
|
||||||
|
type: [CreateSeccionDto],
|
||||||
|
required: false
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
|
|||||||
@@ -1,4 +1,15 @@
|
|||||||
import { PartialType } from '@nestjs/mapped-types';
|
import { PartialType } from '@nestjs/mapped-types';
|
||||||
import { CreateCuestionarioDto } from './create-cuestionario.dto';
|
import { CreateCuestionarioDto } from './create-cuestionario.dto';
|
||||||
|
import { IsNumber, IsOptional } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class UpdateCuestionarioDto extends PartialType(CreateCuestionarioDto) {}
|
export class UpdateCuestionarioDto extends PartialType(CreateCuestionarioDto) {
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID del evento asociado',
|
||||||
|
example: 1,
|
||||||
|
required: false
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
id_evento?: number;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { CuestionarioSeccion } from 'src/cuestionario_seccion/entities/cuestionario_seccion.entity';
|
import { CuestionarioSeccion } from 'src/cuestionario_seccion/entities/cuestionario_seccion.entity';
|
||||||
|
import { Evento } from 'src/evento/evento.entity';
|
||||||
import { TipoCuestionario } from 'src/tipo_cuestionario/entities/tipo_cuestionario.entity';
|
import { TipoCuestionario } from 'src/tipo_cuestionario/entities/tipo_cuestionario.entity';
|
||||||
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToMany, ManyToOne } from 'typeorm';
|
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToMany, ManyToOne, JoinColumn } from 'typeorm';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -39,4 +40,11 @@ export class Cuestionario {
|
|||||||
|
|
||||||
@ManyToOne(()=> Cuestionario)
|
@ManyToOne(()=> Cuestionario)
|
||||||
cuestionarioOriginal: Cuestionario;
|
cuestionarioOriginal: Cuestionario;
|
||||||
|
|
||||||
|
@Column({ type: 'int', nullable: true })
|
||||||
|
id_evento: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Evento)
|
||||||
|
@JoinColumn({ name: 'id_evento' })
|
||||||
|
evento: Evento;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,17 +157,15 @@ export class CuestionarioRespondidoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: number) {
|
async findOne(id: number) {
|
||||||
|
// Obtener cuestionario respondido con sus relaciones básicas
|
||||||
const cuestionarioRespondido = await this.cuestionarioRespondidoRepository.findOne({
|
const cuestionarioRespondido = await this.cuestionarioRespondidoRepository.findOne({
|
||||||
where: { idCuestionarioRespondido: id },
|
where: { idCuestionarioRespondido: id },
|
||||||
relations: [
|
relations: [
|
||||||
'participante',
|
'participante',
|
||||||
'cuestionario',
|
'cuestionario',
|
||||||
'respuestasAbiertas',
|
'respuestasAbiertas',
|
||||||
'respuestasAbiertas.pregunta',
|
'respuestasAbiertas.pregunta',
|
||||||
'respuestasCerradas',
|
'respuestasCerradas'
|
||||||
'respuestasCerradas.preguntaOpcion',
|
|
||||||
'respuestasCerradas.preguntaOpcion.opcion',
|
|
||||||
'respuestasCerradas.preguntaOpcion.pregunta'
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -175,7 +173,48 @@ export class CuestionarioRespondidoService {
|
|||||||
throw new NotFoundException(`Cuestionario respondido con ID ${id} no encontrado`);
|
throw new NotFoundException(`Cuestionario respondido con ID ${id} no encontrado`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cuestionarioRespondido;
|
// Obtener directamente los datos de respuestas cerradas desde la base de datos
|
||||||
|
// usando una consulta SQL directa
|
||||||
|
const respuestasCerradas = await this.dataSource.query(`
|
||||||
|
SELECT
|
||||||
|
rpc.idRespuestaParticipanteCerrada,
|
||||||
|
rpc.id_pregunta_opcion,
|
||||||
|
po.id_pregunta,
|
||||||
|
p.texto_pregunta,
|
||||||
|
p.id_tipo_pregunta,
|
||||||
|
o.id_opcion,
|
||||||
|
o.opcion
|
||||||
|
FROM respuesta_participante_cerrada rpc
|
||||||
|
LEFT JOIN pregunta_opcion po ON rpc.id_pregunta_opcion = po.id_pregunta_opcion
|
||||||
|
LEFT JOIN pregunta p ON po.id_pregunta = p.id_pregunta
|
||||||
|
LEFT JOIN opcion o ON po.id_opcion = o.id_opcion
|
||||||
|
WHERE rpc.id_cuestionario_respondido = ?
|
||||||
|
`, [id]);
|
||||||
|
|
||||||
|
console.log('Respuestas cerradas SQL:', JSON.stringify(respuestasCerradas, null, 2));
|
||||||
|
|
||||||
|
// Transformar las respuestas cerradas al formato deseado
|
||||||
|
const respuestasCerradasFormateadas = respuestasCerradas.map(respuesta => ({
|
||||||
|
idRespuestaParticipanteCerrada: respuesta.idRespuestaParticipanteCerrada,
|
||||||
|
id_pregunta_opcion: respuesta.id_pregunta_opcion,
|
||||||
|
pregunta: {
|
||||||
|
id_pregunta: respuesta.id_pregunta,
|
||||||
|
texto_pregunta: respuesta.texto_pregunta,
|
||||||
|
id_tipo_pregunta: respuesta.id_tipo_pregunta
|
||||||
|
},
|
||||||
|
opcion: {
|
||||||
|
id_opcion: respuesta.id_opcion,
|
||||||
|
opcion: respuesta.opcion
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Crear el objeto de respuesta con el formato deseado
|
||||||
|
const resultado = {
|
||||||
|
...cuestionarioRespondido,
|
||||||
|
respuestasCerradas: respuestasCerradasFormateadas
|
||||||
|
};
|
||||||
|
|
||||||
|
return resultado;
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: number, updateCuestionarioRespondidoDto: UpdateCuestionarioRespondidoDto) {
|
update(id: number, updateCuestionarioRespondidoDto: UpdateCuestionarioRespondidoDto) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { CreateQrDto } from './dto/create-qr.dto';
|
import { CreateQrDto } from './dto/create-qr.dto';
|
||||||
import { UpdateQrDto } from './dto/update.qr.dto';
|
import { UpdateQrDto } from './dto/update.qr.dto';
|
||||||
|
// @ts-ignore
|
||||||
import * as QRCode from 'qrcode';
|
import * as QRCode from 'qrcode';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const feriaSexualidad = {
|
|||||||
fecha_inicio: '2025-03-07T00:00:01',
|
fecha_inicio: '2025-03-07T00:00:01',
|
||||||
fecha_fin: '2025-03-18T23:59:59',
|
fecha_fin: '2025-03-18T23:59:59',
|
||||||
id_tipo_cuestionario: 1,
|
id_tipo_cuestionario: 1,
|
||||||
|
evento: 'Feria de la Sexualidad',
|
||||||
secciones: [
|
secciones: [
|
||||||
{
|
{
|
||||||
titulo: 'Información Personal',
|
titulo: 'Información Personal',
|
||||||
|
|||||||
Reference in New Issue
Block a user