pcpuma_unam_api/src/prestamo/prestamo.service.ts
2022-10-24 09:55:13 -05:00

954 lines
34 KiB
TypeScript

import * as moment from 'moment';
import {
BadRequestException,
ConflictException,
ForbiddenException,
forwardRef,
Inject,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import {
FindManyOptions,
FindOptionsWhere,
LessThanOrEqual,
Like,
MoreThanOrEqual,
Repository,
} from 'typeorm';
import { AppGateway } from '../app.gateway';
import { Institucion } from '../institucion/entity/institucion.entity';
import { InstitucionUsuario } from '../institucion-usuario/entity/institucion-usuario.entity';
import { Modulo } from '../modulo/entity/modulo.entity';
import { Operador } from '../operador/entity/operador.entity';
import { Prestamo } from './entity/prestamo.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';
import { InformacionPrestamoView } from './entity/views/informacion-prestamo.view';
import { EquipoService } from '../equipo/equipo.service';
import { InstitucionService } from '../institucion/institucion.service';
import { InstitucionDiaService } from '../institucion-dia/institucion-dia.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 { ModuloService } from '../modulo/modulo.service';
import { MultaService } from '../multa/multa.service';
import { OperadorService } from '../operador/operador.service';
import { TipoUsuarioService } from '../tipo-usuario/tipo-usuario.service';
import { UsuarioService } from '../usuario/usuario.service';
@Injectable()
export class PrestamoService {
constructor(
@InjectRepository(Prestamo) private repository: Repository<Prestamo>,
@InjectRepository(InformacionPrestamoView)
private informacionPrestamoView: Repository<InformacionPrestamoView>,
@InjectRepository(FullInformacionPrestamoView)
private fullInformacionPrestamoView: Repository<FullInformacionPrestamoView>,
@InjectRepository(PrestamoInformacionView)
private prestamoInformacionView: Repository<PrestamoInformacionView>,
private appGateway: AppGateway,
private equipoService: EquipoService,
private institucionService: InstitucionService,
private institucionDiaService: InstitucionDiaService,
private institucionProgramaService: InstitucionProgramaService,
private institucionTipoCarritoService: InstitucionTipoCarritoService,
private institucionTipoEntradaService: InstitucionTipoEntradaService,
private moduloService: ModuloService,
@Inject(forwardRef(() => MultaService))
private multaService: MultaService,
private operadorService: OperadorService,
private tipoUsuarioService: TipoUsuarioService,
private usuarioService: UsuarioService,
) {}
async cancelarOperador(
operadorRegreso: Operador,
id_prestamo: number,
motivo: string,
) {
const ahora = moment();
const prestamo = await this.findInfoPrestamoById(id_prestamo);
this.validacionBasicaPrestamo(prestamo);
this.validacionOperadorPrestamo(prestamo, operadorRegreso);
prestamo.activo = false;
prestamo.fecha_entrega = ahora.toDate();
prestamo.cancelado_operador = true;
prestamo.operadorRegreso = operadorRegreso;
prestamo.equipo.u = null;
prestamo.equipo.status.id_status = 6;
return this.equipoService
.updateStatus(prestamo.equipo, operadorRegreso, motivo)
.then((_) => this.repository.save(prestamo))
.then((_) => {
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, id_prestamo: number) {
const ahora = moment();
const prestamo = await this.findInfoPrestamoById(id_prestamo);
this.validacionBasicaPrestamo(prestamo);
if (prestamo.equipo.status.id_status === 3)
throw new ConflictException(
'No puedes cancelar este préstamo una vez se te entregó el equipo.',
);
if (usuario.id_usuario != prestamo.usuario.id_usuario)
throw new ConflictException(
'No puedes cancelar este préstamo porque no te pretenece.',
);
prestamo.activo = false;
prestamo.fecha_entrega = ahora.toDate();
prestamo.cancelado_usuario = true;
prestamo.equipo.u = null;
prestamo.equipo.status.id_status = 1;
return this.equipoService
.updateStatus(prestamo.equipo)
.then((_) => this.repository.save(prestamo))
.then((_) => {
this.appGateway.actualizarUsuario(prestamo.usuario.id_usuario);
this.appGateway.actualizarOperador(
prestamo.equipo.carrito.modulo.institucion.id_institucion,
);
return { message: 'Se canceló correctamente este préstamo.' };
});
}
async create(
usuario: Usuario,
id_modulo: number,
id_tipo_carrito: number,
id_programa?: number,
id_tipo_entrada?: number,
) {
const ahora = moment();
const ahoraStr = ahora.format('YYYY-MM-DD');
const sistema = { id_operador: 1 };
const modulo = await this.moduloService.findById(id_modulo);
const tipoCarrito =
await this.institucionTipoCarritoService.findTipoCarritoById(
id_tipo_carrito,
);
const institucionDia =
await this.institucionDiaService.findByInstitucionDia(
modulo.institucion,
ahora.weekday(),
);
const horaMin = institucionDia
? moment(`${ahoraStr} ${institucionDia.hora_inicio}`)
: null;
const horaExtra = institucionDia
? moment(`${ahoraStr} ${institucionDia.hora_extra}`)
: null;
const programa = id_programa
? await this.institucionProgramaService.findProgramaById(id_programa)
: null;
const tipoEntrada = id_tipo_entrada
? await this.institucionTipoEntradaService.findTipoEntradaById(
id_tipo_entrada,
)
: null;
if (ahora.weekday() === 0)
throw new ConflictException('No hay servicio los días domingo.');
this.validarInstitucionUsuario(usuario.instituciones, modulo);
if (!institucionDia.activo)
throw new ConflictException(
'El día de hoy no hay servicio de préstamo de equipos.',
);
if (ahora < horaMin)
throw new ConflictException(
`El servicio inicia a las ${institucionDia.hora_inicio} el día de hoy.`,
);
if (ahora >= horaExtra)
throw new ConflictException(
`El servicio terminó a las ${institucionDia.hora_extra} el día de hoy.`,
);
for (let i = 0; i < institucionDia.horasExcepcion.length; i++) {
const horaFin = moment(
`${ahoraStr} ${institucionDia.horasExcepcion[i].hora_fin}`,
);
const horaInicio = moment(
`${ahoraStr} ${institucionDia.horasExcepcion[i].hora_inicio}`,
);
if (ahora > horaInicio && ahora < horaFin)
throw new ConflictException(
`Se suspendió temporalmente el servicio de ${institucionDia.horasExcepcion[i].hora_inicio} a ${institucionDia.horasExcepcion[i].hora_fin}.`,
);
}
return this.informacionPrestamoView
.findOne({ where: { activo: 1, id_usuario: usuario.id_usuario } })
.then((existePrestamo) => {
if (existePrestamo)
throw new ConflictException(
'Este usuario ya tiene un préstamo activo.',
);
return this.equipoService.findEquipo(
usuario.id_usuario,
modulo,
tipoCarrito,
programa,
tipoEntrada,
);
})
.then((equipo) =>
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,
usuario,
}),
),
)
.then((prestamo) => {
this.appGateway.actualizarOperador(modulo.institucion.id_institucion);
return prestamo;
});
}
async desactivarPrestamos() {
const ahora = moment();
return this.informacionPrestamoView
.find({ where: { activo: 1, id_status: 2 } })
.then(async (infoPrestamo) => {
for (let i = 0; i < infoPrestamo.length; i++) {
const prestamo = this.viewToPrestamo(infoPrestamo[i]);
if (ahora.diff(moment(prestamo.hora_max_recoger)) > 0) {
prestamo.activo = false;
prestamo.cancelado_operador = true;
prestamo.equipo.u = null;
prestamo.equipo.status.id_status = 1;
await this.repository
.save(prestamo)
.then((_) => this.equipoService.updateStatus(prestamo.equipo))
.then((_) => {
this.appGateway.actualizarOperador(
prestamo.equipo.carrito.modulo.institucion.id_institucion,
);
this.appGateway.actualizarUsuario(prestamo.usuario.id_usuario);
});
}
}
});
}
async entregar(
operadorEntrega: Operador,
id_prestamo: number,
modulo?: Modulo,
) {
const ahora = moment();
const ahoraStr = ahora.format('YYYY-MM-DD');
const prestamo = await this.findInfoPrestamoById(id_prestamo);
const institucionDia =
await this.institucionDiaService.findByInstitucionDia(
operadorEntrega.institucion,
ahora.weekday(),
);
const horaTope = institucionDia
? moment(`${ahoraStr} ${institucionDia.hora_tope}`)
: null;
const horaMax = institucionDia
? moment(`${ahoraStr} ${institucionDia.hora_fin}`)
: null;
this.validacionBasicaPrestamo(prestamo);
this.validacionOperadorPrestamo(prestamo, operadorEntrega, modulo);
if (prestamo.equipo.status.id_status === 3)
throw new ConflictException(
'Ya se entregó el equipo de cómputo al usuario.',
);
prestamo.hora_inicio = ahora.toDate();
prestamo.hora_fin =
ahora > horaMax
? horaTope.toDate()
: ahora.add(operadorEntrega.institucion.tiempo_prestamo, 'm').toDate();
prestamo.operadorEntrega = operadorEntrega;
prestamo.equipo.prestado = true;
prestamo.equipo.status.id_status = 3;
return this.repository
.save(prestamo)
.then((_) => this.equipoService.updateStatus(prestamo.equipo))
.then((_) => {
this.appGateway.actualizarUsuario(prestamo.usuario.id_usuario);
this.appGateway.actualizarOperador(
prestamo.equipo.carrito.modulo.institucion.id_institucion,
);
return prestamo.equipo;
});
}
async findAllByIdEquipo(id_equipo: number, pagina: number) {
return this.fullInformacionPrestamoView
.findAndCount({
where: { id_equipo },
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,
},
}),
);
return [prestamos, infoPrestamos[1]];
});
}
findAllByIdUsuario(id_usuario: number, pagina: number) {
return this.usuarioService
.findInfoUsuarioById(id_usuario)
.then((usuario) =>
this.fullInformacionPrestamoView.findAndCount({
where: { id_usuario: usuario.id_usuario },
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,
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,
},
}),
);
return [prestamos, infoPrestamos[1]];
});
}
findById(id_prestamo: number) {
return this.repository
.createQueryBuilder('p')
.innerJoinAndSelect('p.equipo', 'e')
.innerJoinAndSelect('p.usuario', 'u')
.innerJoinAndSelect('e.carrito', 'c')
.innerJoinAndSelect('e.programas', 'ps')
.innerJoinAndSelect('e.status', 's')
.innerJoinAndSelect('e.tiposEntradas', 'tes')
.innerJoinAndSelect('u.instituciones', 'is')
.innerJoinAndSelect('c.modulo', 'm')
.innerJoinAndSelect('c.tipoCarrito', 'tc')
.innerJoinAndSelect('ps.programa', 'pr')
.innerJoinAndSelect('tes.tipoEntrada', 'te')
.innerJoinAndSelect('is.institucionCarrera', 'ic')
.innerJoinAndSelect('ic.carrera', 'ca')
.innerJoinAndSelect('ic.institucion', 'in')
.innerJoinAndSelect('m.institucion', 'i')
.where('p.id_prestamo = :id_prestamo', {
id_prestamo,
})
.getOne()
.then((prestamo) => {
if (!prestamo) throw new NotFoundException('No existe este préstamo.');
return prestamo;
});
}
async findFullInfoPrestamoAll(filtros: {
pagina?: string;
activo?: string | boolean;
cancelado_operador?: string;
cancelado_usuario?: string;
carrito?: string;
equipo?: string;
fechaFin?: string;
fechaInicio?: string;
id_institucion?: 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;
}) {
const institucion = filtros.id_institucion
? await this.institucionService.findById(parseInt(filtros.id_institucion))
: null;
const modulo = filtros.id_modulo
? await this.moduloService.findInfoModuloById(parseInt(filtros.id_modulo))
: null;
const operadorEntrega = filtros.id_operador_entrega
? await this.operadorService.findInfoOperadorById(
parseInt(filtros.id_operador_entrega),
)
: null;
const operadorRegreso = filtros.id_operador_regreso
? await this.operadorService.findInfoOperadorById(
parseInt(filtros.id_operador_regreso),
)
: null;
const tipoCarrito = filtros.id_tipo_carrito
? await this.institucionTipoCarritoService.findTipoCarritoById(
parseInt(filtros.id_tipo_carrito),
)
: null;
const tipoUsuario = filtros.id_tipo_usuario
? await this.tipoUsuarioService.findById(
parseInt(filtros.id_tipo_usuario),
)
: null;
const options: FindManyOptions<FullInformacionPrestamoView> = {
order: { id_prestamo: 'DESC' },
};
const busqueda: FindOptionsWhere<FullInformacionPrestamoView> = {};
if (filtros.pagina) {
options.take = 25;
options.skip = (parseInt(filtros.pagina) - 1) * 25;
}
if (filtros.activo) {
if (typeof filtros.activo === 'boolean') {
busqueda.activo = filtros.activo ? 1 : 0;
options.order.id_prestamo = 'ASC';
} else busqueda.activo = filtros.activo === 'true' ? 1 : 0;
}
if (filtros.cancelado_operador)
busqueda.cancelado_operador =
filtros.cancelado_operador === 'true' ? 1 : 0;
if (filtros.cancelado_usuario)
busqueda.cancelado_usuario = filtros.cancelado_usuario === 'true' ? 1 : 0;
if (filtros.fechaInicio)
busqueda.fecha_inicio = MoreThanOrEqual(new Date(filtros.fechaInicio));
if (filtros.fechaFin)
busqueda.fecha_inicio = LessThanOrEqual(new Date(filtros.fechaFin));
if (filtros.id_prestamo)
busqueda.id_prestamo = parseInt(filtros.id_prestamo);
if (filtros.carrito) busqueda.carrito = Like(`%${filtros.carrito}%`);
if (filtros.equipo) busqueda.equipo = Like(`%${filtros.equipo}%`);
if (filtros.usuario) busqueda.usuario = Like(`%${filtros.usuario}%`);
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;
if (operadorEntrega)
busqueda.id_operador_entrega = operadorEntrega.id_operador;
if (operadorRegreso)
busqueda.id_operador_regreso = operadorRegreso.id_operador;
options.where = busqueda;
return this.fullInformacionPrestamoView
.findAndCount(options)
.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,
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,
},
}),
);
return [prestamos, infoPrestamos[1]];
});
}
findInfoPrestamoById(id_prestamo: number) {
return this.informacionPrestamoView
.findOne({ where: { id_prestamo } })
.then((infoPrestamo) => {
if (!infoPrestamo)
throw new NotFoundException('No existe este id préstamo.');
return this.viewToPrestamo(infoPrestamo);
});
}
findInfoPrestamoByNumeroInventario(
institucion: Institucion,
numero_inventario: string,
) {
return this.informacionPrestamoView
.findOne({
where: {
id_institucion: institucion.id_institucion,
numero_inventario,
},
})
.then((infoPrestamo) => {
if (!infoPrestamo)
throw new NotFoundException(
'No existe un equipo con este número de inventario en esta institución.',
);
return this.viewToPrestamo(infoPrestamo);
});
}
private mensajeNoPoderPedir() {
return 'No puedes pedir equipos de cómputo porque:';
}
prestamoInfoById(id_prestamo: number) {
return this.prestamoInformacionView
.findOne({ where: { id_prestamo } })
.then((infoPrestamo) => {
if (!infoPrestamo)
throw new NotFoundException('No existe este id préstamo.');
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 },
},
});
});
}
prestamoInfoByIdUsuario(id_usuario: number) {
return this.prestamoInformacionView
.findOne({ where: { activo: 1, id_usuario } })
.then((infoPrestamo) => {
if (!infoPrestamo)
throw new NotFoundException(
'Este usuario no tiene un préstamo activo.',
);
return 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,
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 },
},
});
});
}
prestamoInfoByNumeroInventario(
id_institucion: number,
numero_inventario: string,
) {
return this.institucionService
.findById(id_institucion)
.then((institucion) =>
this.equipoService.findByNumeroInventario(
institucion,
numero_inventario,
),
)
.then((equipo) =>
this.prestamoInformacionView.findOne({
where: { activo: 1, id_equipo: equipo.id_equipo },
}),
)
.then((infoPrestamo) => {
if (!infoPrestamo)
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 },
},
});
});
}
async regresar(
prestamo: Prestamo,
operadorRegreso: Operador,
id_status: number,
motivo?: string,
descripcion?: string,
id_institucion_infraccion?: number,
modulo?: Modulo,
) {
const ahora = moment();
const tardanza = Math.trunc(ahora.diff(moment(prestamo.hora_fin)) / 60000);
const semanasCastigo = Math.trunc(
tardanza / operadorRegreso.institucion.tiempo_entrega,
);
this.validacionBasicaPrestamo(prestamo);
this.validacionOperadorPrestamo(prestamo, operadorRegreso, modulo);
if (prestamo.equipo.status.id_status === 2)
throw new ConflictException(
'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.');
prestamo.activo = false;
prestamo.fecha_entrega = ahora.toDate();
prestamo.operadorRegreso = operadorRegreso;
prestamo.equipo.u = null;
prestamo.equipo.status.id_status = id_status;
if (semanasCastigo > 0) {
const mensajeTardanza = `El usaurio se tardó: ${tardanza} minutos en entregar el equipo de cómputo.`;
if (id_institucion_infraccion)
await this.multaService.create(
prestamo,
operadorRegreso,
`${mensajeTardanza} ${descripcion}`,
semanasCastigo,
id_institucion_infraccion,
);
else
await this.multaService.create(
prestamo,
operadorRegreso,
mensajeTardanza,
semanasCastigo,
);
} else if (id_institucion_infraccion)
await this.multaService.create(
prestamo,
operadorRegreso,
descripcion,
null,
id_institucion_infraccion,
);
return this.repository
.save(prestamo)
.then((_) =>
this.equipoService.updateStatus(
prestamo.equipo,
operadorRegreso,
motivo,
),
)
.then((_) => {
this.appGateway.actualizarUsuario(prestamo.usuario.id_usuario);
this.appGateway.actualizarOperador(
operadorRegreso.institucion.id_institucion,
);
return {
message: 'Se regresó el equipo de cómputo.',
};
});
}
regresarIdPrestamo(
operador: Operador,
id_prestamo: number,
id_status: number,
motivo: string,
descripcion?: string,
id_institucion_infraccion?: number,
modulo?: Modulo,
) {
return this.findInfoPrestamoById(id_prestamo).then((prestamo) =>
this.regresar(
prestamo,
operador,
id_status,
motivo,
descripcion,
id_institucion_infraccion,
modulo,
),
);
}
regresarNumeroInventario(
operador: Operador,
numero_inventario: string,
id_status: number,
motivo: string,
descripcion?: string,
id_institucion_infraccion?: number,
modulo?: Modulo,
) {
return this.findInfoPrestamoByNumeroInventario(
operador.institucion,
numero_inventario,
).then((prestamo) =>
this.regresar(
prestamo,
operador,
id_status,
motivo,
descripcion,
id_institucion_infraccion,
modulo,
),
);
}
validacionBasicaPrestamo(prestamo: Prestamo) {
if (prestamo.cancelado_usuario)
throw new ConflictException(
'Este préstamo fue cancelado por el usuario.',
);
if (prestamo.cancelado_operador)
throw new ConflictException(
'Este préstamo fue cancelado por un operador.',
);
if (!prestamo.activo)
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.`,
);
}
validacionOperadorPrestamo(
prestamo: Prestamo,
operador: Operador,
modulo?: Modulo,
) {
// Valido que el prestamo pertenezca a la institución
if (
operador.institucion.id_institucion !=
prestamo.equipo.carrito.modulo.institucion.id_institucion
)
throw new ConflictException(
'Este préstamo no pertenece a esta institución.',
);
// Valido que el prestamo pertenezca al módulo del operador
if (modulo && prestamo.equipo.carrito.modulo.id_modulo != modulo.id_modulo)
throw new ConflictException('Este préstamo no pertenece a tu módulo.');
}
private viewToPrestamo(infoPrestamo: InformacionPrestamoView) {
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,
institucion: { id_institucion: infoPrestamo.id_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 },
operadorRegreso: { id_operador: infoPrestamo.id_operador_regreso },
usuario: { id_usuario: infoPrestamo.id_usuario },
});
}
}