diff --git a/src/equipo/dto/grafica.dto.ts b/src/equipo/dto/grafica.dto.ts new file mode 100644 index 0000000..82788a6 --- /dev/null +++ b/src/equipo/dto/grafica.dto.ts @@ -0,0 +1,30 @@ +import { IsArray, IsOptional, IsString } from "class-validator"; + +export class FiltrosGraficaDto { + + @IsOptional() + @IsArray() + @IsString({ each: true }) + adscripciones?: number[] + + @IsOptional() + @IsArray() + @IsString({ each: true }) + procesadores?: number[] + + @IsOptional() + @IsArray() + @IsString({ each: true }) + sistemas?: number[] + + @IsOptional() + @IsArray() + @IsString({ each: true }) + usos?: number[] + + @IsOptional() + @IsArray() + @IsString({ each: true }) + antiguedad?: string[] + +} \ No newline at end of file diff --git a/src/equipo/equipo.controller.ts b/src/equipo/equipo.controller.ts index 7b3c60a..856f385 100644 --- a/src/equipo/equipo.controller.ts +++ b/src/equipo/equipo.controller.ts @@ -19,10 +19,11 @@ import { UpdateEquipoDto } from './dto/update-equipo.dto'; import { AuthGuard } from '@nestjs/passport'; import { CreateEquipoDto } from './dto/create-equipo.dto'; import type { Response } from 'express'; +import { FiltrosGraficaDto } from './dto/grafica.dto'; @Controller('equipos') export class EquipoController { - constructor(private readonly equipoService: EquipoService) {} + constructor(private readonly equipoService: EquipoService) { } @UseGuards(AuthGuard('jwt')) @Get('buscar') async buscarEquipos( @@ -33,6 +34,14 @@ export class EquipoController { return this.equipoService.buscarEquipos(filtros, +page, +limit); } + @Post('grafica/:tipo') + async graficaProcesador( + @Param("tipo") tipo: 'antiguedad' | 'uso' | 'so' | 'procesador', + @Body() filtros: FiltrosGraficaDto + ) { + return this.equipoService.grafica(tipo, filtros); + } + @UseGuards(AuthGuard('jwt')) @Get('buscar/:inv') async serch(@Param('inv') inv: string) { @@ -92,6 +101,7 @@ export class EquipoController { findTiposEquipo() { return this.equipoService.findAllTiposEquipo(); } + @UseGuards(AuthGuard('jwt')) @Get('sistemas-operativos') findSistemasOperativos() { @@ -121,7 +131,7 @@ export class EquipoController { return this.equipoService.findAllPerifericos(); } - @UseGuards(AuthGuard('jwt')) + @Get('procesador-tipo-equipos') findProcesadorTipoEquipos() { return this.equipoService.findAllProcesadorTipoEquipos(); diff --git a/src/equipo/equipo.service.ts b/src/equipo/equipo.service.ts index 6173823..9ae7e67 100644 --- a/src/equipo/equipo.service.ts +++ b/src/equipo/equipo.service.ts @@ -27,6 +27,7 @@ import { CreateEquipoDto } from './dto/create-equipo.dto'; import { MovimientoService } from 'src/movimiento/movimiento.service'; import { Cron } from '@nestjs/schedule'; +import { FiltrosGraficaDto } from './dto/grafica.dto'; @Injectable() export class EquipoService { @@ -62,7 +63,7 @@ export class EquipoService { private readonly laboratorioRepo: Repository, @InjectRepository(Proyecto) private readonly proyectoRepo: Repository, - ) {} + ) { } async deleteEquipo(inventario: string): Promise<{ message: string }> { const equipo = await this.equipoRepository.findOne({ @@ -293,12 +294,12 @@ export class EquipoService { equipo.isImpresora ? { ...datosBase, periferico: { id_periferico: equipo.id_periferico } } : { - ...datosBase, - sistemaOperativo: { - id_sistema_operativo: equipo.id_sistema_operativo, - }, - procesador: { id_procesador: equipo.id_procesador }, + ...datosBase, + sistemaOperativo: { + id_sistema_operativo: equipo.id_sistema_operativo, }, + procesador: { id_procesador: equipo.id_procesador }, + }, ); let equip = await this.equipoRepository.save(nuevoEquipo); @@ -1117,6 +1118,94 @@ export class EquipoService { return Array.from(conteo.values()).sort((a, b) => b.total - a.total); } + + async grafica( + tipo: 'antiguedad' | 'uso' | 'so' | 'procesador', + filtros?: FiltrosGraficaDto + ) { + + const qb = this.equipoRepository + .createQueryBuilder('equipo') + .leftJoin('equipo.adscripcion', 'adscripcion') + .leftJoin('equipo.procesador', 'procesador') + .leftJoin('equipo.sistemaOperativo', 'sistemaOperativo') + .leftJoin('equipo.tipoUso', 'tipoUso') + + // filtros + + if (filtros?.adscripciones?.length) { + qb.andWhere('adscripcion.id_adscripcion IN (:...adscripciones)', { + adscripciones: filtros.adscripciones + }) + } + + if (filtros?.procesadores?.length) { + qb.andWhere('procesador.id_procesador IN (:...procesadores)', { + procesadores: filtros.procesadores + }) + } + + if (filtros?.sistemas?.length) { + qb.andWhere('sistemaOperativo.id_sistema_operativo IN (:...sistemas)', { + sistemas: filtros.sistemas + }) + } + + if (filtros?.usos?.length) { + qb.andWhere('tipoUso.id_uso IN (:...usos)', { + usos: filtros.usos + }) + } + + // selector dinámico + + switch (tipo) { + + case 'antiguedad': + + qb.select('equipo.antiguedad', 'antiguedad') + .addSelect('COUNT(*)', 'total') + .groupBy('equipo.antiguedad') + .orderBy(` + CASE + WHEN equipo.antiguedad = 'Menor a 2 años' THEN 1 + WHEN equipo.antiguedad = 'Entre 2 y 3 años' THEN 2 + WHEN equipo.antiguedad = 'Entre 4 y 5 años' THEN 3 + WHEN equipo.antiguedad = 'Mayor a 6 años' THEN 4 + END + `) + + break + + case 'uso': + + qb.select('tipoUso.tipo_uso', 'uso') + .addSelect('COUNT(*)', 'total') + .groupBy('tipoUso.tipo_uso') + + break + + case 'so': + + qb.select('sistemaOperativo.sistema_operativo', 'so') + .addSelect('COUNT(*)', 'total') + .groupBy('sistemaOperativo.sistema_operativo') + + break + + case 'procesador': + + qb.select('procesador.procesador', 'procesador') + .addSelect('COUNT(*)', 'total') + .groupBy('procesador.procesador') + + break + + } + return qb.getRawMany() + + } + } let estado_excluidos = ['DE BAJA'];