const moment = require('moment'); const { Op } = require('sequelize'); const io = require('../../socket'); const { validarNumeroEntero } = require('../../helper/validar'); const dbPath = '../../db/tablas'; const Carrito = require(`${dbPath}/Carrito`); const Equipo = require(`${dbPath}/Equipo`); const Modulo = require(`${dbPath}/Modulo`); const Prestamo = require(`${dbPath}/Prestamo`); const Programa = require(`${dbPath}/Programa`); const TipoCarrito = require(`${dbPath}/TipoCarrito`); const Usuario = require(`${dbPath}/Usuario`); const pedir = async (body) => { const ahora = moment(); const horaMax = moment(`${ahora.format('YYYY-MM-DD')} 18:45`); const horaMin = moment(`${ahora.format('YYYY-MM-DD')} 09:00`); const idUsuario = validarNumeroEntero(body.idUsuario, 'id usuario', true); const idTipoCarrito = validarNumeroEntero( body.idTipoCarrito, 'id tipo carrito', true ); const idPrograma = body.idPrograma ? validarNumeroEntero(body.idPrograma, 'id programa', true) : ''; const idModulo = idPrograma ? 1 : validarNumeroEntero(body.idModulo, 'id modulo', true); let whereEquipo = { idStatus: 4 }; let idEquipo; if (ahora.day() === 6 || ahora.day() === 0) throw new Error( 'No se puede pedir un equipo de cómputo los días sabados y domingos.' ); if (ahora > horaMax) throw new Error('Ya no se puede realizar un préstamo el día de hoy.'); if (ahora < horaMin) throw new Error('Aún es muy temprano para realizar un préstamo.'); return TipoCarrito.findOne({ where: { idTipoCarrito } }) .then((res) => { if (!res) throw new Error('No existe este tipo de equipo.'); return Modulo.findOne({ where: { idModulo } }); }) .then((res) => { if (!res) throw new Error('No existe este módulo.'); return Programa.findOne({ where: { idPrograma } }); }) .then((res) => { if (!res && idPrograma) throw new Error('No existe este programa.'); if (idPrograma) whereEquipo.idPrograma = idPrograma; return Usuario.findOne({ where: { idUsuario } }); }) .then((res) => { if (!res || !res.password) throw new Error('No existe este usuario.'); if (!res.activo) throw new Error('Este usuario no esta activo.'); if (res.multa) throw new Error( 'Tienes una multa vigente, no puedes solicitar un equipo de cómputo.' ); return Prestamo.findOne({ where: { idUsuario, [Op.or]: [ { activo: true }, { [Op.and]: [ { regresoInmediato: true }, { idOperadorRegreso: null }, ], }, ], }, }); }) .then((res) => { if (res) { if (res.regresoInmediato) throw new Error( 'No puedes pedir otro equipo de cómputo hasta que un operador confirme la entrega del equipo de cómputo del anterior préstamo.' ); throw new Error( 'Tienes un préstamo activo. No puedes solicitar otro equipo de cómputo.' ); } return Equipo.count({ where: whereEquipo, include: [ { model: Carrito, where: { idTipoCarrito, idModulo, activo: true }, }, ], }); }) .then((res) => { if (res === 0) throw new Error( 'No existe un equipo de cómputo con las características solicitadas. Intenta elegir otro tipo de equipo.' ); return Equipo.count({ where: { ...whereEquipo, prestado: false }, include: [ { model: Carrito, where: { idTipoCarrito, idModulo, activo: true }, }, ], }); }) .then(async (res) => { if (res === 0) await Equipo.update( { prestado: false }, { where: { ...whereEquipo, prestado: true }, include: [ { model: Carrito, where: { idTipoCarrito, idModulo, activo: true }, }, ], } ); return Equipo.findOne({ where: { ...whereEquipo, prestado: false }, include: [ { model: Carrito, where: { idTipoCarrito, idModulo, activo: true }, }, ], order: [ ['idCarrito', 'ASC'], ['equipo', 'ASC'], ], }); }) .then((res) => { if (!res) throw new Error( 'No hay un equipo de cómputo disponible con las características solicitadas. Intenta más tarde o elige otro tipo de equipo.' ); idEquipo = res.idEquipo; return Equipo.update({ idStatus: 1 }, { where: { idEquipo } }); }) .then(() => Prestamo.create({ horaMaxRecoger: ahora.add(10, 'm'), idUsuario, idEquipo, }) ) .then(() => { io.getIO().emit('actualizar', { idUsuario }); return { message: 'Haz solicitado un equipo de cómputo correctamente. Presentate al módulo señalado y muestra tu QR.', }; }); }; module.exports = pedir;