Files
api-AT/src/equipo/equipo.service.ts
T
2026-03-17 12:07:26 -05:00

225 lines
5.7 KiB
TypeScript

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<Equipo>,
// 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 + 0', '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<Equipo> {
const equipo = await this.equipoRepository.findOne({
where: { ubicacion },
});
if (!equipo) {
throw new NotFoundException('not found');
}
return equipo;
}
async findOnlyUsable(id_cuenta: number): Promise<Equipo[]> {
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 + 0', 'ASC')
.getMany();
if (!equipos.length) {
throw new NotFoundException('No usable equipment found');
}
return equipos;
}
async findOnlyBusy(): Promise<Equipo[]> {
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