import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { GetOccupancyDurationBySpaceDto, GetOccupancyHeatMapBySpaceDto, } from '../dto/get-occupancy.dto'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { SpaceParamsDto } from '../dto/occupancy-params.dto'; import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service'; import { DataSource } from 'typeorm'; import { SQL_PROCEDURES_PATH } from '@app/common/constants/sql-query-path'; import { BaseResponseDto } from '@app/common/dto/base.response.dto'; @Injectable() export class OccupancyService { constructor( private readonly sqlLoader: SqlLoaderService, private readonly dataSource: DataSource, ) {} async getOccupancyDurationDataBySpace( params: SpaceParamsDto, query: GetOccupancyDurationBySpaceDto, ): Promise { const { monthDate } = query; const { spaceUuid } = params; try { const data = await this.executeProcedure( 'fact_daily_space_occupancy_duration', 'procedure_select_daily_space_occupancy_duration', [spaceUuid, monthDate], ); const formattedData = data.map((item) => ({ ...item, event_date: new Date(item.event_date).toLocaleDateString('en-CA'), // YYYY-MM-DD })); return this.buildResponse( `Occupancy duration data fetched successfully for ${spaceUuid} space`, formattedData, ); } catch (error) { console.error('Failed to fetch occupancy duration data', { error, spaceUuid, }); throw new HttpException( error.response?.message || 'Failed to fetch occupancy duration data', error.status || HttpStatus.INTERNAL_SERVER_ERROR, ); } } async getOccupancyHeatMapDataBySpace( params: SpaceParamsDto, query: GetOccupancyHeatMapBySpaceDto, ): Promise { const { year } = query; const { spaceUuid } = params; try { const data = await this.executeProcedure( 'fact_space_occupancy_count', 'proceduce_select_fact_space_occupancy', [spaceUuid, year], ); const formattedData = data.map((item) => ({ ...item, event_date: new Date(item.event_date).toLocaleDateString('en-CA'), // YYYY-MM-DD })); return this.buildResponse( `Occupancy heat map data fetched successfully for ${spaceUuid} space`, formattedData, ); } catch (error) { console.error('Failed to fetch occupancy heat map data', { error, spaceUuid, }); throw new HttpException( error.response?.message || 'Failed to fetch occupancy heat map data', error.status || HttpStatus.INTERNAL_SERVER_ERROR, ); } } private buildResponse(message: string, data: any[]) { return new SuccessResponseDto({ message, data, statusCode: HttpStatus.OK, }); } private async executeProcedure( procedureFolderName: string, procedureFileName: string, params: (string | number | null)[], ): Promise { const query = this.loadQuery(procedureFolderName, procedureFileName); return await this.dataSource.query(query, params); } private loadQuery(folderName: string, fileName: string): string { return this.sqlLoader.loadQuery(folderName, fileName, SQL_PROCEDURES_PATH); } }