import { BadRequestException, Injectable, NotFoundException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Equipo } from './entities/equipo.entity'; import { CreateEquipoDto } from './dto/create-equipo.dto'; @Injectable() export class EquipoService { constructor( @InjectRepository(Equipo) private readonly equipoRepository: Repository, // private readonly alumnoInscritoService: AlumnoInscritoService, ) { } findAll() { return this.equipoRepository .createQueryBuilder('equipo') .innerJoinAndSelect('equipo.areaUbicacion', 'area') .innerJoinAndSelect('equipo.plataforma', 'plataforma') .where('area.extra = :extra', { extra: '0' }) .getMany(); } findActive() { return this.equipoRepository .createQueryBuilder('equipo') .select([ 'equipo.id_equipo AS id_equipo', 'equipo.nombre_equipo AS nombre_equipo', 'equipo.ubicacion AS ubicacion', 'equipo.ip AS ip', 'p.nombre AS plataforma', 'a.area AS area', ` EXISTS ( SELECT 1 FROM bitacora b WHERE b.id_equipo = equipo.id_equipo AND TIMESTAMPDIFF( SECOND, NOW(), DATE_ADD(b.tiempo_entrada, INTERVAL b.tiempo_asignado MINUTE) ) > 0 ) AS ocupado `, ]) .innerJoin('equipo.plataforma', 'p') .innerJoin('equipo.areaUbicacion', 'a') .where('equipo.activo = 1') .orderBy('equipo.ubicacion', 'ASC') .getRawMany(); } findDisable() { return this.equipoRepository .createQueryBuilder('equipo') .where('equipo.activo = :activo', { activo: 0 }) .innerJoinAndSelect('equipo.plataforma', 'p') .innerJoinAndSelect('equipo.areaUbicacion', 'a') .orderBy('equipo.ubicacion', 'ASC') .getMany(); } async findOne(ubicacion: string): Promise { const equipo = await this.equipoRepository.findOne({ where: { ubicacion }, }); if (!equipo) { throw new NotFoundException('not found'); } return equipo; } async findOnlyUsable(id_cuenta: number): Promise { const equipos = await this.equipoRepository .createQueryBuilder('equipo') .innerJoinAndSelect('equipo.plataforma', 'plataforma') .innerJoin('plataforma.alumnos_inscritos', 'ai') .innerJoin('ai.periodo', 'periodo') .innerJoin('equipo.areaUbicacion', 'area') .where('ai.id_cuenta = :id_cuenta', { id_cuenta }) .andWhere('periodo.activo = true') .andWhere('equipo.activo = true') .andWhere('ai.tiempo_disponible > 0') .andWhere('area.extra = 0') .andWhere((qb) => { const subQuery = qb .subQuery() .select('bitacora.id_equipo') .from('bitacora', 'bitacora') .where( `TIMESTAMPDIFF( SECOND, NOW(), DATE_ADD(bitacora.tiempo_entrada, INTERVAL bitacora.tiempo_asignado MINUTE) ) > 0`, ) .getQuery(); return `equipo.id_equipo NOT IN ${subQuery}`; }) .orderBy('equipo.ubicacion', 'ASC') .getMany(); if (!equipos.length) { throw new NotFoundException('No usable equipment found'); } return equipos; } async findOnlyBusy(): Promise { const equipos = await this.equipoRepository .createQueryBuilder('equipo') .innerJoinAndSelect('equipo.plataforma', 'plataforma') .innerJoinAndSelect('equipo.areaUbicacion', 'area') .andWhere('equipo.activo = true') .andWhere((qb) => { const subQuery = qb .subQuery() .select('bitacora.id_equipo') .from('bitacora', 'bitacora') .where( `TIMESTAMPDIFF( SECOND, NOW(), DATE_ADD(bitacora.tiempo_entrada, INTERVAL bitacora.tiempo_asignado MINUTE) ) > 0`, ) .getQuery(); return `equipo.id_equipo IN ${subQuery}`; }) .orderBy('equipo.ubicacion', 'ASC') .getMany(); if (!equipos.length) { throw new NotFoundException('No existen equipos en uso'); } return equipos; } async create(equipo: CreateEquipoDto) { const find = await this.equipoRepository.findOne({ where: { ubicacion: equipo.ubicacion }, }); if (find) { throw new BadRequestException('Ubicacion ya existente'); } const create = await this.equipoRepository.create(equipo); return this.equipoRepository.save(create); } async update(equipo: CreateEquipoDto) { return this.equipoRepository.update(equipo.id_equipo, equipo); } async toggleActivo(id_equipo: number) { if (Number.isNaN(id_equipo)) { throw new BadRequestException('ID de equipo inválido'); } const equipo = await this.equipoRepository.findOne({ where: { id_equipo }, }); if (!equipo) { throw new NotFoundException('Equipo no encontrado'); } let activoActual: boolean; if (Buffer.isBuffer(equipo.activo)) { activoActual = equipo.activo[0] === 1; } else { activoActual = Boolean(equipo.activo); } const nuevoActivo = !activoActual; await this.equipoRepository.update(id_equipo, { activo: nuevoActivo, }); return { message: 'Estado del equipo actualizado', id_equipo, activo: nuevoActivo, }; } async actualizarEquiposPorArea( id_area_ubicacion: number, activo: boolean, ) { const result = await this.equipoRepository.update( { id_area_ubicacion }, { activo }, ); return { message: 'Equipos actualizados correctamente', affected: result.affected, }; } } //IO