import { Injectable, NotFoundException } from '@nestjs/common'; import omit from 'lodash.omit'; import pick from 'lodash.pick'; import { BuildingService } from 'src/objects/building/building.service'; import { GroupService } from 'src/objects/group/group.service'; import { User } from 'src/objects/user/user.entity'; import { UserService } from 'src/objects/user/user.service'; import { BuildingFloorUpdateRequestDto } from './dto/buildings-floor-request.dto'; import { CreateBuildingRequestDto } from './dto/buildings-create-request.dto'; import { BuildingsUpdateRequestDto } from './dto/buildings-update-request.dto'; import { BuildingsCreateRoomRequestDto, BuildingsUpdateRoomRequestDto, } from './dto/buildings-create-room-request.dto'; import { PlanRendererService } from './plan-renderer/plan-renderer.service'; @Injectable() export class AppBuildingService { constructor( private readonly buildingService: BuildingService, private readonly userService: UserService, private readonly groupService: GroupService, private readonly planRenderService: PlanRendererService, ) {} async getUserBuildings(user: User) { return this.buildingService.getBuildingsByUserSub(user.sub); } async createBuilding(user: User, body: CreateBuildingRequestDto) { const getGroup = await this.groupService.getByIdAndMemberSub( body.group, user.sub, ); if (!getGroup) { throw new NotFoundException('Group not found'); } // TODO: validate color const newBuilding = await this.buildingService.saveBuilding({ ...pick(body, ['displayName', 'color', 'address']), groups: [getGroup], }); const newFloor = await this.buildingService.saveFloor({ displayName: 'Ground Floor', number: 0, plan: '{}', building: newBuilding, }); delete newFloor.building; newBuilding.floors = [newFloor]; return omit(newBuilding, ['groups']); } async updateBuilding( user: User, id: number, body: BuildingsUpdateRequestDto, ) { const building = await this.buildingService.getBuildingByIdAndUserSub( id, user.sub, ); if (!building) { throw new NotFoundException('Building not found'); } Object.assign(building, body); await this.buildingService.saveBuilding(building); return building; } async getBuildingById(user: User, id: number) { const building = await this.buildingService.getBuildingByIdAndUserSub( id, user.sub, ['floors', 'floors.rooms'], ); if (!building) { throw new NotFoundException('Building not found'); } return omit(building, ['groups']); } async getBuildingFloors(user: User, buildingId: number) { const floors = await this.buildingService.getFloorsByBuildingAndUserSub( buildingId, user.sub, ['rooms'], ); return floors.map((floor) => omit(floor, ['building'])); } async getBuildingFloor(user: User, buildingId: number, floorNumber: number) { const floor = await this.buildingService.getFloorByBuildingAndUserSub( buildingId, floorNumber, user.sub, ['rooms'], ); if (!floor) { throw new NotFoundException('Floor not found'); } return omit(floor, ['building']); } async updateBuildingFloor( user: User, body: BuildingFloorUpdateRequestDto, buildingId: number, floorNumber: number, ) { const floor = await this.buildingService.getFloorByBuildingAndUserSub( buildingId, floorNumber, user.sub, ['rooms'], ); if (!floor) { throw new NotFoundException('Floor not found'); } Object.assign(floor, body); this.planRenderService.renderFloor(floor); await this.buildingService.saveFloor(floor); return omit(floor, ['building']); } async addNewRoom( user: User, body: BuildingsCreateRoomRequestDto, buildingId: number, floorNumber: number, ) { const floor = await this.buildingService.getFloorByBuildingAndUserSub( buildingId, floorNumber, user.sub, ['building', 'rooms'], ); if (!floor) { throw new NotFoundException('Floor not found'); } const newRoom = await this.buildingService.saveRoom({ ...body, floor, building: floor.building, }); floor.rooms = [...floor.rooms, newRoom]; return omit(newRoom, ['building', 'floor']); } async getRoomsOnFloor(user: User, buildingId: number, floorNumber: number) { return this.buildingService.getRoomsOnFloorByBuildingAndUserSub( buildingId, floorNumber, user.sub, ); } async getRoomsInBuilding(user: User, buildingId: number) { const rooms = await this.buildingService.getRoomsByBuildingAndUserSub( buildingId, user.sub, ['floor'], ); return rooms.map((room) => ({ ...room, floor: pick(room.floor, ['id', 'displayName', 'number']), })); } async getRoom(user: User, buildingId: number, roomId: number) { const room = await this.buildingService.getRoomByBuildingAndUserSub( buildingId, roomId, user.sub, ); if (!room) { throw new NotFoundException('Room not found'); } return room; } async updateRoom( user: User, body: BuildingsUpdateRoomRequestDto, buildingId: number, roomId: number, ) { const room = await this.buildingService.getRoomByBuildingAndUserSub( buildingId, roomId, user.sub, ); if (!room) { throw new NotFoundException('Room not found'); } Object.assign(room, body); await this.buildingService.saveRoom(room); return room; } async deleteRoom(user: User, buildingId: number, roomId: number) { const room = await this.buildingService.getRoomByBuildingAndUserSub( buildingId, roomId, user.sub, ); if (!room) { throw new NotFoundException('Room not found'); } await this.buildingService.deleteRoom(room); return room; } }