From cc45011af6814d0c8e64bbb420627822d2dc8bd5 Mon Sep 17 00:00:00 2001 From: lemuel Date: Wed, 4 Jan 2023 16:40:55 -0600 Subject: [PATCH] multa service final --- .../institucion-carrera.service.ts | 2 +- .../institucion-usuario.service.ts | 2 +- src/multa/multa.service.ts | 347 +++++++++--------- src/prestamo/prestamo.service.ts | 17 +- 4 files changed, 192 insertions(+), 176 deletions(-) diff --git a/src/institucion-carrera/institucion-carrera.service.ts b/src/institucion-carrera/institucion-carrera.service.ts index bdec3b5..0ae9c94 100644 --- a/src/institucion-carrera/institucion-carrera.service.ts +++ b/src/institucion-carrera/institucion-carrera.service.ts @@ -62,7 +62,7 @@ export class InstitucionCarreraService { return this.carreraRepository .findOne({ where: { carrera } }) .then((carrera) => { - if (validarNoExiste && !carrera) + if (!carrera && validarNoExiste) throw new NotFoundException('No existe esta carrera.'); return carrera; }); diff --git a/src/institucion-usuario/institucion-usuario.service.ts b/src/institucion-usuario/institucion-usuario.service.ts index 40b40ea..b3bb88d 100644 --- a/src/institucion-usuario/institucion-usuario.service.ts +++ b/src/institucion-usuario/institucion-usuario.service.ts @@ -243,7 +243,7 @@ export class InstitucionUsuarioService { // Guardamos cambios await this.repository.save(institucionesUsuario[i]); } - return { message: 'Se multó correctamente a este usuario' }; + return { message: 'Se multó correctamente a este usuario.' }; }, ); } diff --git a/src/multa/multa.service.ts b/src/multa/multa.service.ts index 59967cb..32c907d 100644 --- a/src/multa/multa.service.ts +++ b/src/multa/multa.service.ts @@ -2,13 +2,13 @@ import * as moment from 'moment'; import { ConflictException, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { FindOptionsWhere, LessThanOrEqual, Like, Repository } from 'typeorm'; -import { Multa } from './entity/multa.entity'; -import { FullInformacionMultaView } from './entity/views/full-informacion-multa.view'; -import { InformacionMultaView } from './entity/views/informacion-multa.view'; import { Modulo } from '../modulo/entity/modulo.entity'; +import { Multa } from './entity/multa.entity'; import { Operador } from '../operador/entity/operador.entity'; import { Prestamo } from '../prestamo/entity/prestamo.entity'; import { Usuario } from '../usuario/entity/usuario.entity'; +import { FullInformacionMultaView } from './entity/views/full-informacion-multa.view'; +import { InformacionMultaView } from './entity/views/informacion-multa.view'; import { EquipoService } from '../equipo/equipo.service'; import { InstitucionInfraccionService } from '../institucion-infraccion/institucion-infraccion.service'; import { InstitucionUsuarioService } from '../institucion-usuario/institucion-usuario.service'; @@ -37,111 +37,95 @@ export class MultaService { modulo: Modulo, prestamo: Prestamo, descripcion: string, - retraso?: number, + semanasCastigo?: number, id_institucion_infraccion?: number, - ) { + ): Promise<{ message: string }> { + // Buscamos la infracción, si es que se mandó una, de lo contrario se asigna "Sin infracción" por default const institucionInfraccion = id_institucion_infraccion ? await this.institucionInfraccionService.findById( id_institucion_infraccion, ) - : // Asigno institucionInfraccion "Sin infracción" por default - await this.institucionInfraccionService.findSinInfraccion( + : await this.institucionInfraccionService.findSinInfraccion( operadorMulta.institucion, ); - // Creo registro de multa - const nuevaMulta = this.repository.create({ - descripcion, - fecha_inicio: moment().toDate(), - operadorMulta: id_institucion_infraccion - ? operadorMulta - : this.operadorService.sistema(), - prestamo, - institucionInfraccion, - }); - const existeMulta = await this.findByPrestamo(prestamo).catch( - (err) => true, - ); + const existeMulta = await this.findByPrestamo(prestamo); const fecha_fin = moment(); - // Si ya tiene multa es que hubo un error en otra ocasión pero se creo la multa - // correctamente esa vez + // Si ya existe una multa asignada a este préstamo significa que hubo un problema pero si se multo al usuario. Cortamos la función if (existeMulta) return; this.validacionMultaCancelacion(prestamo); - // Si no se mando un id_institucion_infraccion ni retraso sacamos error - if (!id_institucion_infraccion && !retraso) - throw new ConflictException( - 'No se mandó ningún motivo para multar a este alumno.', + // Si hay semanasCastigo agregamos el tiempo de multa correspondiente a la institución + if (semanasCastigo) + fecha_fin.add( + semanasCastigo * modulo.institucion.dias_multa_retraso, + 'd', ); - // Si hay retraso lo agrego a la multa - if (retraso) { - nuevaMulta.retraso = true; - fecha_fin.add(retraso * modulo.institucion.dias_multa_retraso, 'd'); - } - fecha_fin.add(institucionInfraccion.dias_multa, 'd'); - nuevaMulta.fecha_fin = fecha_fin.toDate(); - // Guardo la información - return this.repository.save(nuevaMulta).then((_) => - // Actualizo multas del usuario - this.institucionUsuarioService.updateMulta( - operadorMulta.institucion, - prestamo.usuario, - true, - ), - ); - } - - async multaExtemporanea( - operador: Operador, - id_prestamo: number, - descripcion: string, - id_institucion_infraccion: number, - ) { - const prestamo = - typeof id_prestamo === 'number' - ? await this.prestamoService.findById(id_prestamo) - : id_prestamo; - const institucionInfraccion = - await this.institucionInfraccionService.findById( - id_institucion_infraccion, - ); - const fecha_fin = moment(); - - // Validamos que este prestamo le pertenezca al operador - if ( - operador.institucion.id_institucion != - prestamo.equipo.carrito.modulo.institucion.id_institucion - ) - throw new ConflictException( - 'Este préstamo no pertenece a esta institución.', - ); - this.validacionMultaCancelacion(prestamo); - fecha_fin.add(institucionInfraccion.dias_multa, 'd'); - // Buscamos una multa con este préstamo - return this.findByPrestamo(prestamo) - .then((_) => - // Creamos y guardamos registro - this.repository.save( - this.repository.create({ - descripcion, - fecha_fin: fecha_fin.toDate(), - fecha_inicio: moment().toDate(), - institucionInfraccion, - operadorMulta: operador, - prestamo, - }), - ), + // Si la institucionInfraccion no es "Sin infracción" + if (institucionInfraccion.infraccion.id_infraccion != 1) + // Agregamos el tiempo de multa correspondiente de la infracción enviada + fecha_fin.add(institucionInfraccion.dias_multa, 'd'); + // Creamos y guardamos un registro + return this.repository + .save( + this.repository.create({ + descripcion, + fecha_fin: fecha_fin.toDate(), + fecha_inicio: moment().toDate(), + retraso: semanasCastigo ? true : false, + institucionInfraccion, + operadorMulta: id_institucion_infraccion + ? operadorMulta + : this.operadorService.sistema(), + prestamo, + }), ) .then((_) => - // Actualizo multas del usuario + // Multamos al usuario en todas las carreras a las que pertenece en esa institución this.institucionUsuarioService.updateMulta( - operador.institucion, + operadorMulta.institucion, prestamo.usuario, true, ), ); } - findAllActivasExpiradas() { + findAll( + operador: Operador, + filtros: { + pagina: string; + nombre?: string; + usuario?: string; + }, + ): Promise<[Multa[], number]> { + const busqueda: FindOptionsWhere = {}; + + if (filtros.nombre) busqueda.nombre = Like(`%${filtros.nombre}%`); + if (filtros.usuario) busqueda.usuario = Like(`%${filtros.usuario}%`); + if (operador) busqueda.id_institucion = operador.institucion.id_institucion; + return this.fullInformacionMultaView + .findAndCount({ + where: busqueda, + order: { + institucion: 'ASC', + activo: 'DESC', + fecha_fin: 'ASC', + usuario: 'ASC', + }, + skip: (parseInt(filtros.pagina) - 1) * 25, + take: 25, + }) + .then((infoMultas) => { + const multas: Multa[] = []; + + for (let i = 0; i < infoMultas[0].length; i++) + multas.push( + this.repository.create(this.fullViewToMulta(infoMultas[0][i])), + ); + return [multas, infoMultas[1]]; + }); + } + + findAllActivasExpiradas(): Promise { return this.informacionMultaView .find({ where: { activo: 1, fecha_fin: LessThanOrEqual(moment().toDate()) }, @@ -173,43 +157,11 @@ export class MultaService { }); } - findAll( + findAllByIdEquipo( operador: Operador, - filtros: { - pagina: string; - nombre?: string; - usuario?: string; - }, - ) { - const busqueda: FindOptionsWhere = {}; - - if (filtros.nombre) busqueda.nombre = Like(`%${filtros.nombre}%`); - if (filtros.usuario) busqueda.usuario = Like(`%${filtros.usuario}%`); - if (operador) busqueda.id_institucion = operador.institucion.id_institucion; - return this.fullInformacionMultaView - .findAndCount({ - where: busqueda, - order: { - institucion: 'ASC', - activo: 'DESC', - fecha_fin: 'ASC', - id_usuario: 'ASC', - }, - skip: (parseInt(filtros.pagina) - 1) * 25, - take: 25, - }) - .then((infoMultas) => { - const multas: Multa[] = []; - - for (let i = 0; i < infoMultas[0].length; i++) - multas.push( - this.repository.create(this.fullViewToMulta(infoMultas[0][i])), - ); - return [multas, infoMultas[1]]; - }); - } - - findAllByIdEquipo(operador: Operador, id_equipo: number, pagina: number) { + id_equipo: number, + pagina: number, + ): Promise<[Multa[], number]> { return this.equipoService.findById(id_equipo).then((equipo) => this.fullInformacionMultaView .findAndCount({ @@ -232,7 +184,11 @@ export class MultaService { ); } - findAllByIdUsuario(operador: Operador, id_usuario: number, pagina: number) { + findAllByIdUsuario( + operador: Operador, + id_usuario: number, + pagina: number, + ): Promise<[Multa[], number]> { return this.usuarioService.findById(id_usuario).then((usuario) => this.fullInformacionMultaView .findAndCount({ @@ -255,32 +211,28 @@ export class MultaService { ); } - findByPrestamo(prestamo: Prestamo) { - return this.repository - .findOne({ select: ['id_multa'], where: { prestamo } }) - .then((existeMulta) => { - if (existeMulta) - throw new ConflictException( - 'Ya existe una multa asignada a este préstamo.', - ); - return existeMulta; - }); + findByPrestamo(prestamo: Prestamo): Promise { + return this.repository.findOne({ + select: ['id_multa'], + where: { prestamo }, + }); } - findMultasActivasByUsuario(usuario: Usuario) { - return this.repository - .createQueryBuilder('mu') - .innerJoin('mu.prestamo', 'p') - .innerJoin('p.usuario', 'u', 'u.id_usuario = :id_usuario', { - id_usuario: usuario.id_usuario, - }) - .innerJoinAndSelect('mu.institucionInfraccion', 'ii') - .innerJoinAndSelect('ii.institucion', 'i') - .andWhere('mu.activo = 1') - .getMany(); + findMultasActivasByUsuario(usuario: Usuario): Promise { + return this.repository.find({ + join: { + alias: 'mu', + innerJoin: { p: 'mu.prestamo', u: 'p.usuario' }, + innerJoinAndSelect: { + ii: 'mu.institucionInfraccion', + i: 'ii.institucion', + }, + }, + where: { activo: true, prestamo: { usuario } }, + }); } - private fullViewToMulta(infoMulta: FullInformacionMultaView) { + private fullViewToMulta(infoMulta: FullInformacionMultaView): Multa { return this.repository.create({ id_multa: infoMulta.id_multa, activo: infoMulta.activo === 1, @@ -314,19 +266,68 @@ export class MultaService { }); } - save(multa: Multa) { - return this.repository.save(multa); - } + async multaExtemporanea( + operador: Operador, + id_prestamo: number, + descripcion: string, + id_institucion_infraccion: number, + ): Promise<{ message: string }> { + const prestamo = await this.prestamoService.findById(id_prestamo); + const institucionInfraccion = + await this.institucionInfraccionService.findById( + id_institucion_infraccion, + ); + const fecha_fin = moment(); - private validacionMultaCancelacion(prestamo: Prestamo) { - // Validamos que este prestamo no haya sido cancelado poer el usuario u operador - if (prestamo.cancelado_operador || prestamo.cancelado_usuario) + // Validamos que este préstamo le pertenezca al operador + if ( + operador.institucion.id_institucion != + prestamo.equipo.carrito.modulo.institucion.id_institucion + ) throw new ConflictException( - 'No se puede multar a un usuario con un préstamo que fue cancelado.', + 'Este préstamo no pertenece a tu institución.', + ); + // Validamos que la infracción enviada no sea "Sin infracción" + if (institucionInfraccion.infraccion.id_infraccion === 1) + throw new ConflictException( + 'No se puede asignar esta infracción manualmente.', + ); + this.validacionMultaCancelacion(prestamo); + // Agregamos el tiempo de multa correspondiente de la infracción enviada + fecha_fin.add(institucionInfraccion.dias_multa, 'd'); + return this.findByPrestamo(prestamo) + .then((existeMulta) => { + // Validamos que no exista una multa con este préstamo + if (existeMulta) + throw new ConflictException( + 'Ya existe una multa asignada a este préstamo.', + ); + // Creamos y guardamos un registro + return this.repository.save( + this.repository.create({ + descripcion, + fecha_fin: fecha_fin.toDate(), + fecha_inicio: moment().toDate(), + institucionInfraccion, + operadorMulta: operador, + prestamo, + }), + ); + }) + .then((_) => + // Multamos al usuario en todas las carreras a las que pertenece en esa institución + this.institucionUsuarioService.updateMulta( + operador.institucion, + prestamo.usuario, + true, + ), ); } - async quitarMulta(admin: Operador, id_institucion_usuario: number) { + async quitarMulta( + admin: Operador, + id_institucion_usuario: number, + ): Promise<{ message: string }> { const institucionUsuario = await this.institucionUsuarioService.findById( id_institucion_usuario, ); @@ -343,18 +344,34 @@ export class MultaService { .where('mu.activo = 1') .getOne(); - await this.institucionUsuarioService.updateMulta( - admin.institucion, - institucionUsuario.usuario, - false, - ); - if (!multa) + // Validamos que este institucionUsuario le pertenezca al admin + if ( + admin.institucion.id_institucion != + institucionUsuario.institucionCarrera.institucion.id_institucion + ) throw new ConflictException( - 'Este usuario no tiene una multa activa en esta institución.', + 'No puedes modificar la información este usuario porque no pertenece a tu institución.', + ); + return this.institucionUsuarioService + .updateMulta(admin.institucion, institucionUsuario.usuario, false) + .then(async (_) => { + if (multa) { + multa.activo = false; + await this.repository.save(multa); + } + return { message: 'Se guardaron los cambios correctamente.' }; + }); + } + + save(multa: Multa): Promise { + return this.repository.save(multa); + } + + private validacionMultaCancelacion(prestamo: Prestamo): void { + // Validamos que este présstamo no haya sido cancelado por el usuario u operador + if (prestamo.cancelado_operador || prestamo.cancelado_usuario) + throw new ConflictException( + 'No se puede multar a un usuario con un préstamo que fue cancelado.', ); - multa.activo = false; - return this.repository - .save(multa) - .then((_) => ({ message: 'Se guardaron los cambios correctamente.' })); } } diff --git a/src/prestamo/prestamo.service.ts b/src/prestamo/prestamo.service.ts index adc8db7..c08fdf5 100644 --- a/src/prestamo/prestamo.service.ts +++ b/src/prestamo/prestamo.service.ts @@ -606,30 +606,29 @@ export class PrestamoService { if (!infoPrestamo) throw new NotFoundException('No existe este id préstamo.'); - const prestamo = this.prestamoInfoViewToPrestamo(infoPrestamo); - - return this.prestamoPasscode(prestamo); + return this.prestamoPasscode( + this.prestamoInfoViewToPrestamo(infoPrestamo), + ); }); } prestamoInfoByUsuario( usuario: Usuario, - validarExistencia = true, + validarNoExiste = true, ): Promise { return this.prestamoInformacionView .findOne({ where: { activo: 1, id_usuario: usuario.id_usuario } }) .then((infoPrestamo) => { if (!infoPrestamo) { - if (validarExistencia) + if (validarNoExiste) throw new NotFoundException( 'Este usuario no tiene un préstamo activo.', ); return null; } - - const prestamo = this.prestamoInfoViewToPrestamo(infoPrestamo); - - return this.prestamoPasscode(prestamo); + return this.prestamoPasscode( + this.prestamoInfoViewToPrestamo(infoPrestamo), + ); }); }