Files
Iris_back/src/programa/programa.service.ts
T

262 lines
7.8 KiB
TypeScript
Raw Normal View History

2025-05-20 15:53:57 -06:00
import { Injectable } from '@nestjs/common';
2025-05-29 16:38:26 -06:00
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import * as csv from 'csvtojson';
import * as fs from 'fs';
import * as path from 'path';
import * as moment from 'moment';
import { Programa } from './entities/programa.entity';
import { Usuario } from 'src/usuario/entities/usuario.entity';
import { ValidacionService } from 'src/helpers.services/validacion.service';
import { AuthService } from 'src/auth/auth.service';
import { gmail } from 'src/helpers.services/gmail.service';
import { SendCorreoDto } from 'src/helpers.services/dto/send-email.dto';
2025-05-20 15:53:57 -06:00
@Injectable()
export class ProgramaService {
2025-05-29 16:38:26 -06:00
constructor(
@InjectRepository(Programa)
private programaRepo: Repository<Programa>,
@InjectRepository(Usuario)
private usuarioRepo: Repository<Usuario>,
private validacionService:ValidacionService,
private authService:AuthService,
private gmail:gmail,
) {}
async cargaMasiva(nombreArchivo: string): Promise<{ message: string }> {
const filePath = path.join('server/uploads', nombreArchivo);
const today = moment();
const programas = await csv().fromFile(filePath);
let mensaje = '';
for (let i = 0; i < programas.length; i++) {
const prog = programas[i];
mensaje += `Línea ${i + 2}\n`;
if (!prog.correo || !prog.nombre || !prog.institucion || !prog.dependencia || !prog.programa || !prog.clave) {
mensaje += 'Faltan campos requeridos. Línea omitida.\n\n';
continue;
}
try {
this.validacionService.validarCorreo(prog.correo);
} catch {
mensaje += 'Correo inválido. Línea omitida.\n\n';
continue;
}
const acatlan = prog.clave.substr(4, 7) === '-12/20-';
const activo = Number(prog.clave.substr(0, 4)) === today.year();
let responsable = await this.usuarioRepo.findOne({
where: {
usuario: prog.correo,
tipoUsuario: {
idTipoUsuario:2
}
},
});
if (!responsable) {
const password = await this.authService.encriptar(this.authService.generarPassword());
const correoInfo = enviarSec(password, prog.correo, prog.nombre);
responsable = await this.usuarioRepo.create({
usuario: prog.correo,
password: password,
nombre: prog.nombre,
activo: true,
tipoUsuario:{
idTipoUsuario: 2
},
});
const sendCorreoDto: SendCorreoDto = {
to: prog.correo,
subject: correoInfo.subject,
fecha_recibido: new Date(),
text: correoInfo.msj,
html: '',
adjuntos: undefined
};
if (!process.env.TOKEN_GMAIL) {
throw new Error('No existe el token');
}
try {
responsable = await this.usuarioRepo.save(responsable);
await this.gmail.send(sendCorreoDto, process.env.TOKEN_GMAIL);
mensaje += `Responsable creado con ID ${responsable.idUsuario} y correo ${responsable.usuario}\n`;
} catch (err) {
mensaje += `Error creando responsable: ${err.message}\n`;
continue;
}
}
if (!acatlan) {
const existente = await this.programaRepo.findOne({
where: { clavePrograma: prog.clave },
relations: ['usuario'],
});
if (!existente) {
try {
const nuevoPrograma = this.programaRepo.create({
institucion: prog.institucion,
dependencia: prog.dependencia,
programa: prog.programa,
clavePrograma: prog.clave,
activo,
usuario:{
idUsuario:responsable.idUsuario
}
});
const creado = await this.programaRepo.save(nuevoPrograma);
mensaje += `Programa ${creado.clavePrograma} asignado al usuario ${responsable.usuario}\n`;
} catch (err) {
mensaje += `Error creando programa: ${err.message}\n`;
}
} else {
mensaje += `Programa ya existe con clave ${existente.clavePrograma}. `;
if (existente.usuario?.usuario === prog.correo) {
mensaje += 'Ya pertenece a este responsable.\n';
} else {
mensaje += `Asignado a otro responsable: ${existente.usuario.usuario}\n`;
}
}
} else {
const existente = await this.programaRepo.findOne({
where: {
clavePrograma: prog.clave,
usuario:{
idUsuario: responsable.idUsuario
},
},
});
if (!existente) {
try {
const nuevoPrograma = this.programaRepo.create({
institucion: 'UNAM',
dependencia: 'FES ACATLAN',
programa: prog.programa,
clavePrograma: prog.clave,
activo,
acatlan,
usuario:{
idUsuario: responsable.idUsuario
},
});
const creado = await this.programaRepo.save(nuevoPrograma);
mensaje += `Programa ACATLÁN ${creado.clavePrograma} asignado a ${responsable.usuario}\n`;
} catch (err) {
mensaje += `Error creando programa: ${err.message}\n`;
}
} else {
mensaje += `Programa ACATLÁN ya pertenece a ${responsable.usuario}\n`;
}
}
2025-05-20 15:53:57 -06:00
2025-05-29 16:38:26 -06:00
mensaje += '\n';
}
fs.unlinkSync(filePath);
return {
message: 'Se subió correctamente el archivo CSV para la carga masiva.',
};
2025-05-20 15:53:57 -06:00
}
2025-05-29 16:38:26 -06:00
async programasAdmin(body: { idUsuario: number }) {
const idUsuario = this.validacionService.validarNumeroEntero(body.idUsuario, 'id usuario');
const usuario = await this.usuarioRepo.findOne({
where: { idUsuario },
});
if (!usuario) {
throw new Error('No existe este usuario.');
}
if (usuario.tipoUsuario.idTipoUsuario !== 2) {
throw new Error('No es un usuario de tipo responsable');
}
return this.programaRepo.find({
where: { usuario:{idUsuario} },
});
2025-05-20 15:53:57 -06:00
}
2025-05-29 16:38:26 -06:00
async programasResponsable(body: { idUsuario: number }) {
const idUsuario = this.validacionService.validarNumeroEntero(body.idUsuario, 'id usuario');
const usuario = await this.usuarioRepo.findOne({
where: { idUsuario },
});
if (!usuario) {
throw new Error('No existe este usuario.');
}
if (usuario.tipoUsuario.idTipoUsuario !== 2) {
throw new Error('No es un usuario de tipo responsable');
}
return this.programaRepo.find({
where: {
usuario:{idUsuario},
activo: true,
},
});
2025-05-20 15:53:57 -06:00
}
2025-05-29 16:38:26 -06:00
async reasignarProgramas(idUsuario:number,correoOtroResponsable:string){
const idusuario= this.validacionService.validarNumeroEntero(idUsuario,'id usuario')
const otroResponsable = this.validacionService.validarCorreo(
correoOtroResponsable
);
2025-05-30 14:37:44 -06:00
let usuarioNuevo= await this.usuarioRepo.findOne({where:{idUsuario:idusuario}})
2025-05-29 16:38:26 -06:00
2025-05-30 14:37:44 -06:00
if (!usuarioNuevo) throw new Error('No existe este usuario.');
if (usuarioNuevo.tipoUsuario.idTipoUsuario != 2) throw new Error('No es un usuario de tipo responsable');
if (usuarioNuevo.usuario === correoOtroResponsable) throw new Error('Son el mismo usuario.');
2025-05-29 16:38:26 -06:00
2025-05-30 14:37:44 -06:00
let viejoResponsable=await this.usuarioRepo.findOne({where:{usuario:otroResponsable}})
2025-05-29 16:38:26 -06:00
2025-05-30 14:37:44 -06:00
if (!viejoResponsable) throw new Error('No existe este usuario.');
2025-05-29 16:38:26 -06:00
2025-05-30 14:37:44 -06:00
await this.programaRepo.update(
{ usuario:viejoResponsable },
{ usuario:usuarioNuevo }
2025-05-29 16:38:26 -06:00
);
2025-05-30 14:37:44 -06:00
// Eliminar usuario antiguo
await this.usuarioRepo.delete({idUsuario:viejoResponsable.idUsuario});
2025-05-29 16:38:26 -06:00
2025-05-30 14:37:44 -06:00
2025-05-29 16:38:26 -06:00
2025-05-30 14:37:44 -06:00
return {
message: `Se eliminó correctamente al usuario ${correoOtroResponsable} y se reasignaron sus programas.`,
}
}
2025-05-20 15:53:57 -06:00
}