import * as csvtojson from 'csvtojson'; import { BadRequestException, Injectable } from '@nestjs/common'; import { Equipo } from '../equipo/entity/equipo.entity'; import { InstitucionUsuario } from '../institucion-usuario/entity/institucion-usuario.entity'; import { CarritoService } from '../carrito/carrito.service'; import { EquipoService } from '../equipo/equipo.service'; import { EquipoProgramaService } from '../equipo-programa/equipo-programa.service'; import { EquipoTipoEntradaService } from '../equipo-tipo-entrada/equipo-tipo-entrada.service'; import { InstitucionService } from '../institucion/institucion.service'; import { InstitucionCarreraService } from '../institucion-carrera/institucion-carrera.service'; import { InstitucionProgramaService } from '../institucion-programa/institucion-programa.service'; import { InstitucionTipoCarritoService } from '../institucion-tipo-carrito/institucion-tipo-carrito.service'; import { InstitucionTipoEntradaService } from '../institucion-tipo-entrada/institucion-tipo-entrada.service'; import { InstitucionUsuarioService } from '../institucion-usuario/institucion-usuario.service'; import { ModuloService } from '../modulo/modulo.service'; 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'; @Injectable() export class UploadFileService { constructor( private carritoService: CarritoService, private equipoService: EquipoService, private equipoProgramaService: EquipoProgramaService, private equipoTipoEntradaService: EquipoTipoEntradaService, private institucionService: InstitucionService, private institucionCarreraService: InstitucionCarreraService, private institucionProgramaService: InstitucionProgramaService, private institucionTipoCarritoService: InstitucionTipoCarritoService, private institucionTipoEntradaService: InstitucionTipoEntradaService, private institucionUsuarioService: InstitucionUsuarioService, private moduloService: ModuloService, private tipoUsuarioService: TipoUsuarioService, private usuarioService: UsuarioService, ) {} async createEquipos(path: string, id_institucion: number) { const institucion = await this.institucionService.findById(id_institucion); const errores: string[] = []; const mensajes: string[] = []; const equiposNuevos: Equipo[] = []; return 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( institucion, equipos[i].modulo, 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 || !modulo || !carrito) { if (!tipoCarrito) error += ' no existe este tipo de carrito.'; 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, equipos[i].marca, equipos[i].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.existeEquipoTipoEntrada( 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.existeEquipoPrograma( 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 .eliminarEquipoSinPrograma(equipo) .then((_) => this.equipoProgramaService.create(equipo, programa), ) .then((res) => { equipo.programas.push(res.equipoPrograma); mensajes.push(res.message); }); } equiposNuevos.push(equipo); } } return { message: 'Se subió y cargó correctamente tu archivo csv.', mensajes, equiposNuevos, errores, }; }); } async createUsuarios(path: string, id_institucion: number) { const institucion = await this.institucionService.findById(id_institucion); const errores: string[] = []; const mensajes: string[] = []; const usuariosActualizados: InstitucionUsuario[] = []; const usuariosNuevos: InstitucionUsuario[] = []; return csvtojson() .fromFile(path) .then(async (usuarios: UploadFileCargaMasivaUsuarioDto[]) => { for (let i = 0; i < usuarios.length; i++) { let error = this.errorBase(i); if (!usuarios[i].numero_cuenta || !usuarios[i].tipo_usuario) { if (!usuarios[i].numero_cuenta) error += ' falta del campo numero_cuenta'; if (error != this.errorBase(i)) error += ','; if (!usuarios[i].tipo_usuario) error += ' falta del campo tipo_usuario'; errores.push(`${error}.`); continue; } const tipoUsuario = await this.tipoUsuarioService.findByTipoUsuario( usuarios[i].tipo_usuario, false, ); const usuario = await this.usuarioService.findByUsuario( usuarios[i].numero_cuenta, false, ); const carrera = tipoUsuario && (tipoUsuario.id_tipo_usuario === 5 || usuarios[i].carrera) ? await this.institucionCarreraService.findCarreraByCarrera( tipoUsuario.id_tipo_usuario === 5 ? 'PROFESOR' : usuarios[i].carrera, false, ) : null; const institucionCarrera = carrera ? await this.institucionCarreraService.findByIdInstitucionIdCarrera( institucion, carrera, ) : null; if ( !tipoUsuario || tipoUsuario.id_tipo_usuario < 5 || !carrera || (carrera && !institucionCarrera) ) { if (!tipoUsuario) error += ' no existe este tipo de usuario.'; if (tipoUsuario.id_tipo_usuario < 5) ' no se puede asignar este tipo de usuario a este usuario.'; 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); continue; } if (usuario) { let existeInstitucionUsuario: InstitucionUsuario = null; for (let i = 0; i < usuario.instituciones.length; i++) if ( usuario.instituciones[i].institucionCarrera .id_institucion_carrera === institucionCarrera.id_institucion_carrera ) { existeInstitucionUsuario = usuario.instituciones[i]; break; } if (existeInstitucionUsuario && !existeInstitucionUsuario.activo) { existeInstitucionUsuario.activo = true; await this.institucionUsuarioService.update( existeInstitucionUsuario, ); } else if (!existeInstitucionUsuario) await this.institucionUsuarioService .create(institucionCarrera, usuario) .then(({ message, institucionUsuario }) => { usuariosActualizados.push(institucionUsuario); mensajes.push(message); }); if ( usuario.tipoUsuario.id_tipo_usuario != tipoUsuario.id_tipo_usuario ) { usuario.tipoUsuario = tipoUsuario; await this.usuarioService .update(usuario, false) .then(({ message }) => mensajes.push(message)); } } else { if ( !usuarios[i].nombres || !usuarios[i].apellido_m || !usuarios[i].apellido_p ) { if (error != this.errorBase(i)) error += ','; if (!usuarios[i].nombres) error += ' falta del campo nombres'; if (error != this.errorBase(i)) error += ','; if (!usuarios[i].apellido_m) error += ' falta del campo apellido_m'; if (error != this.errorBase(i)) error += ','; if (!usuarios[i].apellido_p) error += ' falta del campo apellido_p'; errores.push(`${error}.`); continue; } await this.usuarioService .create( usuarios[i].numero_cuenta, `${usuarios[i].apellido_p.trim()} ${usuarios[ i ].apellido_m.trim()} ${usuarios[i].nombres.trim()}`, tipoUsuario, institucionCarrera, ) .then(({ message, institucionUsuario }) => { usuariosNuevos.push(institucionUsuario); mensajes.push(message); }); } } return { message: 'Se subió y cargó correctamente tu archivo csv.', mensajes, usuariosNuevos, errores, }; }); } downloadLogo(id_institucion: number) { return this.institucionService .findById(id_institucion) .then((institucion) => institucion.logo); } errorBase(index) { return `Se saltó la linea ${ index + 2 } por el siguiente/los siguientes motivo(s):`; } 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.' })); } }