diff --git a/src/institucion/institucion.service.ts b/src/institucion/institucion.service.ts index 443422f..e77d324 100644 --- a/src/institucion/institucion.service.ts +++ b/src/institucion/institucion.service.ts @@ -24,7 +24,10 @@ export class InstitucionService { findById(id_institucion: number): Promise { return this.repository - .findOne({ select: ['id_institucion'], where: { id_institucion } }) + .findOne({ + select: ['id_institucion', 'logo'], + where: { id_institucion }, + }) .then((institucion) => { if (!institucion) throw new NotFoundException('No existe este id institución.'); @@ -71,6 +74,10 @@ export class InstitucionService { }); } + save(institucion: Institucion): Promise { + return this.repository.save(institucion); + } + update( admin: Operador, attrs: Partial, diff --git a/src/upload-file/upload-file.controller.ts b/src/upload-file/upload-file.controller.ts index 7d9eec0..6622c89 100644 --- a/src/upload-file/upload-file.controller.ts +++ b/src/upload-file/upload-file.controller.ts @@ -1,3 +1,4 @@ +import * as multer from 'multer'; import { BadRequestException, Controller, @@ -47,10 +48,7 @@ export class UploadFileController { this.validarUsuarioService.validarAdmin(admin); if (!file) throw new BadRequestException('No se mandó ningún archivo.'); - return this.uploadFileService.createEquipos( - path, - admin.institucion.id_institucion, - ); + return this.uploadFileService.createEquipos(path, admin); } @Serealize(MessageOutputDto) @@ -74,10 +72,7 @@ export class UploadFileController { this.validarUsuarioService.validarAdmin(admin); if (!file) throw new BadRequestException('No se mandó ningún archivo.'); - return this.uploadFileService.createUsuarios( - path, - admin.institucion.id_institucion, - ); + return this.uploadFileService.createUsuarios(path, admin); } @Get('download-logo') @@ -87,15 +82,32 @@ export class UploadFileController { const operador: Operador = req.user.operador; this.validarUsuarioService.validarAdminOperador(operador); - // return this.uploadFileService - // .downloadLogo(parseInt(query.id_institucion)) - // .then((logo) => res.download(logo)); + return this.uploadFileService.downloadLogo(operador).then((logo) => { + if (logo) res.download(logo); + else return false; + }); } @Serealize(MessageOutputDto) @Post('upload-logo') @UseGuards(AuthGuard('jwt')) - @UseInterceptors(FileInterceptor('logo')) + @UseInterceptors( + FileInterceptor('logo', { + storage: multer.diskStorage({ + destination: './upload', + filename: (req: any, file, cb) => { + cb( + null, + `${ + req.user.operador.institucion.id_institucion + }${Date.now()}${Math.round( + Math.random() * 1e9, + )}${file.originalname.slice(-4)}`, + ); + }, + }), + }), + ) @ApiBearerAuth('jwt') @ApiConsumes('multipart/form-data') @ApiBody({ @@ -108,9 +120,7 @@ export class UploadFileController { const admin: Operador = req.user.operador; this.validarUsuarioService.validarAdmin(admin); - return this.uploadFileService.uploadLogo( - file, - admin.institucion.id_institucion, - ); + if (!file) throw new BadRequestException('No se mandó ningún archivo.'); + return this.uploadFileService.uploadLogo(file, admin); } } diff --git a/src/upload-file/upload-file.service.ts b/src/upload-file/upload-file.service.ts index b7444b0..de1001f 100644 --- a/src/upload-file/upload-file.service.ts +++ b/src/upload-file/upload-file.service.ts @@ -1,10 +1,11 @@ import * as fs from 'fs'; import * as csvtojson from 'csvtojson'; -import { BadRequestException, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { AppGateway } from '../app.gateway'; import { Equipo } from '../equipo/entity/equipo.entity'; import { Institucion } from '../institucion/entity/institucion.entity'; import { InstitucionUsuario } from '../institucion-usuario/entity/institucion-usuario.entity'; +import { Operador } from '../operador/entity/operador.entity'; import { CarritoService } from '../carrito/carrito.service'; import { EquipoService } from '../equipo/equipo.service'; import { EquipoProgramaService } from '../equipo-programa/equipo-programa.service'; @@ -44,10 +45,8 @@ export class UploadFileService { private usuarioService: UsuarioService, ) {} - async createEquipos(path: string, id_institucion: number) { - const institucion = await this.institucionService.findById(id_institucion); + createEquipos(path: string, admin: Operador): { message: string } { let errores: string[] = []; - let mensajes: string[] = []; let equiposNuevos: Equipo[] = []; csvtojson() @@ -55,21 +54,18 @@ export class UploadFileService { .then(async (equipos: UploadFileCargaMasivaEquipoDto[]) => { for (let i = 0; i < equipos.length; i++) { await this.evaluarEquipo( - institucion, + admin.institucion, i, equipos[i], - mensajes, errores, equiposNuevos, ); if ((i + 1) % 90 === 0 || i + 1 === equipos.length) { - this.appGateway.equiposNuevos(institucion.id_institucion, { + this.appGateway.equiposNuevos(admin.institucion.id_institucion, { errores, - mensajes, equiposNuevos, }); errores = []; - mensajes = []; equiposNuevos = []; } } @@ -78,8 +74,7 @@ export class UploadFileService { return { message: 'Se subió y cargó correctamente su archivo csv.' }; } - async createUsuarios(path: string, id_institucion: number) { - const institucion = await this.institucionService.findById(id_institucion); + createUsuarios(path: string, admin: Operador): { message: string } { let errores: string[] = []; let mensajes: string[] = []; let usuariosNuevos: InstitucionUsuario[] = []; @@ -89,7 +84,7 @@ export class UploadFileService { .then(async (usuarios: UploadFileCargaMasivaUsuarioDto[]) => { for (let i = 0; i < usuarios.length; i++) { await this.evaluarUsuario( - institucion, + admin.institucion, i, usuarios[i], mensajes, @@ -97,7 +92,7 @@ export class UploadFileService { usuariosNuevos, ); if ((i + 1) % 100 === 0 || i + 1 === usuarios.length) { - this.appGateway.usuariosNuevos(institucion.id_institucion, { + this.appGateway.usuariosNuevos(admin.institucion.id_institucion, { errores, mensajes, usuariosNuevos, @@ -111,13 +106,13 @@ export class UploadFileService { return { message: 'Se subió y cargó correctamente tu archivo csv.' }; } - downloadLogo(id_institucion: number) { - // return this.institucionService - // .findById(id_institucion) - // .then((institucion) => institucion.logo); + downloadLogo(operador: Operador): Promise { + return this.institucionService + .findById(operador.institucion.id_institucion) + .then((institucion) => institucion.logo); } - errorBase(index) { + errorBase(index): string { return `Se saltó la linea ${ index + 2 } por el siguiente/los siguientes motivo(s):`; @@ -127,13 +122,13 @@ export class UploadFileService { institucion: Institucion, index: number, dataEquipo: UploadFileCargaMasivaEquipoDto, - mensajes: string[], errores: string[], equiposNuevos: Equipo[], ) { const errorAux = this.errorBase(index); let error = errorAux; + // Si falta agluno de estos campos sacamos error if ( !dataEquipo.carrito || !dataEquipo.entradas || @@ -145,41 +140,49 @@ export class UploadFileService { !dataEquipo.numero_serie || !dataEquipo.tipo ) { + // Si falta campo carrito, agregamos error a la variable error if (!dataEquipo.carrito) error += ' falta del campo carrito'; + // Si falta campo entradas, agregamos error a la variable error if (!dataEquipo.entradas) { if (error != errorAux) error += ','; error += ' falta del campo entradas'; } + // Si falta campo equipo, agregamos error a la variable error if (!dataEquipo.equipo) { if (error != errorAux) error += ','; error += ' falta del campo equipo'; } + // Si falta campo marca, agregamos error a la variable error if (!dataEquipo.marca) { if (error != errorAux) error += ','; error += ' falta del campo marca'; } + // Si falta campo modelo, agregamos error a la variable error if (!dataEquipo.modelo) { if (error != errorAux) error += ','; error += ' falta del campo modelo'; } + // Si falta campo modulo , agregamos error a la variable error if (!dataEquipo.modulo) { if (error != errorAux) error += ','; error += ' falta del campo modulo'; } + // Si falta campo numero_inventario, agregamos error a la variable error if (!dataEquipo.numero_inventario) { if (error != errorAux) error += ','; error += ' falta del campo numero_inventario'; } + // Si falta campo numero_serie, agregamos error a la variable error if (!dataEquipo.numero_serie) { if (error != errorAux) error += ','; error += ' falta del campo numero_serie'; } + // Si falta campo tipo, agregamos error a la variable error if (!dataEquipo.tipo) { if (error != errorAux) error += ','; error += ' falta del campo tipo'; } - errores.push(error + '.'); - return; + return errores.push(error + '.'); // Agregamos error al array de errores } const tipoCarrito = @@ -203,137 +206,157 @@ export class UploadFileService { dataEquipo.carrito, ) : null; - let equipo = carrito - ? await this.equipoService.findByEquipo(carrito, dataEquipo.equipo, false) - : null; + // Validamos que exista la información mandada del client en la db, si no sacamos error if (!tipoCarrito || !marca || !modelo || !modulo || !carrito) { + // Validamos que existe el tipo de carrito if (!tipoCarrito) error += ' no existe este tipo de carrito'; + // Validamos que existe la marca if (!marca) { if (error != errorAux) error += ','; error += ' no existe esta marca'; } + // Validamos que existe el modelo if (!modelo) { if (error != errorAux) error += ','; error += ' no existe este modelo'; } + // Validamos que existe el módulo if (!modulo) { if (error != errorAux) error += ','; error += ' no existe este módulo'; } + // Validamos que existe el carrito if (!carrito) { if (error != errorAux) error += ','; error += ' no existe este carrito'; } - errores.push(error + '.'); - return; + return errores.push(error + '.'); // Agregamos el error al array de errores } - if (equipo) { - errores.push( + // Buscamos un equipo con el sobrenombre enviado del client en el carrito seleccionado + let equipo = carrito + ? await this.equipoService.findByEquipo(carrito, dataEquipo.equipo, false) + : null; + + // Si existe uno sacamos error + if (equipo) + return 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, + // Buscamos un equipo con el numero_inventario enviado del client en la institución del admin + equipo = await this.equipoService.findByNumeroInventario( + institucion, + dataEquipo.numero_inventario, + false, + ); + // Si existe uno saca error + if (equipo) + return errores.push( + `${error} ya existe un equipo con ese número de inventario en esta institución.`, ); - if (equipo) { - errores.push( - `${error} ya existe un equipo con ese número de inventario en esta institución.`, - ); - return; - } - await this.equipoService - .create( - dataEquipo.equipo, - carrito, - dataEquipo.numero_inventario, - dataEquipo.numero_serie, - marca, - modelo, - ) - .then(async (equipo) => { - const entradas = dataEquipo.entradas.split(','); - const programas = dataEquipo.programas - ? dataEquipo.programas.split(',') - : []; + // Creamos y guardamos un registro + await this.equipoService + .create( + dataEquipo.equipo, + carrito, + dataEquipo.numero_inventario, + dataEquipo.numero_serie, + marca, + modelo, + ) + .then(async (equipoNuevo) => { + 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(), - ); - const existeEquipoTipoEntrada = tipoEntrada - ? await this.equipoTipoEntradaService.findByEquipoTipoEntrada( - equipo, - tipoEntrada, - ) - : null; + // Inicializamos los arrays + equipoNuevo.programas = []; + equipoNuevo.tiposEntradas = []; + // Recorremos el array de entradas + for (let j = 0; j < entradas.length; j++) { + const tipoEntrada = + await this.institucionTipoEntradaService.findTipoEntradaByTipoEntrada( + entradas[j].trim(), + ); + const existeEquipoTipoEntrada = tipoEntrada + ? await this.equipoTipoEntradaService.findByEquipoTipoEntrada( + equipoNuevo, + tipoEntrada, + ) + : 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((equipoTipoEntrada) => - equipo.tiposEntradas.push(equipoTipoEntrada), + if (!tipoEntrada || existeEquipoTipoEntrada) { + // Validamos que exista el tipo de entrada que se quiere asignar al equipo + if (!tipoEntrada) + errores.push( + `No se asignó el conector: ${ + entradas[j] + }, al equipo de la linea ${ + index + 2 + } porque no existe este conector.`, ); + // Validamos que el tipo de entrada no este ya asignado al equipo + if (existeEquipoTipoEntrada) + errores.push( + `El conector: ${ + entradas[j] + }, ya fue asignado al equipo de la linea ${index + 2}.`, + ); + // Nos saltamos esta entrada + continue; } - for (let j = 0; j < programas.length; j++) { - const programa = - await this.institucionProgramaService.findProgramaByPrograma( - programas[j].trim(), - ); - const existeEquipoPrograma = programa - ? await this.equipoProgramaService.findByEquipoPrograma( - equipo, - programa, - ) - : null; + // Asignamos el tipo de entrada al equipo + await this.equipoTipoEntradaService + .create(equipoNuevo, tipoEntrada) + .then((equipoTipoEntrada) => + equipoNuevo.tiposEntradas.push(equipoTipoEntrada), + ); + } + // Recorremos el array de programas + for (let j = 0; j < programas.length; j++) { + const programa = + await this.institucionProgramaService.findProgramaByPrograma( + programas[j].trim(), + ); + const existeEquipoPrograma = programa + ? await this.equipoProgramaService.findByEquipoPrograma( + equipoNuevo, + programa, + ) + : 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((equipoPrograma) => equipo.programas.push(equipoPrograma)); + if (!programa || existeEquipoPrograma) { + // Validamos que exista el programa que se quiere asignar al equipo + if (!programa) + errores.push( + `No se asignó el software: ${ + programas[j] + }, al equipo de la linea ${ + index + 2 + } porque no existe este software.`, + ); + // Validamos que el programa no este ya asignado al equipo + if (existeEquipoPrograma) + errores.push( + `El programa: ${ + programas[j] + }, ya lo tiene asignado el equipo de la linea ${index + 2}.`, + ); + // Nos saltamos este programa + continue; } - equiposNuevos.push(equipo); - }); - } + // Asignamos el programa al equipo + await this.equipoProgramaService + .create(equipoNuevo, programa) + .then((equipoPrograma) => + equipoNuevo.programas.push(equipoPrograma), + ); + } + // Agregamos el equipo nuevo al array de equipos nuevos + equiposNuevos.push(equipoNuevo); + }); } async evaluarUsuario( @@ -347,14 +370,16 @@ export class UploadFileService { const errorAux = this.errorBase(index); let error = errorAux; + // Si falta agluno de estos campos sacamos error if (!dataUsuario.numero_cuenta || !dataUsuario.tipo_usuario) { + // Si falta campo numero_cuenta, agregamos error a la variable error if (!dataUsuario.numero_cuenta) error += ' falta del campo numero_cuenta'; + // Si falta campo tipo_usuario, agregamos error a la variable error if (!dataUsuario.tipo_usuario) { if (error != errorAux) error += ','; error += ' falta del campo tipo_usuario'; } - errores.push(`${error}.`); - return; + return errores.push(`${error}.`); } const tipoUsuario = await this.tipoUsuarioService.findByTipoUsuario( @@ -379,22 +404,27 @@ export class UploadFileService { ) : null; + // Validamos que exista la información mandada del client en la db, si no sacamos error if ( !tipoUsuario || tipoUsuario.id_tipo_usuario < 5 || !carrera || (carrera && !institucionCarrera) ) { + // Validamos que existe el tipo de usuario if (!tipoUsuario) error += ' no existe este tipo de usuario.'; + // Validamos que el id tipo usuario no sea menor a 5 else if (tipoUsuario.id_tipo_usuario < 5) ' no se puede asignar este tipo de usuario a este usuario.'; + // Validamos que existe la carrera if (!carrera) error += ' falta del campo carrera para el alumno.'; - if (carrera && !institucionCarrera) - error += ' la carrera no pertenece a la institución.'; - errores.push(error); - return; + // Validamos que la carrera enviada del client pertenezca a la institución del admin + else if (!institucionCarrera) + error += ' la carrera no pertenece a tu institución.'; + return errores.push(error); } + // Solución a error de encriptación de caracteres en nombres let nombre = `${dataUsuario.apellido_p.trim()} ${dataUsuario.apellido_m.trim()} ${dataUsuario.nombres.trim()}`; while (nombre.search('√ë') != -1) { @@ -403,17 +433,30 @@ export class UploadFileService { while (nombre.search('√É∆í√¢‚ǨÀú') != -1) { nombre = nombre.replace('√É∆í√¢‚ǨÀú', 'Ñ'); } + // Si ya existe el usuario if (usuario) { + // Buscamos si el usuario ya tiene asignada la carrera let existeInstitucionUsuario = await this.institucionUsuarioService.findByIdUsuarioIdInstitucionCarrera( usuario, institucionCarrera, ); + // Si si ya la tiene asignada y no esta activa if (existeInstitucionUsuario && !existeInstitucionUsuario.activo) { + // La activamos existeInstitucionUsuario.activo = true; - await this.institucionUsuarioService.save(existeInstitucionUsuario); - } else if (!existeInstitucionUsuario) + await this.institucionUsuarioService + .save(existeInstitucionUsuario) + .then((institucionUsuario) => + mensajes.push( + `Se activo la carrera: ${institucionUsuario.institucionCarrera.carrera.carrera} del usuario: ${institucionUsuario.usuario.usuario}.`, + ), + ); + } + // Si no la tiene asignada + else if (!existeInstitucionUsuario) + // Se la asignamos await this.institucionUsuarioService .create(institucionCarrera, usuario) .then((institucionUsuario) => @@ -421,21 +464,33 @@ export class UploadFileService { `Se asignó la carrera: ${institucionUsuario.institucionCarrera.carrera.carrera} al usuario: ${institucionUsuario.usuario.usuario}.`, ), ); + // Si el nombre, tipo de usuario o correo enviado es distinto al que se tiene en la db se actualiza if ( usuario.nombre != nombre || usuario.tipoUsuario.id_tipo_usuario != tipoUsuario.id_tipo_usuario || (dataUsuario.correo && usuario.correo != dataUsuario.correo) ) { + // Si el id tipo usuario es distinto al que se tiene en base se actualiza if (usuario.tipoUsuario.id_tipo_usuario != tipoUsuario.id_tipo_usuario) usuario.tipoUsuario = tipoUsuario; + // Si el nombre es distinto al que se tiene en base se actualiza if (usuario.nombre != nombre) usuario.nombre = nombre; + // Si se mando correo y el correo es distinto al que se tiene en base se actualiza if (dataUsuario.correo && usuario.correo != dataUsuario.correo) usuario.correo = dataUsuario.correo; + // Guardamos cambios de usuario await this.usuarioService .save(usuario) - .then(({ message }) => mensajes.push(message)); + .then((_) => + mensajes.push( + `Se actualizaron los datos de usuario: ${usuario.usuario}`, + ), + ); } - } else { + } + // Si no existe el usuario + else { + // Si falta agluno de estos campos sacamos error if ( !dataUsuario.nombres || !dataUsuario.apellido_m || @@ -443,27 +498,32 @@ export class UploadFileService { !dataUsuario.correo || (tipoUsuario.id_tipo_usuario === 5 && !dataUsuario.rfc) ) { + // Si falta campo rfc y el tipo de usuario es profesor, agregamos error a la variable error if (tipoUsuario.id_tipo_usuario === 5 && !dataUsuario.rfc) error += ' falta del campo rfc'; + // Si falta campo nombres, agregamos error a la variable error if (!dataUsuario.nombres) { if (error != errorAux) error += ','; error += ' falta del campo nombres'; } + // Si falta campo apellido_m, agregamos error a la variable error if (!dataUsuario.apellido_m) { if (error != errorAux) error += ','; error += ' falta del campo apellido_m'; } + // Si falta campo apellido_p, agregamos error a la variable error if (!dataUsuario.apellido_p) { if (error != errorAux) error += ','; error += ' falta del campo apellido_p'; } + // Si falta campo correo, agregamos error a la variable error if (!dataUsuario.correo) { if (error != errorAux) error += ','; error += ' falta del campo correo'; } - errores.push(`${error}.`); - return; + return errores.push(`${error}.`); // Agregamos error al array de errores } + // Creamos un usuario y le asignamos la carrera enviada await this.usuarioService .create( dataUsuario.numero_cuenta, @@ -473,23 +533,25 @@ export class UploadFileService { dataUsuario.correo, dataUsuario.rfc ? dataUsuario.rfc : '', ) - .then((institucionUsuario) => { - usuariosNuevos.push(institucionUsuario); - mensajes.push( - `Se asignó la carrera: ${institucionUsuario.institucionCarrera.carrera.carrera} al usuario: ${institucionUsuario.usuario.usuario}.`, - ); - }); + .then((institucionUsuario) => usuariosNuevos.push(institucionUsuario)); } } - async uploadLogo(file: Express.Multer.File, id_institucion: number) { - const path = file ? `${file.destination}/${file.filename}` : null; - const institucion = await this.institucionService.findById(id_institucion); - - if (!file) throw new BadRequestException('No se mandó ningún logo.'); - institucion.logo = path; - // return this.institucionService - // .update(institucion) - // .then((_) => ({ message: 'Se subió correctamente el logo.' })); + uploadLogo( + file: Express.Multer.File, + admin: Operador, + ): Promise<{ message: string }> { + return this.institucionService + .findById(admin.institucion.id_institucion) + .then((institucion) => { + // Si ya hay registro de un logo eliminamos el archivo + if (institucion.logo) fs.unlink(institucion.logo, (err) => {}); + // Guardamos la nueva ubicación del logo + institucion.logo = `${file.destination}/${file.filename}`; + // Guardamos los cambios + return this.institucionService + .save(institucion) + .then((_) => ({ message: 'Se subió correctamente el logo.' })); + }); } } diff --git a/src/usuario/usuario.service.ts b/src/usuario/usuario.service.ts index d2a69a0..ac2ad9d 100644 --- a/src/usuario/usuario.service.ts +++ b/src/usuario/usuario.service.ts @@ -272,10 +272,8 @@ export class UsuarioService { .then((_) => ({ message })); } - save(usuario: Usuario): Promise<{ message: string }> { - return this.repository - .save(usuario) - .then((_) => ({ message: 'Se guardaron los cambios correctamente.' })); + save(usuario: Usuario): Promise { + return this.repository.save(usuario); } update(