import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'; import { UpdateMesaDto } from './dto/update-mesa.dto'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Mesa } from './entities/mesa.entity'; @Injectable() export class MesaService { constructor( @InjectRepository(Mesa) private readonly mesaRepository: Repository, ) { } async asignarMesa(idUsuario: number, idMesa: number) { const yaTieneMesa = await this.mesaRepository.findOne({ where: { id_mesa: idMesa } }); if (yaTieneMesa) { throw new BadRequestException('El usuario ya tiene una mesa asignada'); } const mesa = await this.mesaRepository.findOne({ where: { id_mesa: idMesa } }); if (!mesa) { throw new NotFoundException('Mesa no existe'); } mesa.activo = false; await this.mesaRepository.save(mesa); return await this.mesaRepository.save({ id_usuario: idUsuario, id_mesa: idMesa, }); } async findAll(): Promise { return await this.mesaRepository.find(); } async findAllActivo(): Promise { const mesas = await this.mesaRepository .createQueryBuilder('mesa') .andWhere('mesa.activo = true') .andWhere((qb) => { const subQuery = qb .subQuery() .select('bitacora_mesa.id_mesa') .from('bitacora_mesa', 'bitacora_mesa') .where( `TIMESTAMPDIFF( SECOND, NOW(), DATE_ADD(bitacora_mesa.tiempo_entrada, INTERVAL bitacora_mesa.tiempo_asignado MINUTE) ) > 0`, ) .getQuery(); return `mesa.id_mesa NOT IN ${subQuery}`; }) .orderBy('mesa.id_mesa', 'ASC') .getMany(); if (!mesas.length) { throw new NotFoundException('No usable table found'); } return mesas; } async updateActivo(id: number, updateMesaDto: UpdateMesaDto) { const mesa = await this.mesaRepository.findOne({ where: { id_mesa: id } }); if (!mesa) { throw new NotFoundException(`La mesa no fue encontrada`); } mesa.activo = updateMesaDto.activo; return this.mesaRepository.save(mesa); } async toggleActivo(id_mesa: number) { if (Number.isNaN(id_mesa)) { throw new BadRequestException('ID de mesa inválido'); } const mesa = await this.mesaRepository.findOne({ where: { id_mesa }, }); if (!mesa) { throw new NotFoundException('Mesa no encontrada'); } let activoActual: boolean; if (Buffer.isBuffer(mesa.activo)) { activoActual = mesa.activo[0] === 1; } else { activoActual = Boolean(mesa.activo); } const nuevoActivo = !activoActual; await this.mesaRepository.update(id_mesa, { activo: nuevoActivo, }); return { message: 'Estado de mesa actualizado', id_mesa, activo: nuevoActivo, }; } findActiveMesas() { return this.mesaRepository .createQueryBuilder('mesa') .select([ 'mesa.id_mesa AS id_mesa', ` EXISTS ( SELECT 1 FROM bitacora_mesa bm WHERE bm.id_mesa = mesa.id_mesa AND TIMESTAMPDIFF( SECOND, NOW(), DATE_ADD(bm.tiempo_entrada, INTERVAL bm.tiempo_asignado MINUTE) ) > 0 ) AS ocupado `, ]) .where('mesa.activo = 1') .orderBy('mesa.id_mesa', 'ASC') .getRawMany(); } }