From 82cc556cd87a2a29adf9ef0becaf3d724315c2e7 Mon Sep 17 00:00:00 2001 From: lemuel Date: Fri, 12 Aug 2022 15:42:18 -0500 Subject: [PATCH] carga masiva equipos lista --- .gitignore | 2 +- src/app.gateway.ts | 14 +- src/tipo-usuario/tipo-usuario.module.ts | 3 +- src/upload-file/upload-file.controller.ts | 10 +- src/upload-file/upload-file.module.ts | 3 +- src/upload-file/upload-file.service.ts | 435 ++++++++++++---------- src/usuario/usuario.controller.ts | 4 + src/usuario/usuario.service.ts | 1 - 8 files changed, 250 insertions(+), 222 deletions(-) diff --git a/.gitignore b/.gitignore index 0c34e48..907c122 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # archivo env .env pcpuma_unam.sql -# /upload/* +/upload/* # compiled output /dist diff --git a/src/app.gateway.ts b/src/app.gateway.ts index 167fe63..8f73505 100644 --- a/src/app.gateway.ts +++ b/src/app.gateway.ts @@ -6,16 +6,14 @@ import { OnGatewayDisconnect, } from '@nestjs/websockets'; import { Socket, Server } from 'socket.io'; -import { Equipo } from './equipo/entity/equipo.entity'; -import { Usuario } from './usuario/entity/usuario.entity'; @WebSocketGateway({ cors: { origin: [ - // 'http://localhost:3176', - // 'http://localhost:3186', - 'http://132.248.80.196:3155', - 'http://132.248.80.196:3185', + 'http://localhost:3176', + 'http://localhost:3186', + // 'http://132.248.80.196:3155', + // 'http://132.248.80.196:3185', // 'https://pmodulospcpuma.unam.mx', // 'http://pmodulospcpuma.unam.mx:3015', // 'https://modulospcpuma.unam.mx', @@ -36,8 +34,8 @@ export class AppGateway this.server.emit('actualizar-operador', { id_institucion }); } - equiposNuevos(id_institucion: number, equiposNuevos: Equipo[]) { - this.server.emit('equipos-nuevos', { id_institucion, equiposNuevos }); + equiposNuevos(id_institucion: number, data) { + this.server.emit('equipos-nuevos', { id_institucion, data }); } usuariosNuevos(id_institucion: number, data) { diff --git a/src/tipo-usuario/tipo-usuario.module.ts b/src/tipo-usuario/tipo-usuario.module.ts index 582d894..f5c0928 100644 --- a/src/tipo-usuario/tipo-usuario.module.ts +++ b/src/tipo-usuario/tipo-usuario.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { PassportModule } from '@nestjs/passport'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { AppGateway } from '../app.gateway'; import { TipoUsuarioController } from './tipo-usuario.controller'; import { TipoUsuarioService } from './tipo-usuario.service'; import { TipoUsuario } from './entity/tipo-usuario.entity'; @@ -12,7 +11,7 @@ import { TipoUsuario } from './entity/tipo-usuario.entity'; TypeOrmModule.forFeature([TipoUsuario]), ], controllers: [TipoUsuarioController], - providers: [AppGateway, TipoUsuarioService], + providers: [TipoUsuarioService], exports: [TipoUsuarioService], }) export class TipoUsuarioModule {} diff --git a/src/upload-file/upload-file.controller.ts b/src/upload-file/upload-file.controller.ts index 1ca966d..d2a2f26 100644 --- a/src/upload-file/upload-file.controller.ts +++ b/src/upload-file/upload-file.controller.ts @@ -28,12 +28,10 @@ export class UploadFileController { const path = file ? `${file.destination}/${file.filename}` : null; if (!file) throw new BadRequestException('No se mandó ningún archivo.'); - return this.uploadFileService - .createEquipos(path, parseInt(query.id_institucion)) - .then((res) => { - fs.unlink(path, (err) => {}); - return res; - }); + return this.uploadFileService.createEquipos( + path, + parseInt(query.id_institucion), + ); } @Post('carga-masiva-usuarios') diff --git a/src/upload-file/upload-file.module.ts b/src/upload-file/upload-file.module.ts index 29d94af..40d7f24 100644 --- a/src/upload-file/upload-file.module.ts +++ b/src/upload-file/upload-file.module.ts @@ -1,6 +1,7 @@ import { ConflictException, Module } from '@nestjs/common'; import { PassportModule } from '@nestjs/passport'; import { MulterModule } from '@nestjs/platform-express'; +import { AppGateway } from '../app.gateway'; import { UploadFileController } from './upload-file.controller'; import { UploadFileService } from './upload-file.service'; import { CarritoModule } from '../carrito/carrito.module'; @@ -50,6 +51,6 @@ import { UsuarioModule } from '../usuario/usuario.module'; UsuarioModule, ], controllers: [UploadFileController], - providers: [UploadFileService], + providers: [AppGateway, UploadFileService], }) export class UploadFileModule {} diff --git a/src/upload-file/upload-file.service.ts b/src/upload-file/upload-file.service.ts index 93b6132..c1d8b0f 100644 --- a/src/upload-file/upload-file.service.ts +++ b/src/upload-file/upload-file.service.ts @@ -1,5 +1,7 @@ +import * as fs from 'fs'; import * as csvtojson from 'csvtojson'; import { BadRequestException, Injectable } from '@nestjs/common'; +import { AppGateway } from '../app.gateway'; import { Equipo } from '../equipo/entity/equipo.entity'; import { InstitucionUsuario } from '../institucion-usuario/entity/institucion-usuario.entity'; import { CarritoService } from '../carrito/carrito.service'; @@ -19,10 +21,12 @@ import { TipoUsuarioService } from '../tipo-usuario/tipo-usuario.service'; import { UsuarioService } from '../usuario/usuario.service'; import { UploadFileCargaMasivaUsuarioDto } from './dto/upload-file-carga-masiva-usuario.dto'; import { UploadFileCargaMasivaEquipoDto } from './dto/upload-file-carga-masiva-equipo.dto'; +import { Institucion } from 'src/institucion/entity/institucion.entity'; @Injectable() export class UploadFileService { constructor( + private appGateway: AppGateway, private carritoService: CarritoService, private equipoService: EquipoService, private equipoProgramaService: EquipoProgramaService, @@ -40,220 +44,245 @@ export class UploadFileService { private usuarioService: UsuarioService, ) {} + async evaluarEquipo( + institucion: Institucion, + index: number, + dataEquipo: UploadFileCargaMasivaEquipoDto, + mensajes: string[], + errores: string[], + equiposNuevos: Equipo[], + ) { + let error = this.errorBase(index); + + if ( + !dataEquipo.carrito || + !dataEquipo.entradas || + !dataEquipo.equipo || + !dataEquipo.marca || + !dataEquipo.modelo || + !dataEquipo.modulo || + !dataEquipo.numero_inventario || + !dataEquipo.numero_serie || + !dataEquipo.tipo + ) { + if (!dataEquipo.carrito) error += ' falta del campo carrito'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.entradas) error += ' falta del campo entradas'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.equipo) error += ' falta del campo equipo'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.marca) error += ' falta del campo marca'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.modelo) error += ' falta del campo modelo'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.modulo) error += ' falta del campo modulo'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.numero_inventario) + error += ' falta del campo numero_inventario'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.numero_serie) error += ' falta del campo numero_serie'; + if (error != this.errorBase(index)) error += ','; + if (!dataEquipo.tipo) error += ' falta del campo tipo'; + errores.push(error + '.'); + return; + } + + const tipoCarrito = + await this.institucionTipoCarritoService.findTipoCarritoByTipoCarrito( + dataEquipo.tipo, + false, + ); + const modulo = await this.moduloService.findModulo( + institucion, + dataEquipo.modulo, + false, + ); + const marca = await this.marcaService.findByMarca( + dataEquipo.marca, + 'e', + false, + ); + const modelo = await this.modeloService.findByModelo( + dataEquipo.modelo, + 'e', + false, + ); + const carrito = + tipoCarrito && modulo + ? await this.carritoService.findCarrito( + modulo, + tipoCarrito, + dataEquipo.carrito, + false, + ) + : null; + let equipo = carrito + ? await this.equipoService.findEquipoByEquipo( + carrito, + dataEquipo.equipo, + false, + ) + : null; + + if (!tipoCarrito || !marca || !modelo || !modulo || !carrito) { + if (!tipoCarrito) error += ' no existe este tipo de carrito'; + if (error != this.errorBase(index)) error += ','; + if (!marca) error += ' no existe esta marca'; + if (error != this.errorBase(index)) error += ','; + if (!modelo) error += ' no existe este modelo'; + if (error != this.errorBase(index)) error += ','; + if (!modulo) error += ' no existe este módulo'; + if (error != this.errorBase(index)) error += ','; + if (!carrito) error += ' no existe este carrito'; + errores.push(error + '.'); + return; + } + + if (equipo) { + errores.push( + `${error} ya existe un equipo de cómputo con el sobrenombre: ${equipo.equipo} en el carrito: ${equipo.carrito.carrito}.`, + ); + return; + } else { + equipo = await this.equipoService.findByNumeroInventario( + institucion, + dataEquipo.numero_inventario, + false, + ); + if (equipo) { + errores.push( + `${error} ya existe un equipo con ese número de inventario en esta institución.`, + ); + return; + } + equipo = await this.equipoService.create( + carrito, + dataEquipo.equipo, + dataEquipo.numero_inventario, + dataEquipo.numero_serie, + marca, + modelo, + ); + + const entradas = dataEquipo.entradas.split(','); + const programas = dataEquipo.programas + ? dataEquipo.programas.split(',') + : []; + + equipo.programas = []; + equipo.tiposEntradas = []; + for (let j = 0; j < entradas.length; j++) { + const tipoEntrada = + await this.institucionTipoEntradaService.findTipoEntradaByTipoEntrada( + entradas[j].trim(), + false, + ); + const existeEquipoTipoEntrada = tipoEntrada + ? await this.equipoTipoEntradaService.findEquipoTipoEntradaByEquipoTipoEntrada( + equipo, + tipoEntrada, + false, + ) + : null; + + if (!tipoEntrada || existeEquipoTipoEntrada) { + if (!tipoEntrada) + errores.push( + `No se asignó el conector: ${ + entradas[j] + }, al equipo de la linea ${ + index + 2 + } porque no existe este conector.`, + ); + if (existeEquipoTipoEntrada) + errores.push( + `El conector: ${ + entradas[j] + }, ya fue asignado al equipo de la linea ${index + 2}.`, + ); + continue; + } + await this.equipoTipoEntradaService + .create(equipo, tipoEntrada) + .then((res) => { + equipo.tiposEntradas.push(res.equipoTipoEntrada); + mensajes.push(res.message); + }); + } + for (let j = 0; j < programas.length; j++) { + const programa = + await this.institucionProgramaService.findProgramaByPrograma( + programas[j].trim(), + false, + ); + const existeEquipoPrograma = programa + ? await this.equipoProgramaService.findEquipoProgramaByEquipoPrograma( + equipo, + programa, + false, + ) + : null; + + if (!programa || existeEquipoPrograma) { + if (!programa) + errores.push( + `No se asignó el software: ${ + programas[j] + }, al equipo de la linea ${ + index + 2 + } porque no existe este software.`, + ); + if (existeEquipoPrograma) + errores.push( + `El programa: ${ + programas[j] + }, ya lo tiene asignado el equipo de la linea ${index + 2}.`, + ); + continue; + } + await this.equipoProgramaService + .create(equipo, programa) + .then((res) => { + equipo.programas.push(res.equipoPrograma); + mensajes.push(res.message); + }); + } + equiposNuevos.push(equipo); + } + } + async createEquipos(path: string, id_institucion: number) { const institucion = await this.institucionService.findById(id_institucion); - const errores: string[] = []; - const mensajes: string[] = []; - const equiposNuevos: Equipo[] = []; + let errores: string[] = []; + let mensajes: string[] = []; + let equiposNuevos: Equipo[] = []; - return csvtojson() + csvtojson() .fromFile(path) .then(async (equipos: UploadFileCargaMasivaEquipoDto[]) => { for (let i = 0; i < equipos.length; i++) { - let error = this.errorBase(i); - - if ( - !equipos[i].carrito || - !equipos[i].entradas || - !equipos[i].equipo || - !equipos[i].marca || - !equipos[i].modelo || - !equipos[i].modulo || - !equipos[i].numero_inventario || - !equipos[i].numero_serie || - !equipos[i].tipo - ) { - if (!equipos[i].carrito) error += ' falta del campo carrito'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].entradas) error += ' falta del campo entradas'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].equipo) error += ' falta del campo equipo'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].marca) error += ' falta del campo marca'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].modelo) error += ' falta del campo modelo'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].modulo) error += ' falta del campo modulo'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].numero_inventario) - error += ' falta del campo numero_inventario'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].numero_serie) - error += ' falta del campo numero_serie'; - if (error != this.errorBase(i)) error += ','; - if (!equipos[i].tipo) error += ' falta del campo tipo'; - errores.push(error + '.'); - continue; - } - - const tipoCarrito = - await this.institucionTipoCarritoService.findTipoCarritoByTipoCarrito( - equipos[i].tipo, - false, - ); - const modulo = await this.moduloService.findModulo( + await this.evaluarEquipo( institucion, - equipos[i].modulo, - false, + i, + equipos[i], + mensajes, + errores, + equiposNuevos, ); - const marca = await this.marcaService.findByMarca( - equipos[i].marca, - 'e', - false, - ); - const modelo = await this.modeloService.findByModelo( - equipos[i].modelo, - 'e', - false, - ); - const carrito = - tipoCarrito && modulo - ? await this.carritoService.findCarrito( - modulo, - tipoCarrito, - equipos[i].carrito, - false, - ) - : null; - let equipo = carrito - ? await this.equipoService.findEquipoByEquipo( - carrito, - equipos[i].equipo, - false, - ) - : null; - - if (!tipoCarrito || !marca || !modelo || !modulo || !carrito) { - if (!tipoCarrito) error += ' no existe este tipo de carrito.'; - if (!marca) error += ' no existe esta marca.'; - if (!modelo) error += ' no existe este modelo.'; - if (!modulo) error += ' no existe este módulo.'; - if (!carrito) error += ' no existe este carrito.'; - errores.push(error); - continue; - } - - if (equipo) { - errores.push( - `Ya existe un equipo de computo con el sobrenombre: ${equipo.equipo} en el carrito: ${equipo.carrito.carrito}`, - ); - continue; - } else { - equipo = await this.equipoService.findByNumeroInventario( - institucion, - equipos[i].numero_inventario, - false, - ); - if (equipo) { - error += ' ya existe un equipo con ese número de inventario.'; - continue; - } - equipo = await this.equipoService.create( - carrito, - equipos[i].equipo, - equipos[i].numero_inventario, - equipos[i].numero_serie, - marca, - modelo, - ); - - const entradas = equipos[i].entradas.split(','); - const programas = equipos[i].programas - ? equipos[i].programas.split(',') - : []; - - equipo.programas = []; - equipo.tiposEntradas = []; - for (let j = 0; j < entradas.length; j++) { - entradas[j] = entradas[j].trim(); - - const tipoEntrada = - await this.institucionTipoEntradaService.findTipoEntradaByTipoEntrada( - entradas[j], - false, - ); - const existeEquipoTipoEntrada = tipoEntrada - ? await this.equipoTipoEntradaService.findEquipoTipoEntradaByEquipoTipoEntrada( - equipo, - tipoEntrada, - false, - ) - : null; - - if (!tipoEntrada || existeEquipoTipoEntrada) { - if (!tipoEntrada) - errores.push( - `No se asignó la entrada: ${ - entradas[j] - }, al equipo de la linea ${ - i + 2 - } porque no existe ese tipo de entrada.`, - ); - if (tipoEntrada && existeEquipoTipoEntrada) - errores.push( - `La entrada: ${ - entradas[j] - }, ya esta asignada al equipo de la linea ${i + 2}.`, - ); - continue; - } - await this.equipoTipoEntradaService - .create(equipo, tipoEntrada) - .then((res) => { - equipo.tiposEntradas.push(res.equipoTipoEntrada); - mensajes.push(res.message); - }); - } - for (let j = 0; j < programas.length; j++) { - programas[j] = programas[j].trim(); - - const programa = - await this.institucionProgramaService.findProgramaByPrograma( - programas[j], - false, - ); - const existeEquipoPrograma = programa - ? await this.equipoProgramaService.findEquipoProgramaByEquipoPrograma( - equipo, - programa, - false, - ) - : null; - - if (!programa || existeEquipoPrograma) { - if (!programa) - errores.push( - `No se asignó el programa: ${ - programas[j] - }, al equipo de la linea ${ - i + 2 - } porque no existe ese programa.`, - ); - if (programa && existeEquipoPrograma) - errores.push( - `El programa: ${ - programas[j] - }, ya lo tiene asignado el equipo de la linea ${i + 2}.`, - ); - continue; - } - await this.equipoProgramaService - .create(equipo, programa) - .then((res) => { - equipo.programas.push(res.equipoPrograma); - mensajes.push(res.message); - }); - } - equiposNuevos.push(equipo); + if ((i + 1) % 100 === 0) { + this.appGateway.equiposNuevos(institucion.id_institucion, { + errores, + mensajes, + equiposNuevos, + }); + errores = []; + mensajes = []; + equiposNuevos = []; } } - return { - message: 'Se subió y cargó correctamente su archivo csv.', - mensajes, - equiposNuevos, - errores, - }; + fs.unlink(path, (err) => {}); }); + return { message: 'Se subió y cargó correctamente su archivo csv.' }; } async createUsuarios(path: string, id_institucion: number) { diff --git a/src/usuario/usuario.controller.ts b/src/usuario/usuario.controller.ts index 320f3bd..93ff37a 100644 --- a/src/usuario/usuario.controller.ts +++ b/src/usuario/usuario.controller.ts @@ -17,6 +17,7 @@ import { ApiQuery, ApiTags, } from '@nestjs/swagger'; +import { Recaptcha } from '@nestlab/google-recaptcha'; import { Serealize } from '../interceptors/serialize.interceptor'; import { UsuarioService } from './usuario.service'; import { DgaeInputDto } from './dto/input/dgae.dto'; @@ -36,6 +37,7 @@ export class UsuarioController { constructor(private usuarioService: UsuarioService) {} @Serealize(UsuarioInstitucionCarreraOutputDto) + @Recaptcha() @Get('dgae') @ApiOperation({ description: 'Endpoint que retorna información de dgae de un alumno.', @@ -58,6 +60,7 @@ export class UsuarioController { } @Serealize(UsuarioInstitucionCarreraOutputDto) + @Recaptcha() @Get('dgp') @ApiOperation({ description: 'Endpoint que retorna información de dgp de un profesor.', @@ -77,6 +80,7 @@ export class UsuarioController { } @Post('registrar') + @Recaptcha() @ApiOperation({ description: 'Enpoint que realiza el registro de un usuario.', }) diff --git a/src/usuario/usuario.service.ts b/src/usuario/usuario.service.ts index 1c646c0..b2cfad5 100644 --- a/src/usuario/usuario.service.ts +++ b/src/usuario/usuario.service.ts @@ -95,7 +95,6 @@ export class UsuarioService { ); return this.findByUsuario(usuario, true).then(async (existeUsuario) => { - /* Falta conexión a soap */ if (existeUsuario.password) throw new ConflictException('Ya fue regisrado este número de cuenta.'); return this.institucionUsuarioService.findByUsuarioInstitucionCarrera(