Se agregó la visualización de datos y cambios en el servicio de excel

This commit is contained in:
evenegas
2025-06-18 12:54:26 -06:00
parent 4984c47029
commit bf83f9d788
10 changed files with 192 additions and 55 deletions
+3 -1
View File
@@ -9,6 +9,7 @@ import * as entities from './entities/entities';
import { ExcelModule } from './excel/excel.module';
import { AuthModule } from './auth/auth.module';
import { MovimientoModule } from './movimiento/movimiento.module';
import { UsuariosModule } from './usuarios/usuarios.module';
@Module({
@@ -49,7 +50,8 @@ import { MovimientoModule } from './movimiento/movimiento.module';
ExcelModule,
AuthModule,
MovimientoModule
MovimientoModule,
UsuariosModule
],
controllers: [AppController],
+13 -12
View File
@@ -90,6 +90,19 @@ export class Usuario {
@OneToMany(() => UsuarioTipoUsuario, utu => utu.usuario)
usuarioTipos: UsuarioTipoUsuario[];
}
@Entity({ name: 'carrera_usuario' })
export class CarreraUsuario {
@PrimaryGeneratedColumn({ name: 'id_carrera_usuario', type: 'int' })
id_carrera_usuario: number;
@ManyToOne(() => Carrera, carrera => carrera.carreraUsuarios)
@JoinColumn({ name: 'id_carrera' })
carrera: Carrera;
@ManyToOne(() => Usuario, usuario => usuario.carreraUsuarios)
@JoinColumn({ name: 'id_usuario' })
usuario: Usuario;
}
@Entity({ name: 'usuariosDelSistema' })
export class UsuariosDelSistema {
@@ -113,19 +126,7 @@ export class UsuariosDelSistema {
origen: Origen;
}
@Entity({ name: 'carrera_usuario' })
export class CarreraUsuario {
@PrimaryGeneratedColumn({ name: 'id_carrera_usuario', type: 'int' })
id_carrera_usuario: number;
@ManyToOne(() => Carrera, carrera => carrera.carreraUsuarios)
@JoinColumn({ name: 'id_carrera' })
carrera: Carrera;
@ManyToOne(() => Usuario, usuario => usuario.carreraUsuarios)
@JoinColumn({ name: 'id_usuario' })
usuario: Usuario;
}
@Entity({ name: 'equipo' })
export class Equipo {
+1 -1
View File
@@ -3,7 +3,7 @@ import { Controller, Post, Get, UseGuards, Request, Res, UploadedFile, UseInterc
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth } from '@nestjs/swagger';
import { FileInterceptor } from '@nestjs/platform-express';
import e, { Response } from 'express';
import { Response } from 'express';
import { ExcelDocumentation } from './excel.documentation';
import { ExcelService } from './excel.service';
import { MovimientoService } from '../movimiento/movimiento.service';
+3 -3
View File
@@ -2,15 +2,15 @@ import { Module } from '@nestjs/common';
import { ExcelService } from './excel.service';
import { ExcelController } from './excel.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Usuario, Genero, Carrera } from '../entities/entities';
import { Usuario, Genero, Carrera, CarreraUsuario, UsuarioTipoUsuario, TipoUsuario } from '../entities/entities';
import { MovimientoModule } from 'src/movimiento/movimiento.module';
@Module({
imports: [
TypeOrmModule.forFeature([Usuario, Genero, Carrera]),
TypeOrmModule.forFeature([Usuario, Genero, Carrera, CarreraUsuario, UsuarioTipoUsuario, TipoUsuario]),
MovimientoModule
],
providers: [ExcelService],
controllers: [ExcelController],
})
export class ExcelModule {}
export class ExcelModule { }
+52 -38
View File
@@ -3,7 +3,7 @@ import { Injectable, BadRequestException, Logger } from '@nestjs/common';
import { Workbook } from 'exceljs';
import { In, Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { Usuario } from '../entities/entities';
import { CarreraUsuario, TipoUsuario, Usuario, UsuarioTipoUsuario } from '../entities/entities';
import { Genero } from '../entities/entities';
import { Carrera } from '../entities/entities';
@@ -34,6 +34,12 @@ export class ExcelService {
private readonly generoRepo: Repository<Genero>,
@InjectRepository(Carrera)
private readonly carreraRepo: Repository<Carrera>,
@InjectRepository(CarreraUsuario)
private readonly carreraUsuarioRepo: Repository<CarreraUsuario>,
@InjectRepository(UsuarioTipoUsuario)
private readonly usuarioTipoUsuarioRepo: Repository<UsuarioTipoUsuario>,
@InjectRepository(TipoUsuario)
private readonly tipoUsuarioRepo: Repository<TipoUsuario>,
// … inyecta otros repositorios si los usarás
) { }
@@ -181,6 +187,16 @@ export class ExcelService {
await this.carreraRepo.save(carrera);
}
let tipo = await this.tipoUsuarioRepo.findOne({
where: { tipo_usuario: r.tipo.trim() },
});
if (!tipo) {
tipo = this.tipoUsuarioRepo.create({
tipo_usuario: r.tipo.trim(),
});
await this.tipoUsuarioRepo.save(tipo);
}
const generacion = /^[0-9]{4}$/.test(r.gen?.toString().trim())
? parseInt(r.gen.toString().trim(), 10)
: null;
@@ -198,12 +214,24 @@ export class ExcelService {
});
await this.usuarioRepo.save(usuario);
// 4) Relacion usuariocarrera (tabla intermedia)
await this.carreraRepo
.createQueryBuilder()
.relation('carreraUsuarios')
.of(carrera)
.add(usuario);
// 4) Relacion usuariocarrxera (tabla intermedia)
const carreraUsuario = this.carreraUsuarioRepo.create({
usuario,
carrera,
});
await this.carreraUsuarioRepo.save(carreraUsuario);
// 5) Tipo de usuario
const usuarioTipo = this.usuarioTipoUsuarioRepo.create({
usuario,
tipoUsuario: tipo,
});
await this.usuarioTipoUsuarioRepo.save(usuarioTipo);
}
return { inserted: rows.length };
@@ -271,17 +299,7 @@ export class ExcelService {
'carreraUsuarios', // relación intermedia
'carreraUsuarios.carrera', // carrera asociada a través de la intermedia
],
select: {
num_cuenta: true,
nombre: true,
a_paterno: true,
a_materno: true,
rfc: true,
fecha_nacimiento: true,
generacion: true,
carreraUsuarios: true,
},
});
@@ -343,17 +361,25 @@ export class ExcelService {
'carreraUsuarios', // relación intermedia
'carreraUsuarios.carrera', // carrera asociada a través de la intermedia
],
select: {
num_cuenta: true,
nombre: true,
a_paterno: true,
a_materno: true,
rfc: true,
carreraUsuarios: true,
},
});
const usuariosTipo = await this.usuarioRepo.find({
relations: [
'genero',
'carreraUsuarios', // relación intermedia
'carreraUsuarios.carrera',
'usuarioTipos', // relación con tipo de usuario
'usuarioTipos.tipoUsuario', // tipo de usuario asociado
],
});
console.log('Usuarios encontrados:', usuariosTipo);
console.log('Usuarios encontrados:', usuarios);
@@ -413,10 +439,7 @@ export class ExcelService {
'carreraUsuarios', // relación intermedia
'carreraUsuarios.carrera', // carrera asociada a través de la intermedia
],
select: {
num_cuenta: true,
fecha_nacimiento: true,
},
});
@@ -466,16 +489,7 @@ export class ExcelService {
'carreraUsuarios', // relación intermedia
'carreraUsuarios.carrera', // carrera asociada a través de la intermedia
],
select: {
num_cuenta: true,
nombre: true,
a_paterno: true,
a_materno: true,
fecha_nacimiento: true,
generacion: true,
carreraUsuarios: true,
},
});
+1
View File
@@ -0,0 +1 @@
export class CreateUsuarioDto {}
+4
View File
@@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/swagger';
import { CreateUsuarioDto } from './create-usuario.dto';
export class UpdateUsuarioDto extends PartialType(CreateUsuarioDto) {}
+40
View File
@@ -0,0 +1,40 @@
import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards } from '@nestjs/common';
import { UsuariosService } from './usuarios.service';
import { CreateUsuarioDto } from './dto/create-usuario.dto';
import { UpdateUsuarioDto } from './dto/update-usuario.dto';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth } from '@nestjs/swagger';
@Controller('usuarios')
export class UsuariosController {
constructor(private readonly usuariosService: UsuariosService) { }
@Get(':noCuenta')
findOne(@Param('noCuenta') noCuenta: string) {
return this.usuariosService.findOne(noCuenta);
}
// @UseGuards(AuthGuard('jwt'))
// @ApiBearerAuth('bearer')
// @Post()
// create(@Body() noCuenta: string) {
// return this.usuariosService.altaIndividual(createUsuarioDto);
// }
// @Get()
// findAll() {
// return this.usuariosService.findAll();
// }
// @Patch(':id')
// update(@Param('id') id: string, @Body() updateUsuarioDto: UpdateUsuarioDto) {
// return this.usuariosService.update(+id, updateUsuarioDto);
// }
// @Delete(':id')
// remove(@Param('id') id: string) {
// return this.usuariosService.remove(+id);
// }
}
+16
View File
@@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { UsuariosService } from './usuarios.service';
import { UsuariosController } from './usuarios.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Carrera, CarreraUsuario, Genero, Usuario } from 'src/entities/entities';
import { MovimientoModule } from 'src/movimiento/movimiento.module';
@Module({
imports: [
TypeOrmModule.forFeature([Usuario, Genero, Carrera, CarreraUsuario]),
MovimientoModule
],
controllers: [UsuariosController],
providers: [UsuariosService],
})
export class UsuariosModule { }
+59
View File
@@ -0,0 +1,59 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { CreateUsuarioDto } from './dto/create-usuario.dto';
import { UpdateUsuarioDto } from './dto/update-usuario.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { CarreraUsuario, Usuario } from 'src/entities/entities';
import { Repository } from 'typeorm';
@Injectable()
export class UsuariosService {
constructor(
@InjectRepository(Usuario)
private readonly usuarioRepository: Repository<Usuario>,
@InjectRepository(CarreraUsuario)
private readonly carreraUsuarioRepository: Repository<CarreraUsuario>,
) { }
altaIndividual(createUsuarioDto: CreateUsuarioDto) {
return 'This action adds a new usuario';
}
async findOne(noCuenta: string) {
const usuario = await this.usuarioRepository.findOne({
relations: [
'genero',
'carreraUsuarios',
'carreraUsuarios.carrera',
],
where: { num_cuenta: noCuenta },
});
if (!usuario) {
throw new NotFoundException('Usuario no encontrado');
}
// Transformar a formato plano
const resultadoPlano = {
num_cuenta: usuario.num_cuenta,
nombre: usuario.nombre,
a_paterno: usuario.a_paterno,
a_materno: usuario.a_materno,
fecha_nacimiento: usuario.fecha_nacimiento,
generacion: usuario.generacion,
genero: usuario.genero?.genero ?? '',
carreras: (usuario.carreraUsuarios ?? [])
.map(cu => cu.carrera?.carrera)
.filter(Boolean)
.join(', '), // todas las carreras como string plano
};
return [resultadoPlano]; // importante: frontend espera array
}
update(id: number, updateUsuarioDto: UpdateUsuarioDto) {
return `This action updates a #${id} usuario`;
}
}