pcpuma_unam_api/src/usuario/usuario.service.ts
2022-10-16 11:53:07 -05:00

294 lines
9.8 KiB
TypeScript

import {
ConflictException,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { InstitucionCarrera } from '../institucion-carrera/entity/institucion-carrera.entity';
import { TipoUsuario } from '../tipo-usuario/entity/tipo-usuario.entity';
import { Usuario } from './entity/usuario.entity';
import { InformacionUsuarioView } from './entity/views/informacion-usuario.view';
import { BcryptService } from '../bcrypt/bcrypt.service';
import { InstitucionService } from '../institucion/institucion.service';
import { InstitucionCarreraService } from '../institucion-carrera/institucion-carrera.service';
import { InstitucionUsuarioService } from '../institucion-usuario/institucion-usuario.service';
import { NodemailerService } from '../nodemailer/nodemailer.service';
import { TipoUsuarioService } from '../tipo-usuario/tipo-usuario.service';
@Injectable()
export class UsuarioService {
constructor(
@InjectRepository(Usuario) private repository: Repository<Usuario>,
@InjectRepository(InformacionUsuarioView)
private informacionUsuarioView: Repository<InformacionUsuarioView>,
private bcryptService: BcryptService,
private institucionService: InstitucionService,
private institucionCarreraService: InstitucionCarreraService,
private institucionUsuarioService: InstitucionUsuarioService,
private nodemailerService: NodemailerService,
private tipoUsuarioService: TipoUsuarioService,
) {}
async create(
usuario: string,
nombre: string,
tipoUsuario: TipoUsuario,
institucionCarrera: InstitucionCarrera,
correo: string,
rfc?: string,
) {
return this.repository
.save(
this.repository.create({
nombre,
tipoUsuario,
usuario,
correo,
rfc: rfc ? rfc : '',
}),
)
.then((usuario) =>
this.institucionUsuarioService.create(institucionCarrera, usuario),
);
}
async findAll(filtros: {
pagina: string;
activo?: string;
id_carrera?: string;
id_institucion?: string;
id_tipo_usuario?: string;
nombre?: string;
password?: string;
usuario?: string;
}) {
const carrera = filtros.id_carrera
? await this.institucionCarreraService.findCarreraByIdCarrera(
parseInt(filtros.id_carrera),
)
: null;
const institucion = filtros.id_institucion
? await this.institucionService.findInfoInstitucionById(
parseInt(filtros.id_institucion),
)
: null;
const tipoUsuario = filtros.id_tipo_usuario
? await this.tipoUsuarioService.findById(
parseInt(filtros.id_tipo_usuario),
)
: null;
const query = this.repository
.createQueryBuilder('u')
.innerJoinAndSelect('u.instituciones', 'is')
.innerJoinAndSelect('u.tipoUsuario', 'tu')
.innerJoinAndSelect('is.institucionCarrera', 'ic')
.innerJoinAndSelect('ic.carrera', 'c')
.innerJoinAndSelect('ic.institucion', 'i')
.innerJoinAndSelect('c.nivel', 'n')
.take(25)
.skip((parseInt(filtros.pagina) - 1) * 25);
if (filtros.password)
query.andWhere(
`u.password IS ${filtros.password === 'true' ? 'NOT' : ''} NULL`,
);
if (filtros.activo)
query.andWhere(`is.activo = :activo`, {
activo: filtros.activo === 'true',
});
if (filtros.usuario)
query.andWhere('u.usuario LIKE :usuario', {
usuario: `%${filtros.usuario}%`,
});
if (filtros.nombre)
query.andWhere('u.nombre LIKE :nombre', {
nombre: `%${filtros.nombre}%`,
});
if (carrera)
query.andWhere('c.id_carrera = :id_carrera', {
id_carrera: carrera.id_carrera,
});
if (institucion)
query.andWhere('i.id_institucion = :id_institucion', {
id_institucion: institucion.id_institucion,
});
if (tipoUsuario)
query.andWhere('tu.id_tipo_usuario = :id_tipo_usuario', {
id_tipo_usuario: tipoUsuario.id_tipo_usuario,
});
return query.getManyAndCount();
}
findById(id_usuario: number, validarNoExiste = true, password = false) {
return this.repository
.findOne({
join: {
alias: 'u',
innerJoinAndSelect: {
is: 'u.instituciones',
ic: 'is.institucionCarrera',
c: 'ic.carrera',
i: 'ic.institucion',
n: 'c.nivel',
},
},
where: { id_usuario },
})
.then((usuario) => {
if (validarNoExiste && (!usuario || (password && !usuario.password)))
throw new NotFoundException('No existe este usuario.');
return usuario;
});
}
async findByUsuario(
usuario: string,
validarNoExiste = true,
password = false,
institucionesActivas = false,
rfc?: string,
) {
const query = this.repository
.createQueryBuilder('u')
.innerJoinAndSelect('u.instituciones', 'is')
.innerJoinAndSelect('u.tipoUsuario', 'tu')
.innerJoinAndSelect('is.institucionCarrera', 'ic')
.innerJoinAndSelect('ic.carrera', 'c')
.innerJoinAndSelect('ic.institucion', 'i')
.innerJoinAndSelect('c.nivel', 'n')
.where('usuario = :usuario', { usuario });
if (institucionesActivas) query.andWhere('is.activo = 1');
if (rfc) query.andWhere('rfc = :rfc', { rfc });
return query.getOne().then((usuario) => {
if (validarNoExiste && (!usuario || (password && !usuario.password)))
throw new NotFoundException('No existe este usuario.');
return usuario;
});
}
informacionUsuarioByUsuario(usuario: string) {
return this.informacionUsuarioView
.find({ where: { usuario } })
.then((data) => {
const instituciones: {
id_institucion_usuario: number;
institucionCarrera: {
id_institucion_carrera: number;
institucion: { id_institucion: number; institucion: string };
carrera: { id_carrera: number; carrera: string };
};
}[] = [];
if (data.length === 0) return { usuario: null, password: null };
for (let i = 0; i < data.length; i++)
if (data[i].activo && !data[i].multa)
instituciones.push({
id_institucion_usuario: data[i].id_institucion_usuario,
institucionCarrera: {
id_institucion_carrera: data[i].id_institucion_carrera,
institucion: {
id_institucion: data[i].id_institucion,
institucion: data[i].institucion,
},
carrera: {
id_carrera: data[i].id_carrera,
carrera: data[i].carrera,
},
},
});
return {
usuario: {
id_usuario: data[0].id_usuario,
nombre: data[0].nombre,
usuario: data[0].usuario,
instituciones,
tipoUsuario: { id_tipo_usuario: data[0].id_tipo_usuario },
},
password: data[0].password,
};
});
}
passwordReset(id_usuario: number) {
const password = this.bcryptService.generarPassword();
return this.findById(id_usuario, true, true)
.then((usuario) => {
usuario.password = this.bcryptService.encriptar(password);
return this.repository.save(usuario);
})
.then((usuario) =>
this.nodemailerService.sendEmail({
email: usuario.correo,
subject: 'Credenciales Pc Puma',
html: this.nodemailerService.correoPasswordUsuario(password),
}),
)
.then((_) => ({
message: 'Se cambió correctamente la constraseña del usuario.',
}));
}
async registrar(
id_institucion_carrera: number,
usuario: string,
telefono: string,
rfc = '',
) {
const institucionCarrera = await this.institucionCarreraService.findById(
id_institucion_carrera,
);
const password = this.bcryptService.generarPassword();
let message: string;
return this.findByUsuario(usuario, false, false, false, rfc)
.then(async (existeUsuario) => {
if (!existeUsuario || existeUsuario.password)
throw new ConflictException(
'Verificar sus datos, cualquier duda asistir al módulo PC PUMA.',
);
return this.institucionUsuarioService.findFullInfoInstitucionUsuarioByUsuarioInstitucionCarrera(
existeUsuario,
institucionCarrera,
);
})
.then((institucionUsuario) => {
if (!institucionUsuario.usuario.correo)
throw new ConflictException(
'Tu institución no te asignó un correo institucional, dirigete al módulo para solucionarlo.',
);
const arrobaIndex = institucionUsuario.usuario.correo.indexOf('@');
message = `Se creó correctamente tu cuenta, mandamos un correo a ...${institucionUsuario.usuario.correo.slice(
arrobaIndex - 3,
)} con tus credenciales para acceder a este servicio.`;
institucionUsuario.usuario.telefono = telefono;
institucionUsuario.usuario.password =
this.bcryptService.encriptar(password);
return this.repository.save(institucionUsuario.usuario);
})
.then((usuario) =>
this.nodemailerService.sendEmail({
email: usuario.correo,
subject: 'Credenciales Pc Puma',
html: this.nodemailerService.correoPasswordUsuario(password),
}),
)
.then((_) => ({ message }));
}
update(attrs: Partial<Usuario>, validarPassword = true) {
return this.findById(attrs.id_usuario, true, validarPassword)
.then((usuario) => {
Object.assign(usuario, attrs);
return this.repository.save(usuario);
})
.then((_) => ({
message: 'Se guardaron los cambios correctamente.',
}));
}
}