import { GetUnitChildDto } from '../dtos/get.unit.dto'; import { SpaceTypeRepository } from '../../../libs/common/src/modules/space-type/repositories/space.type.repository'; import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { SpaceRepository } from '@app/common/modules/space/repositories'; import { AddUnitDto } from '../dtos'; import { UnitChildInterface, UnitParentInterface, GetUnitByUuidInterface, } from '../interface/unit.interface'; import { SpaceEntity } from '@app/common/modules/space/entities'; @Injectable() export class UnitService { constructor( private readonly spaceRepository: SpaceRepository, private readonly spaceTypeRepository: SpaceTypeRepository, ) {} async addUnit(addUnitDto: AddUnitDto) { try { const spaceType = await this.spaceTypeRepository.findOne({ where: { type: 'unit', }, }); await this.spaceRepository.save({ spaceName: addUnitDto.unitName, parent: { uuid: addUnitDto.floorUuid }, spaceType: { uuid: spaceType.uuid }, }); } catch (err) { throw new HttpException(err.message, HttpStatus.INTERNAL_SERVER_ERROR); } } async getUnitByUuid(unitUuid: string): Promise { try { const unit = await this.spaceRepository.findOne({ where: { uuid: unitUuid, spaceType: { type: 'unit', }, }, relations: ['spaceType'], }); if (!unit) { throw new HttpException('Unit not found', HttpStatus.NOT_FOUND); } return { uuid: unit.uuid, createdAt: unit.createdAt, updatedAt: unit.updatedAt, name: unit.spaceName, type: unit.spaceType.type, }; } catch (err) { throw new HttpException( err.message, err.status || HttpStatus.INTERNAL_SERVER_ERROR, ); } } async getUnitChildByUuid( unitUuid: string, getUnitChildDto: GetUnitChildDto, ): Promise { const { includeSubSpaces, page, pageSize } = getUnitChildDto; const space = await this.spaceRepository.findOneOrFail({ where: { uuid: unitUuid }, relations: ['children', 'spaceType'], }); if (space.spaceType.type !== 'unit') { throw new HttpException('Unit not found', HttpStatus.NOT_FOUND); } const totalCount = await this.spaceRepository.count({ where: { parent: { uuid: space.uuid } }, }); const children = await this.buildHierarchy( space, includeSubSpaces, page, pageSize, ); return { uuid: space.uuid, name: space.spaceName, type: space.spaceType.type, totalCount, children, }; } private async buildHierarchy( space: SpaceEntity, includeSubSpaces: boolean, page: number, pageSize: number, ): Promise { const children = await this.spaceRepository.find({ where: { parent: { uuid: space.uuid } }, relations: ['spaceType'], skip: (page - 1) * pageSize, take: pageSize, }); if (!children || children.length === 0 || !includeSubSpaces) { return children .filter( (child) => child.spaceType.type !== 'unit' && child.spaceType.type !== 'floor' && child.spaceType.type !== 'community', ) // Filter remaining unit and floor and community types .map((child) => ({ uuid: child.uuid, name: child.spaceName, type: child.spaceType.type, })); } const childHierarchies = await Promise.all( children .filter( (child) => child.spaceType.type !== 'unit' && child.spaceType.type !== 'floor' && child.spaceType.type !== 'community', ) // Filter remaining unit and floor and community types .map(async (child) => ({ uuid: child.uuid, name: child.spaceName, type: child.spaceType.type, children: await this.buildHierarchy(child, true, 1, pageSize), })), ); return childHierarchies; } async getUnitParentByUuid(unitUuid: string): Promise { try { const unit = await this.spaceRepository.findOne({ where: { uuid: unitUuid, spaceType: { type: 'unit', }, }, relations: ['spaceType', 'parent', 'parent.spaceType'], }); if (!unit) { throw new HttpException('Unit not found', HttpStatus.NOT_FOUND); } return { uuid: unit.uuid, name: unit.spaceName, type: unit.spaceType.type, parent: { uuid: unit.parent.uuid, name: unit.parent.spaceName, type: unit.parent.spaceType.type, }, }; } catch (err) { throw new HttpException( err.message, err.status || HttpStatus.INTERNAL_SERVER_ERROR, ); } } }