From f0f3b7d3dc7d464e83bb8c80749f41410e42283f Mon Sep 17 00:00:00 2001 From: xXpuma99Xx <51341582+xXpuma99Xx@users.noreply.github.com> Date: Mon, 2 Jan 2023 23:16:11 -0600 Subject: [PATCH] prestamo service final --- src/carrito/carrito.service.ts | 52 +- .../institucion-dia.controller.ts | 5 +- src/institucion-dia/institucion-dia.module.ts | 2 + .../institucion-dia.service.ts | 39 +- src/prestamo/entity/prestamo.entity.ts | 4 +- src/prestamo/prestamo.controller.ts | 8 +- src/prestamo/prestamo.module.ts | 2 + src/prestamo/prestamo.service.ts | 664 ++++++++---------- 8 files changed, 356 insertions(+), 420 deletions(-) diff --git a/src/carrito/carrito.service.ts b/src/carrito/carrito.service.ts index c32d985..8b2ebf1 100644 --- a/src/carrito/carrito.service.ts +++ b/src/carrito/carrito.service.ts @@ -66,32 +66,6 @@ export class CarritoService { })); } - findById(id_carrito: number): Promise { - return this.informacionCarritoView - .findOne({ where: { id_carrito } }) - .then((infoCarrito) => { - if (!infoCarrito) - throw new NotFoundException('No existe este id carrito.'); - return this.viewToCarrito(infoCarrito); - }); - } - - findCarrito( - modulo: Modulo, - tipoCarrito: TipoCarrito, - carrito: string, - ): Promise { - return this.informacionCarritoView - .findOne({ - where: { - carrito, - id_modulo: modulo.id_modulo, - id_tipo_carrito: tipoCarrito.id_tipo_carrito, - }, - }) - .then((infoCarrito) => this.viewToCarrito(infoCarrito)); - } - async findAll( operador: Operador, filtros: { @@ -153,6 +127,32 @@ export class CarritoService { }); } + findById(id_carrito: number): Promise { + return this.informacionCarritoView + .findOne({ where: { id_carrito } }) + .then((infoCarrito) => { + if (!infoCarrito) + throw new NotFoundException('No existe este id carrito.'); + return this.viewToCarrito(infoCarrito); + }); + } + + findCarrito( + modulo: Modulo, + tipoCarrito: TipoCarrito, + carrito: string, + ): Promise { + return this.informacionCarritoView + .findOne({ + where: { + carrito, + id_modulo: modulo.id_modulo, + id_tipo_carrito: tipoCarrito.id_tipo_carrito, + }, + }) + .then((infoCarrito) => this.viewToCarrito(infoCarrito)); + } + findFullInfoById(operador: Operador, id_carrito: number): Promise { return this.fullInformacionCarritoView .findOne({ where: { id_carrito } }) diff --git a/src/institucion-dia/institucion-dia.controller.ts b/src/institucion-dia/institucion-dia.controller.ts index b6012d4..b4d98df 100644 --- a/src/institucion-dia/institucion-dia.controller.ts +++ b/src/institucion-dia/institucion-dia.controller.ts @@ -61,7 +61,10 @@ export class InstitucionDiaController { const usuario: Usuario = req.user.usuario; this.validarUsuarioService.validarUsuario(usuario); - return this.institucionDiaService.hoy(parseInt(query.id_institucion)); + return this.institucionDiaService.hoyUsuario( + usuario, + parseInt(query.id_institucion), + ); } @Serealize(MessageOutputDto) diff --git a/src/institucion-dia/institucion-dia.module.ts b/src/institucion-dia/institucion-dia.module.ts index ba116a9..485d61c 100644 --- a/src/institucion-dia/institucion-dia.module.ts +++ b/src/institucion-dia/institucion-dia.module.ts @@ -6,10 +6,12 @@ import { InstitucionDiaService } from './institucion-dia.service'; import { Dia } from './entity/dia.entity'; import { InstitucionDia } from './entity/institucion-dia.entity'; import { InstitucionModule } from '../institucion/institucion.module'; +import { InstitucionUsuarioModule } from '../institucion-usuario/institucion-usuario.module'; @Module({ imports: [ InstitucionModule, + InstitucionUsuarioModule, PassportModule.register({ defaultStrategy: 'jwt' }), TypeOrmModule.forFeature([Dia, InstitucionDia]), ], diff --git a/src/institucion-dia/institucion-dia.service.ts b/src/institucion-dia/institucion-dia.service.ts index 188cf8a..8b33164 100644 --- a/src/institucion-dia/institucion-dia.service.ts +++ b/src/institucion-dia/institucion-dia.service.ts @@ -2,6 +2,7 @@ import * as moment from 'moment'; import { BadRequestException, ConflictException, + ForbiddenException, Injectable, NotFoundException, } from '@nestjs/common'; @@ -9,8 +10,10 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Institucion } from '../institucion/entity/institucion.entity'; import { InstitucionDia } from './entity/institucion-dia.entity'; +import { Usuario } from 'src/usuario/entity/usuario.entity'; import { Operador } from '../operador/entity/operador.entity'; import { InstitucionService } from '../institucion/institucion.service'; +import { InstitucionUsuarioService } from '../institucion-usuario/institucion-usuario.service'; @Injectable() export class InstitucionDiaService { @@ -18,6 +21,7 @@ export class InstitucionDiaService { @InjectRepository(InstitucionDia) private repository: Repository, private institucionService: InstitucionService, + private institucionUsuarioService: InstitucionUsuarioService, ) {} findAllAdmin(admin: Operador): Promise { @@ -43,24 +47,37 @@ export class InstitucionDiaService { }); } - findByInstitucionDia( - institucion: Institucion, - id_dia: number, - ): Promise { - return this.repository.findOne({ where: { institucion, dia: { id_dia } } }); - } - - hoy(id_institucion: number): Promise { + hoy(institucion: Institucion): Promise { const ahora = moment(); // Validamos que no sea domingo if (ahora.weekday() === 0) throw new ConflictException('No hay servicio los días domingo.'); + return this.repository.findOne({ + where: { institucion, dia: { id_dia: ahora.weekday() } }, + }); + } + + hoyUsuario( + usuario: Usuario, + id_institucion: number, + ): Promise { return this.institucionService .findById(id_institucion) - .then((institucion) => - this.findByInstitucionDia(institucion, ahora.weekday()), - ); + .then(async (institucion) => { + const institucionUsuario = + await this.institucionUsuarioService.findByIdUsuarioIdInstitucion( + usuario, + institucion, + ); + + // Validamos que el usuario pertenezca a la institución de la información que solicita + if (!institucionUsuario) + throw new ForbiddenException( + 'No puedes acceder a esta información porque no le pertenece a tu institución.', + ); + return this.hoy(institucion); + }); } update( diff --git a/src/prestamo/entity/prestamo.entity.ts b/src/prestamo/entity/prestamo.entity.ts index 6a35bd9..ab660a1 100644 --- a/src/prestamo/entity/prestamo.entity.ts +++ b/src/prestamo/entity/prestamo.entity.ts @@ -46,10 +46,10 @@ export class Prestamo { @Column({ type: Number, nullable: true }) id_equipo: number; - @Column({ type: Number, nullable: true }) + @Column({ type: Number, nullable: true, default: 1 }) id_operador_entrega: number; - @Column({ type: Number, nullable: true }) + @Column({ type: Number, nullable: true, default: 1 }) id_operador_regreso: number; @Column({ type: Number, nullable: true }) diff --git a/src/prestamo/prestamo.controller.ts b/src/prestamo/prestamo.controller.ts index eea3386..36ce3b2 100644 --- a/src/prestamo/prestamo.controller.ts +++ b/src/prestamo/prestamo.controller.ts @@ -117,7 +117,7 @@ export class PrestamoController { const operador: Operador = req.user.operador; this.validarUsuarioService.validarAdminOperador(operador); - return this.prestamoService.findAll(query); + return this.prestamoService.findAll(operador, query); } @Serealize(MessageOutputDto) @@ -286,7 +286,7 @@ export class PrestamoController { const operador: Operador = req.user.operador; this.validarUsuarioService.validarOperador(operador); - return this.prestamoService.findAll(query); + return this.prestamoService.findAll(operador, query); } @Serealize(PrestamosEquipoOutputDto) @@ -312,6 +312,7 @@ export class PrestamoController { this.validarUsuarioService.validarAdminOperador(operador); return this.prestamoService.findAllByIdEquipo( + operador, parseInt(query.id_equipo), parseInt(query.pagina), ); @@ -340,6 +341,7 @@ export class PrestamoController { this.validarUsuarioService.validarAdminOperador(operador); return this.prestamoService.findAllByIdUsuario( + operador, parseInt(query.id_usuario), parseInt(query.pagina), ); @@ -625,6 +627,6 @@ export class PrestamoController { const operador: Operador = req.user.operador; this.validarUsuarioService.validarOperador(operador); - return this.prestamoService.findAll(query); + return this.prestamoService.findAll(operador, query); } } diff --git a/src/prestamo/prestamo.module.ts b/src/prestamo/prestamo.module.ts index cc1b252..1c26a4e 100644 --- a/src/prestamo/prestamo.module.ts +++ b/src/prestamo/prestamo.module.ts @@ -19,6 +19,7 @@ import { ModuloModule } from '../modulo/modulo.module'; import { MultaModule } from '../multa/multa.module'; import { OperadorModule } from '../operador/operador.module'; import { PasscodeModule } from '../passcode/passcode.module'; +import { StatusModule } from '../status/status.module'; import { TipoUsuarioModule } from '../tipo-usuario/tipo-usuario.module'; import { UsuarioModule } from '../usuario/usuario.module'; @@ -36,6 +37,7 @@ import { UsuarioModule } from '../usuario/usuario.module'; OperadorModule, forwardRef(() => PasscodeModule), PassportModule.register({ defaultStrategy: 'jwt' }), + StatusModule, TipoUsuarioModule, TypeOrmModule.forFeature([ Prestamo, diff --git a/src/prestamo/prestamo.service.ts b/src/prestamo/prestamo.service.ts index 03b3996..a118eba 100644 --- a/src/prestamo/prestamo.service.ts +++ b/src/prestamo/prestamo.service.ts @@ -24,6 +24,7 @@ import { InstitucionUsuario } from '../institucion-usuario/entity/institucion-us import { Modulo } from '../modulo/entity/modulo.entity'; import { Operador } from '../operador/entity/operador.entity'; import { Prestamo } from './entity/prestamo.entity'; +import { Equipo } from '../equipo/entity/equipo.entity'; import { Usuario } from '../usuario/entity/usuario.entity'; import { FullInformacionPrestamoView } from './entity/views/full-informacion-prestamo.view'; import { PrestamoInformacionView } from './entity/views/prestamo-informacion.view'; @@ -39,6 +40,7 @@ import { ModuloService } from '../modulo/modulo.service'; import { MultaService } from '../multa/multa.service'; import { OperadorService } from '../operador/operador.service'; import { PasscodeService } from '../passcode/passcode.service'; +import { StatusService } from '../status/status.service'; import { TipoUsuarioService } from '../tipo-usuario/tipo-usuario.service'; import { UsuarioService } from '../usuario/usuario.service'; @@ -66,6 +68,7 @@ export class PrestamoService { private operadorService: OperadorService, @Inject(forwardRef(() => PasscodeService)) private passcodeService: PasscodeService, + private statusService: StatusService, private tipoUsuarioService: TipoUsuarioService, private usuarioService: UsuarioService, ) {} @@ -74,58 +77,61 @@ export class PrestamoService { operadorRegreso: Operador, id_prestamo: number, motivo: string, - modulo: Modulo, - ) { + modulo?: Modulo, + ): Promise<{ message: string }> { const ahora = moment(); const prestamo = await this.findById(id_prestamo); this.validacionBasicaPrestamo(prestamo); this.validacionOperadorPrestamo(prestamo, operadorRegreso, modulo); + // Desactivamos el préstamo prestamo.activo = false; prestamo.fecha_entrega = ahora.toDate(); prestamo.cancelado_operador = true; prestamo.operadorRegreso = operadorRegreso; + // Validamos que el equipo si se la haya asignado al usuario del registro if (prestamo.equipo.u === prestamo.usuario.id_usuario) { + // Reseteamos datos de equipo prestamo.equipo.u = null; prestamo.equipo.status.id_status = 6; - // Guardamos cambios en el equipo, y envio el motivo de cancelación + // Guardamos cambios en el equipo await this.equipoService.updateStatus( prestamo.equipo, operadorRegreso, motivo, ); } - // Guardamos cambios del prestamo + // Guardamos cambios en el préstamo return this.repository.save(prestamo).then((_) => { - // Actualizo interfaz de usaurios + // Actualizamos la interfaz del usaurio this.appGateway.actualizarUsuario(prestamo.usuario.id_usuario); - this.appGateway.actualizarOperador( - operadorRegreso.institucion.id_institucion, - ); return { message: 'Se canceló correctamente este préstamo.' }; }); } - async cancelarUsuario(usuario: Usuario) { + async cancelarUsuario(usuario: Usuario): Promise<{ message: string }> { const ahora = moment(); const prestamo = await this.prestamoInfoByUsuario(usuario); this.validacionBasicaPrestamo(prestamo); - // Sacamos error en status de equipo 3 + // Desactivamos el préstamo + prestamo.activo = false; + prestamo.fecha_entrega = ahora.toDate(); + prestamo.cancelado_usuario = true; + // Validamos que el equipo si se la haya asignado al usuario del registro if (prestamo.equipo.u === usuario.id_usuario) { + // Sacamos error si el equipo ya esta en uso if (prestamo.equipo.status.id_status === 3) throw new ConflictException( 'No puedes cancelar este préstamo una vez que se te entregó el equipo.', ); + // Reseteamos datos de equipo prestamo.equipo.u = null; prestamo.equipo.status.id_status = 1; // Guardamos cambios en el equipo await this.equipoService.updateStatus(prestamo.equipo); } - prestamo.activo = false; - prestamo.fecha_entrega = ahora.toDate(); - prestamo.cancelado_usuario = true; - // Guardamos cambios del prestamo + // Guardamos cambios en el prestamo return this.repository.save(prestamo).then((_) => { // Actualizo interfaz de operador this.appGateway.actualizarOperador( @@ -141,20 +147,17 @@ export class PrestamoService { id_tipo_carrito: number, id_programa?: number, id_tipo_entrada?: number, - ) { + ): Promise { const ahora = moment(); const ahoraStr = ahora.format('YYYY-MM-DD'); - const sistema = { id_operador: 1 }; const modulo = await this.moduloService.findFullInfoById(id_modulo); const tipoCarrito = await this.institucionTipoCarritoService.findTipoCarritoById( id_tipo_carrito, ); - const institucionDia = - await this.institucionDiaService.findByInstitucionDia( - modulo.institucion, - ahora.weekday(), - ); + const institucionDia = await this.institucionDiaService.hoy( + modulo.institucion, + ); const horaMin = institucionDia ? moment(`${ahoraStr} ${institucionDia.hora_inicio}`) : null; @@ -170,15 +173,12 @@ export class PrestamoService { ) : null; - // Validamos que no sea domingo - if (ahora.weekday() === 0) - throw new ConflictException('No hay servicio los días domingo.'); // Validamos si ese día se encuentra activo if (!institucionDia.activo) throw new ConflictException( 'El día de hoy no hay servicio de préstamo de equipos.', ); - // Si ahora es menor a horaMin significa que aun no inicio el horario de serivicio + // Si ahora es menor a horaMin significa que aun no inicia el horario de serivicio if (ahora < horaMin) throw new ConflictException( `El servicio inicia a las ${institucionDia.hora_inicio} el día de hoy.`, @@ -188,7 +188,7 @@ export class PrestamoService { throw new ConflictException( `El servicio terminó a las ${institucionDia.hora_extra} el día de hoy.`, ); - // Recorro el array de horasExcepcion del día en cuestión + // Recorremos el array de horasExcepcion del día de hoy for (let i = 0; i < institucionDia.horasExcepcion.length; i++) { const horaFin = moment( `${ahoraStr} ${institucionDia.horasExcepcion[i].hora_fin}`, @@ -197,14 +197,13 @@ export class PrestamoService { `${ahoraStr} ${institucionDia.horasExcepcion[i].hora_inicio}`, ); - // Si ahora esta entre horaInicio y horaFin significa que no hay servicio de préstamos - // temporalmente + // Si ahora esta entre horaInicio y horaFin significa que no hay servicio de préstamos temporalmente if (ahora > horaInicio && ahora < horaFin) throw new ConflictException( `Se suspendió el servicio de préstamo temporalmente de ${institucionDia.horasExcepcion[i].hora_inicio} a ${institucionDia.horasExcepcion[i].hora_fin}.`, ); } - // Buscamos instituciones activas y sin multa de este usuario + // Buscamos las instituciones usuario de este usuario return this.institucionUsuarioService .findFullInfoAllByIdUsuario(usuario, false) .then((instituciones) => { @@ -230,27 +229,27 @@ export class PrestamoService { ); }) .then((equipo) => - // Genero el registro y lo guardo + // Creamos y guardamos un registro this.repository.save( this.repository.create({ - equipo, fecha_inicio: ahora.toDate(), hora_max_recoger: ahora .add(modulo.institucion.tiempo_recoger, 'm') .toDate(), - operadorEntrega: sistema, - operadorRegreso: sistema, + equipo, usuario, }), ), ) .then((prestamo) => { - // Actualizo la interfaz del operador + // Actualizamos la interfaz del operador this.appGateway.actualizarOperador(modulo.institucion.id_institucion); + // Si es locker if ( prestamo.equipo.carrito.tipoCarrito.id_tipo_carrito === 4 || prestamo.equipo.carrito.tipoCarrito.id_tipo_carrito === 5 ) + // Creamos un passcode return this.passcodeService .create(prestamo) .then((passcode) => ({ ...prestamo, passcode: passcode.passcode })); @@ -258,51 +257,17 @@ export class PrestamoService { }); } - async findAllActivosExpirados(): Promise { - return this.informacionPrestamoView - .find({ - where: { - activo: 1, - hora_max_recoger: LessThanOrEqual(moment().toDate()), - id_status: 2, - }, - }) - .then((infoPrestamos) => { - const prestamos: Prestamo[] = []; - - for (let i = 0; i < infoPrestamos.length; i++) - prestamos.push(this.viewToPrestamo(infoPrestamos[i])); - return prestamos; - }); - } - - async findAllEquiposRepetidos(): Promise { - return this.informacionPrestamoView - .createQueryBuilder('ipv') - .where('activo = 1 AND id_usuario != u') - .getMany() - .then((infoPrestamos) => { - const prestamos: Prestamo[] = []; - - for (let i = 0; i < infoPrestamos.length; i++) - prestamos.push(this.viewToPrestamo(infoPrestamos[i])); - return prestamos; - }); - } - async entregar( operadorEntrega: Operador, modulo: Modulo, id_prestamo: number, - ) { + ): Promise { const ahora = moment(); const ahoraStr = ahora.format('YYYY-MM-DD'); const prestamo = await this.findById(id_prestamo); - const institucionDia = - await this.institucionDiaService.findByInstitucionDia( - operadorEntrega.institucion, - ahora.weekday(), - ); + const institucionDia = await this.institucionDiaService.hoy( + operadorEntrega.institucion, + ); const horaTope = institucionDia ? moment(`${ahoraStr} ${institucionDia.hora_tope}`) : null; @@ -344,25 +309,28 @@ export class PrestamoService { }); } - async findAll(filtros: { - pagina?: string; - activo?: string | boolean; - cancelado_operador?: string; - cancelado_usuario?: string; - carrito?: string; - equipo?: string; - fechaFin?: string; - fechaInicio?: string; - id_institucion?: string; - id_institucion_carrera?: string; - id_modulo?: string; - id_operador_entrega?: string; - id_operador_regreso?: string; - id_prestamo?: string; - id_tipo_carrito?: string; - id_tipo_usuario?: string; - usuario?: string; - }) { + async findAll( + operador: Operador, + filtros: { + activo?: string | boolean; + cancelado_operador?: string; + cancelado_usuario?: string; + carrito?: string; + equipo?: string; + fechaFin?: string; + fechaInicio?: string; + id_institucion?: string; + id_institucion_carrera?: string; + id_modulo?: string; + id_operador_entrega?: string; + id_operador_regreso?: string; + id_prestamo?: string; + id_tipo_carrito?: string; + id_tipo_usuario?: string; + pagina?: string; + usuario?: string; + }, + ): Promise { const institucion = filtros.id_institucion ? await this.institucionService.findById(parseInt(filtros.id_institucion)) : null; @@ -425,7 +393,9 @@ export class PrestamoService { busqueda.id_institucion_carrera = parseInt( filtros.id_institucion_carrera, ); - if (institucion) busqueda.id_institucion = institucion.id_institucion; + if (operador.tipoUsuario.id_tipo_usuario > 2) + busqueda.id_institucion = operador.institucion.id_institucion; + else if (institucion) busqueda.id_institucion = institucion.id_institucion; if (modulo) busqueda.id_modulo = modulo.id_modulo; if (tipoCarrito) busqueda.id_tipo_carrito = tipoCarrito.id_tipo_carrito; if (tipoUsuario) busqueda.id_tipo_usuario = tipoUsuario.id_tipo_usuario; @@ -443,114 +413,68 @@ export class PrestamoService { const prestamos: Prestamo[] = []; for (let i = 0; i < infoPrestamos[0].length; i++) - prestamos.push( - this.repository.create({ - id_prestamo: infoPrestamos[0][i].id_prestamo, - activo: infoPrestamos[0][i].activo === 1, - cancelado_operador: - infoPrestamos[0][i].cancelado_operador === 1, - cancelado_usuario: infoPrestamos[0][i].cancelado_usuario === 1, - fecha_entrega: infoPrestamos[0][i].fecha_entrega, - fecha_inicio: infoPrestamos[0][i].fecha_inicio, - hora_fin: infoPrestamos[0][i].hora_fin, - hora_inicio: infoPrestamos[0][i].hora_inicio, - hora_max_recoger: infoPrestamos[0][i].hora_max_recoger, - equipo: { - id_equipo: infoPrestamos[0][i].id_equipo, - equipo: infoPrestamos[0][i].equipo, - numero_inventario: infoPrestamos[0][i].numero_inventario, - carrito: { - id_carrito: infoPrestamos[0][i].id_carrito, - carrito: infoPrestamos[0][i].carrito, - modulo: { - id_modulo: infoPrestamos[0][i].id_modulo, - modulo: infoPrestamos[0][i].modulo, - institucion: { - id_institucion: infoPrestamos[0][i].id_institucion, - institucion: infoPrestamos[0][i].institucion, - }, - }, - tipoCarrito: { - id_tipo_carrito: infoPrestamos[0][i].id_tipo_carrito, - tipo_carrito: infoPrestamos[0][i].tipo_carrito, - }, - }, - status: { id_status: infoPrestamos[0][i].id_status }, - }, - usuario: { - id_usuario: infoPrestamos[0][i].id_usuario, - nombre: infoPrestamos[0][i].nombre, - usuario: infoPrestamos[0][i].usuario, - tipoUsuario: { - id_tipo_usuario: infoPrestamos[0][i].id_tipo_usuario, - }, - }, - operadorEntrega: { - id_operador: infoPrestamos[0][i].id_operador_entrega, - operador: infoPrestamos[0][i].operador_entrega, - }, - operadorRegreso: { - id_operador: infoPrestamos[0][i].id_operador_regreso, - operador: infoPrestamos[0][i].operador_regreso, - }, - }), - ); + prestamos.push(this.fullViewToPrestamo(infoPrestamos[0][i])); return [prestamos, infoPrestamos[1]]; }); } return this.fullInformacionPrestamoView.find(options); } - findAllByIdEquipo(id_equipo: number, pagina: number) { + findAllActivosExpirados(): Promise { + return this.informacionPrestamoView + .find({ + where: { + activo: 1, + hora_max_recoger: LessThanOrEqual(moment().toDate()), + id_status: 2, + }, + }) + .then((infoPrestamos) => { + const prestamos: Prestamo[] = []; + + for (let i = 0; i < infoPrestamos.length; i++) + prestamos.push(this.viewToPrestamo(infoPrestamos[i])); + return prestamos; + }); + } + + findAllByIdEquipo( + opeardor: Operador, + id_equipo: number, + pagina: number, + ): Promise<[Prestamo[], number]> { return this.fullInformacionPrestamoView .findAndCount({ - where: { id_equipo }, + where: { + id_equipo, + id_institucion: opeardor.institucion.id_institucion, + }, order: { id_prestamo: 'DESC' }, skip: (pagina - 1) * 25, take: 25, }) .then((infoPrestamos) => { const prestamos: Prestamo[] = []; + for (let i = 0; i < infoPrestamos[0].length; i++) - prestamos.push( - this.repository.create({ - id_prestamo: infoPrestamos[0][i].id_prestamo, - activo: infoPrestamos[0][i].activo === 1, - cancelado_operador: infoPrestamos[0][i].cancelado_operador === 1, - cancelado_usuario: infoPrestamos[0][i].cancelado_usuario === 1, - fecha_entrega: infoPrestamos[0][i].fecha_entrega, - fecha_inicio: infoPrestamos[0][i].fecha_inicio, - hora_fin: infoPrestamos[0][i].hora_fin, - hora_inicio: infoPrestamos[0][i].hora_inicio, - hora_max_recoger: infoPrestamos[0][i].hora_max_recoger, - usuario: { - id_usuario: infoPrestamos[0][i].id_usuario, - nombre: infoPrestamos[0][i].nombre, - usuario: infoPrestamos[0][i].usuario, - tipoUsuario: { - id_tipo_usuario: infoPrestamos[0][i].id_tipo_usuario, - }, - }, - operadorEntrega: { - id_operador: infoPrestamos[0][i].id_operador_entrega, - operador: infoPrestamos[0][i].operador_entrega, - }, - operadorRegreso: { - id_operador: infoPrestamos[0][i].id_operador_regreso, - operador: infoPrestamos[0][i].operador_regreso, - }, - }), - ); + prestamos.push(this.fullViewToPrestamo(infoPrestamos[0][i])); return [prestamos, infoPrestamos[1]]; }); } - findAllByIdUsuario(id_usuario: number, pagina: number) { + findAllByIdUsuario( + opeardor: Operador, + id_usuario: number, + pagina: number, + ): Promise<[Prestamo[], number]> { return this.usuarioService .findById(id_usuario) .then((usuario) => this.fullInformacionPrestamoView.findAndCount({ - where: { id_usuario: usuario.id_usuario }, + where: { + id_institucion: opeardor.institucion.id_institucion, + id_usuario: usuario.id_usuario, + }, order: { id_prestamo: 'DESC' }, skip: (pagina - 1) * 25, take: 25, @@ -560,53 +484,26 @@ export class PrestamoService { const prestamos: Prestamo[] = []; for (let i = 0; i < infoPrestamos[0].length; i++) - prestamos.push( - this.repository.create({ - id_prestamo: infoPrestamos[0][i].id_prestamo, - activo: infoPrestamos[0][i].activo === 1, - cancelado_operador: infoPrestamos[0][i].cancelado_operador === 1, - cancelado_usuario: infoPrestamos[0][i].cancelado_usuario === 1, - fecha_entrega: infoPrestamos[0][i].fecha_entrega, - fecha_inicio: infoPrestamos[0][i].fecha_inicio, - hora_fin: infoPrestamos[0][i].hora_fin, - hora_inicio: infoPrestamos[0][i].hora_inicio, - hora_max_recoger: infoPrestamos[0][i].hora_max_recoger, - equipo: { - id_equipo: infoPrestamos[0][i].id_equipo, - equipo: infoPrestamos[0][i].equipo, - numero_inventario: infoPrestamos[0][i].numero_inventario, - carrito: { - id_carrito: infoPrestamos[0][i].id_carrito, - carrito: infoPrestamos[0][i].carrito, - modulo: { - id_modulo: infoPrestamos[0][i].id_modulo, - modulo: infoPrestamos[0][i].modulo, - institucion: { - id_institucion: infoPrestamos[0][i].id_institucion, - institucion: infoPrestamos[0][i].institucion, - }, - }, - tipoCarrito: { - id_tipo_carrito: infoPrestamos[0][i].id_tipo_carrito, - tipo_carrito: infoPrestamos[0][i].tipo_carrito, - }, - }, - }, - operadorEntrega: { - id_operador: infoPrestamos[0][i].id_operador_entrega, - operador: infoPrestamos[0][i].operador_entrega, - }, - operadorRegreso: { - id_operador: infoPrestamos[0][i].id_operador_regreso, - operador: infoPrestamos[0][i].operador_regreso, - }, - }), - ); + prestamos.push(this.fullViewToPrestamo(infoPrestamos[0][i])); return [prestamos, infoPrestamos[1]]; }); } - findById(id_prestamo: number) { + findAllEquiposRepetidos(): Promise { + return this.informacionPrestamoView + .createQueryBuilder('ipv') + .where('activo = 1 AND id_usuario != u') + .getMany() + .then((infoPrestamos) => { + const prestamos: Prestamo[] = []; + + for (let i = 0; i < infoPrestamos.length; i++) + prestamos.push(this.viewToPrestamo(infoPrestamos[i])); + return prestamos; + }); + } + + findById(id_prestamo: number): Promise { return this.informacionPrestamoView .findOne({ where: { id_prestamo } }) .then((infoPrestamo) => { @@ -616,7 +513,10 @@ export class PrestamoService { }); } - findByNumeroInventario(institucion: Institucion, numero_inventario: string) { + findByNumeroInventario( + institucion: Institucion, + numero_inventario: string, + ): Promise { return this.informacionPrestamoView .findOne({ where: { @@ -633,56 +533,79 @@ export class PrestamoService { }); } - private mensajeNoPoderPedir() { + fullViewToPrestamo(infoPrestamo: FullInformacionPrestamoView): Prestamo { + return this.repository.create({ + id_prestamo: infoPrestamo.id_prestamo, + activo: infoPrestamo.activo === 1, + cancelado_operador: infoPrestamo.cancelado_operador === 1, + cancelado_usuario: infoPrestamo.cancelado_usuario === 1, + fecha_entrega: infoPrestamo.fecha_entrega, + fecha_inicio: infoPrestamo.fecha_inicio, + hora_fin: infoPrestamo.hora_fin, + hora_inicio: infoPrestamo.hora_inicio, + hora_max_recoger: infoPrestamo.hora_max_recoger, + equipo: { + id_equipo: infoPrestamo.id_equipo, + equipo: infoPrestamo.equipo, + numero_inventario: infoPrestamo.numero_inventario, + carrito: { + id_carrito: infoPrestamo.id_carrito, + carrito: infoPrestamo.carrito, + modulo: { + id_modulo: infoPrestamo.id_modulo, + modulo: infoPrestamo.modulo, + institucion: { + id_institucion: infoPrestamo.id_institucion, + institucion: infoPrestamo.institucion, + }, + }, + tipoCarrito: { + id_tipo_carrito: infoPrestamo.id_tipo_carrito, + tipo_carrito: infoPrestamo.tipo_carrito, + }, + }, + status: { id_status: infoPrestamo.id_status }, + }, + operadorEntrega: { + id_operador: infoPrestamo.id_operador_entrega, + operador: infoPrestamo.operador_entrega, + }, + operadorRegreso: { + id_operador: infoPrestamo.id_operador_regreso, + operador: infoPrestamo.operador_regreso, + }, + usuario: { + id_usuario: infoPrestamo.id_usuario, + nombre: infoPrestamo.nombre, + usuario: infoPrestamo.usuario, + tipoUsuario: { + id_tipo_usuario: infoPrestamo.id_tipo_usuario, + }, + }, + }); + } + + private mensajeNoPoderPedir(): string { return 'No puedes pedir equipos de cómputo porque:'; } - prestamoInfoById(id_prestamo: number) { + prestamoInfoById(id_prestamo: number): Promise { return this.prestamoInformacionView .findOne({ where: { id_prestamo } }) .then((infoPrestamo) => { if (!infoPrestamo) throw new NotFoundException('No existe este id préstamo.'); - const prestamo = this.repository.create({ - id_prestamo: infoPrestamo.id_prestamo, - activo: infoPrestamo.activo === 1, - cancelado_operador: infoPrestamo.cancelado_operador === 1, - cancelado_usuario: infoPrestamo.cancelado_usuario === 1, - fecha_entrega: infoPrestamo.fecha_entrega, - fecha_inicio: infoPrestamo.fecha_inicio, - hora_fin: infoPrestamo.hora_fin, - hora_inicio: infoPrestamo.hora_inicio, - hora_max_recoger: infoPrestamo.hora_max_recoger, - equipo: { - id_equipo: infoPrestamo.id_equipo, - equipo: infoPrestamo.equipo, - numero_inventario: infoPrestamo.numero_inventario, - carrito: { - id_carrito: infoPrestamo.id_carrito, - carrito: infoPrestamo.carrito, - modulo: { - id_modulo: infoPrestamo.id_modulo, - modulo: infoPrestamo.modulo, - institucion: { - id_institucion: infoPrestamo.id_institucion, - institucion: infoPrestamo.institucion, - }, - }, - tipoCarrito: { - id_tipo_carrito: infoPrestamo.id_tipo_carrito, - tipo_carrito: infoPrestamo.tipo_carrito, - }, - }, - status: { id_status: infoPrestamo.id_status }, - }, - }); + const prestamo = this.prestamoInfoViewToPrestamo(infoPrestamo); return this.prestamoPasscode(prestamo); }); } - prestamoInfoByUsuario(usuario: Usuario, validarExistencia = true) { + prestamoInfoByUsuario( + usuario: Usuario, + validarExistencia = true, + ): Promise { return this.prestamoInformacionView .findOne({ where: { activo: 1, id_usuario: usuario.id_usuario } }) .then((infoPrestamo) => { @@ -694,37 +617,7 @@ export class PrestamoService { return null; } - const prestamo = this.repository.create({ - id_prestamo: infoPrestamo.id_prestamo, - activo: infoPrestamo.activo === 1, - fecha_inicio: infoPrestamo.fecha_inicio, - hora_fin: infoPrestamo.hora_fin, - hora_inicio: infoPrestamo.hora_inicio, - hora_max_recoger: infoPrestamo.hora_max_recoger, - equipo: { - id_equipo: infoPrestamo.id_equipo, - equipo: infoPrestamo.equipo, - numero_inventario: infoPrestamo.numero_inventario, - u: infoPrestamo.u, - carrito: { - id_carrito: infoPrestamo.id_carrito, - carrito: infoPrestamo.carrito, - modulo: { - id_modulo: infoPrestamo.id_modulo, - modulo: infoPrestamo.modulo, - institucion: { - id_institucion: infoPrestamo.id_institucion, - institucion: infoPrestamo.institucion, - }, - }, - tipoCarrito: { - id_tipo_carrito: infoPrestamo.id_tipo_carrito, - tipo_carrito: infoPrestamo.tipo_carrito, - }, - }, - status: { id_status: infoPrestamo.id_status }, - }, - }); + const prestamo = this.prestamoInfoViewToPrestamo(infoPrestamo); return this.prestamoPasscode(prestamo); }); @@ -733,7 +626,7 @@ export class PrestamoService { prestamoInfoByNumeroInventario( operador: Operador, numero_inventario: string, - ) { + ): Promise { return this.equipoService .findByNumeroInventario(operador.institucion, numero_inventario) .then((equipo) => @@ -746,42 +639,60 @@ export class PrestamoService { throw new NotFoundException( 'No existe un préstamo activo con este equipo de cómputo.', ); - return this.repository.create({ - id_prestamo: infoPrestamo.id_prestamo, - activo: infoPrestamo.activo === 1, - fecha_entrega: infoPrestamo.fecha_entrega, - fecha_inicio: infoPrestamo.fecha_inicio, - hora_fin: infoPrestamo.hora_fin, - hora_inicio: infoPrestamo.hora_inicio, - hora_max_recoger: infoPrestamo.hora_max_recoger, - equipo: { - id_equipo: infoPrestamo.id_equipo, - equipo: infoPrestamo.equipo, - carrito: { - id_carrito: infoPrestamo.id_carrito, - carrito: infoPrestamo.carrito, - modulo: { - id_modulo: infoPrestamo.id_modulo, - institucion: { id_institucion: infoPrestamo.id_institucion }, - }, - }, - status: { id_status: infoPrestamo.id_status }, - }, - usuario: { - id_usuario: infoPrestamo.id_usuario, - usuario: infoPrestamo.usuario, - nombre: infoPrestamo.nombre, - tipoUsuario: { id_tipo_usuario: infoPrestamo.id_tipo_usuario }, - }, - }); + return this.prestamoInfoViewToPrestamo(infoPrestamo); }); } + prestamoInfoViewToPrestamo(infoPrestamo: PrestamoInformacionView): Prestamo { + return this.repository.create({ + id_prestamo: infoPrestamo.id_prestamo, + activo: infoPrestamo.activo === 1, + cancelado_operador: infoPrestamo.cancelado_operador === 1, + cancelado_usuario: infoPrestamo.cancelado_usuario === 1, + fecha_entrega: infoPrestamo.fecha_entrega, + fecha_inicio: infoPrestamo.fecha_inicio, + hora_fin: infoPrestamo.hora_fin, + hora_inicio: infoPrestamo.hora_inicio, + hora_max_recoger: infoPrestamo.hora_max_recoger, + equipo: { + id_equipo: infoPrestamo.id_equipo, + equipo: infoPrestamo.equipo, + numero_inventario: infoPrestamo.numero_inventario, + u: infoPrestamo.u, + carrito: { + id_carrito: infoPrestamo.id_carrito, + carrito: infoPrestamo.carrito, + modulo: { + id_modulo: infoPrestamo.id_modulo, + modulo: infoPrestamo.modulo, + institucion: { + id_institucion: infoPrestamo.id_institucion, + institucion: infoPrestamo.institucion, + }, + }, + tipoCarrito: { + id_tipo_carrito: infoPrestamo.id_tipo_carrito, + tipo_carrito: infoPrestamo.tipo_carrito, + }, + }, + status: { id_status: infoPrestamo.id_status }, + }, + usuario: { + id_usuario: infoPrestamo.id_usuario, + usuario: infoPrestamo.usuario, + nombre: infoPrestamo.nombre, + tipoUsuario: { id_tipo_usuario: infoPrestamo.id_tipo_usuario }, + }, + }); + } + private prestamoPasscode(prestamo: Prestamo) { + // Si es locker if ( prestamo.equipo.carrito.tipoCarrito.id_tipo_carrito === 4 || prestamo.equipo.carrito.tipoCarrito.id_tipo_carrito === 5 ) + // Buscamos el passcode y se lo agregamos al préstamo return this.passcodeService .findByPrestamo(prestamo) .then((passcode) => ({ ...prestamo, passcode: passcode.passcode })); @@ -796,15 +707,13 @@ export class PrestamoService { motivo?: string, descripcion?: string, id_institucion_infraccion?: number, - ) { + ): Promise<{ message: string }> { const ahora = moment(); - // La resta ahora - hora_fin nos da la cantidad de tiempo que se paso el usuario - // en entregar el equipo a tiempo. Si es negativa es que fue antes de la hora_fin - const tardanza = Math.trunc(ahora.diff(moment(prestamo.hora_fin)) / 60000); - // Minutos que se tardo entre el tiempo configurable de la institución + const status = await this.statusService.findById(id_status); + const tardanza = Math.trunc(ahora.diff(moment(prestamo.hora_fin)) / 60000); // Si la resta ahora - hora_fin es positiva es que ya se tardo en entregar const semanasCastigo = Math.trunc( tardanza / modulo.institucion.tiempo_entrega, - ); + ); // Semanas de castigo correspondiente al tiempo de tardanza de cada institución this.validacionBasicaPrestamo(prestamo); this.validacionOperadorPrestamo(prestamo, operadorRegreso, modulo); @@ -814,19 +723,21 @@ export class PrestamoService { 'Aún no se ha entregado el equipo de cómputo al usuario.', ); if (id_institucion_infraccion && !descripcion) - throw new ConflictException('No se mandó la descripción de lo ocurrido.'); + throw new ConflictException( + 'No se mandó la descripción para el reporte de incidencia.', + ); + // Desactivamos préstamo prestamo.activo = false; prestamo.fecha_entrega = ahora.toDate(); prestamo.operadorRegreso = operadorRegreso; + // Reseteamos datos de equipo prestamo.equipo.u = null; - prestamo.equipo.status.id_status = id_status; - // Si semanasCastigo es mayor a 0 significa que hay multa + prestamo.equipo.status = status; + // Si semanasCastigo es mayor a 0 significa que hay multa por atraso if (semanasCastigo > 0) { const mensajeTardanza = `El usuario se tardó: ${tardanza} minutos en entregar el equipo de cómputo.`; - // Si se mando id_institucion_infraccion significa que ademas de entregar tarde, - // el usuario daño el equipo, por lo tanto tenemos que agregar la descripción del daño - // a motivo, y mandar la id_institucion_infraccion + // Si se mando id_institucion_infraccion significa que ademas de entregar tarde cometió una infracción if (id_institucion_infraccion) await this.multaService.create( operadorRegreso, @@ -836,7 +747,7 @@ export class PrestamoService { semanasCastigo, id_institucion_infraccion, ); - // Multa normal + // De lo contrario solo se multa por tardanza else await this.multaService.create( operadorRegreso, @@ -845,9 +756,9 @@ export class PrestamoService { mensajeTardanza, semanasCastigo, ); - } else if (id_institucion_infraccion) - // De lo contrario, si se mandó id_institucion_infraccion significa que - // el usuario solo solo daño el equipo + } + // De lo contrario, si se mandó id_institucion_infraccion significa que el usuario solo solo cometió una infracción + else if (id_institucion_infraccion) await this.multaService.create( operadorRegreso, modulo, @@ -856,17 +767,14 @@ export class PrestamoService { null, id_institucion_infraccion, ); - // Guardo los cambios del equipo + // Guardamos cambios en el equipo return this.equipoService .updateStatus(prestamo.equipo, operadorRegreso, motivo) - .then((_) => this.repository.save(prestamo)) // Guardo los cambios del préstamo + .then((_) => this.repository.save(prestamo)) // Guardamos cambios en el préstamo .then((_) => { - // Actualizo la interfaz del usuario + // Actualizamos la interfaz del usuario this.appGateway.actualizarUsuario(prestamo.usuario.id_usuario); - this.appGateway.actualizarOperador( - operadorRegreso.institucion.id_institucion, - ); - return { message: 'Se regresó el equipo de cómputo.' }; + return { message: 'Se regresó el equipo de cómputo correctamente.' }; }); } @@ -878,8 +786,7 @@ export class PrestamoService { motivo: string, descripcion?: string, id_institucion_infraccion?: number, - ) { - // Buscamos el prestamo por id prestamo y luego regreso el equipo + ): Promise<{ message: string }> { return this.findById(id_prestamo).then((prestamo) => this.regresar( operador, @@ -901,9 +808,7 @@ export class PrestamoService { motivo: string, descripcion?: string, id_institucion_infraccion?: number, - ) { - // Buscamos el prestamo por número de inventario y la institución del operador - // luego regreso el equipo + ): Promise<{ message: string }> { return this.findByNumeroInventario( operador.institucion, numero_inventario, @@ -920,17 +825,46 @@ export class PrestamoService { ); } - save(prestamo: Prestamo) { + save(prestamo: Prestamo): Promise { return this.repository.save(prestamo); } - validacionBasicaPrestamo(prestamo: Prestamo) { - // Validamos si el préstamo fue cancelado por el usuario + private validarInstitucionUsuario( + instituciones: InstitucionUsuario[], + modulo: Modulo, + ): InstitucionUsuario { + // Recorremos array de instituciones usuario + for (let i = 0; i < instituciones.length; i++) { + const institucion = instituciones[i].institucionCarrera.institucion; + + // Si encontramos una institución usuario cuyo id institución sea igual al del módulo enviado + if (institucion.id_institucion === modulo.institucion.id_institucion) { + // Validamos que este activo + if (!instituciones[i].activo) + throw new ForbiddenException( + `${this.mensajeNoPoderPedir()} tu cuenta esta desactivada en esta institución.`, + ); + // Validamos que no tenga multa + if (instituciones[i].multa) + throw new ForbiddenException( + `${this.mensajeNoPoderPedir()} tienes una multa activa.`, + ); + return instituciones[i]; + } + } + // Si no se encuentra una institución usuario que sea igual que la del módulo enviado sacamos error + throw new BadRequestException( + `${this.mensajeNoPoderPedir()} no perteneces a la institución del módulo seleccionado.`, + ); + } + + private validacionBasicaPrestamo(prestamo: Prestamo): void { + // Validamos si el préstamo ya fue cancelado por el usuario if (prestamo.cancelado_usuario) throw new ConflictException( 'Este préstamo fue cancelado por el usuario.', ); - // Validamos si el préstamo fue cancelado por el operador + // Validamos si el préstamo ya fue cancelado por el operador if (prestamo.cancelado_operador) throw new ConflictException( 'Este préstamo fue cancelado por un operador.', @@ -940,36 +874,12 @@ export class PrestamoService { throw new ConflictException('Este préstamo ya no se encuentra activo.'); } - validarInstitucionUsuario( - instituciones: InstitucionUsuario[], - modulo: Modulo, - ) { - for (let i = 0; i < instituciones.length; i++) { - const institucion = instituciones[i].institucionCarrera.institucion; - - if (institucion.id_institucion === modulo.institucion.id_institucion) { - if (!instituciones[i].activo) - throw new ForbiddenException( - `${this.mensajeNoPoderPedir()} tu cuenta esta desactivada en esta institución.`, - ); - if (instituciones[i].multa) - throw new ForbiddenException( - `${this.mensajeNoPoderPedir()} tienes una multa activa.`, - ); - return institucion; - } - } - throw new BadRequestException( - `${this.mensajeNoPoderPedir()} no perteneces a la institución del módulo seleccionado.`, - ); - } - private validacionOperadorPrestamo( prestamo: Prestamo, operador: Operador, - modulo: Modulo, - ) { - // Validamos que el prestamo pertenezca a la institución + modulo?: Modulo, + ): void { + // Validamos que el prestamo pertenezca a la institución del operador if ( operador.institucion.id_institucion != prestamo.equipo.carrito.modulo.institucion.id_institucion @@ -982,7 +892,7 @@ export class PrestamoService { throw new ConflictException('Este préstamo no pertenece a tu módulo.'); } - private viewToPrestamo(infoPrestamo: InformacionPrestamoView) { + private viewToPrestamo(infoPrestamo: InformacionPrestamoView): Prestamo { return this.repository.create({ id_prestamo: infoPrestamo.id_prestamo, activo: infoPrestamo.activo === 1,