diff --git a/src/space-model/services/subspace/subspace-model.service.ts b/src/space-model/services/subspace/subspace-model.service.ts index dd3fe91..bd76a9c 100644 --- a/src/space-model/services/subspace/subspace-model.service.ts +++ b/src/space-model/services/subspace/subspace-model.service.ts @@ -243,15 +243,19 @@ export class SubSpaceModelService { ); if (subspaceModel.tags?.length) { - const modifyTagDtos = subspaceModel.tags.map((tag) => ({ - uuid: tag.uuid, - action: ModifyAction.DELETE, - })); - await this.tagModelService.modifyTags( + const modifyTagDtos: CreateTagModelDto[] = subspaceModel.tags.map( + (tag) => ({ + uuid: tag.uuid, + action: ModifyAction.ADD, + tag: tag.tag, + productUuid: tag.product.uuid, + }), + ); + await this.tagModelService.moveTags( modifyTagDtos, queryRunner, + subspaceModel.spaceModel, null, - subspaceModel, ); } } @@ -259,7 +263,7 @@ export class SubSpaceModelService { private async findOne(subspaceUuid: string): Promise { const subspace = await this.subspaceModelRepository.findOne({ where: { uuid: subspaceUuid, disabled: false }, - relations: ['tags', 'spaceModel'], + relations: ['tags', 'spaceModel', 'tags.product'], }); if (!subspace) { throw new HttpException( diff --git a/src/space-model/services/tag-model.service.ts b/src/space-model/services/tag-model.service.ts index 3f6a493..7394ed8 100644 --- a/src/space-model/services/tag-model.service.ts +++ b/src/space-model/services/tag-model.service.ts @@ -146,7 +146,7 @@ export class TagModelService { tag.subspaceModel = subspaceModel; } - if (subspaceModel === null && spaceModel) { + if (!subspaceModel && spaceModel) { await queryRunner.manager.update( this.tagModelRepository.target, { uuid: tag.uuid }, diff --git a/src/space/services/space.service.ts b/src/space/services/space.service.ts index 394fd9f..c1e21c6 100644 --- a/src/space/services/space.service.ts +++ b/src/space/services/space.service.ts @@ -172,8 +172,6 @@ export class SpaceService { ): Promise { const { communityUuid, projectUuid } = params; const { onlyWithDevices } = getSpaceDto; - console.log('onlyWithDevices', onlyWithDevices); - await this.validationService.validateCommunityAndProject( communityUuid, projectUuid, @@ -244,12 +242,53 @@ export class SpaceService { async findOne(params: GetSpaceParam): Promise { const { communityUuid, spaceUuid, projectUuid } = params; try { - const space = - await this.validationService.validateSpaceWithinCommunityAndProject( - communityUuid, - projectUuid, - spaceUuid, - ); + await this.validationService.validateCommunityAndProject( + communityUuid, + projectUuid, + ); + + const queryBuilder = this.spaceRepository + .createQueryBuilder('space') + .leftJoinAndSelect('space.parent', 'parent') + .leftJoinAndSelect( + 'space.children', + 'children', + 'children.disabled = :disabled', + { disabled: false }, + ) + .leftJoinAndSelect( + 'space.incomingConnections', + 'incomingConnections', + 'incomingConnections.disabled = :incomingConnectionDisabled', + { incomingConnectionDisabled: false }, + ) + .leftJoinAndSelect( + 'space.tags', + 'tags', + 'tags.disabled = :tagDisabled', + { tagDisabled: false }, + ) + .leftJoinAndSelect('tags.product', 'tagProduct') + .leftJoinAndSelect( + 'space.subspaces', + 'subspaces', + 'subspaces.disabled = :subspaceDisabled', + { subspaceDisabled: false }, + ) + .leftJoinAndSelect( + 'subspaces.tags', + 'subspaceTags', + 'subspaceTags.disabled = :subspaceTagsDisabled', + { subspaceTagsDisabled: false }, + ) + .leftJoinAndSelect('subspaceTags.product', 'subspaceTagProduct') + .where('space.community_id = :communityUuid', { communityUuid }) + .andWhere('space.spaceName != :orphanSpaceName', { + orphanSpaceName: ORPHAN_SPACE_NAME, + }) + .andWhere('space.disabled = :disabled', { disabled: false }); + + const space = await queryBuilder.getOne(); return new SuccessResponseDto({ message: `Space with ID ${spaceUuid} successfully fetched`, @@ -323,6 +362,7 @@ export class SpaceService { updateSpaceDto: UpdateSpaceDto, ): Promise { const { communityUuid, spaceUuid, projectUuid } = params; + const queryRunner = this.dataSource.createQueryRunner(); try { diff --git a/src/space/services/subspace/subspace-device.service.ts b/src/space/services/subspace/subspace-device.service.ts index 130da1d..e993716 100644 --- a/src/space/services/subspace/subspace-device.service.ts +++ b/src/space/services/subspace/subspace-device.service.ts @@ -11,6 +11,7 @@ import { ValidationService } from '../space-validation.service'; import { SubspaceRepository } from '@app/common/modules/space/repositories/subspace.repository'; import { In, QueryRunner } from 'typeorm'; import { DeviceEntity } from '@app/common/modules/device/entities'; +import { TagRepository } from '@app/common/modules/space'; @Injectable() export class SubspaceDeviceService { @@ -20,6 +21,7 @@ export class SubspaceDeviceService { private readonly tuyaService: TuyaService, private readonly productRepository: ProductRepository, private readonly validationService: ValidationService, + private readonly tagRepository: TagRepository, ) {} async listDevicesInSubspace( @@ -81,6 +83,24 @@ export class SubspaceDeviceService { const subspace = await this.findSubspace(subSpaceUuid); const device = await this.findDevice(deviceUuid); + if (device.tag?.subspace?.uuid !== subspace.uuid) { + await this.tagRepository.update( + { uuid: device.tag.uuid }, + { subspace }, + ); + } + + if (!device.tag) { + const tag = this.tagRepository.create({ + tag: `Tag ${this.findNextTag()}`, + product: device.productDevice, + subspace: subspace, + device: device, + }); + await this.tagRepository.save(tag); + device.tag = tag; + } + device.subspace = subspace; const newDevice = await this.deviceRepository.save(device); @@ -123,6 +143,26 @@ export class SubspaceDeviceService { ); } + if (device.tag?.subspace !== null) { + await this.tagRepository.update( + { uuid: device.tag.uuid }, + { subspace: null, space: device.subspace }, + ); + } + + if (!device.tag) { + const tag = this.tagRepository.create({ + tag: `Tag ${this.findNextTag()}`, + product: device.productDevice, + subspace: null, + space: device.spaceDevice, + device: device, + }); + + await this.tagRepository.save(tag); + device.tag = tag; + } + device.subspace = null; const updatedDevice = await this.deviceRepository.save(device); @@ -167,7 +207,7 @@ export class SubspaceDeviceService { private async findDevice(deviceUuid: string) { const device = await this.deviceRepository.findOne({ where: { uuid: deviceUuid }, - relations: ['subspace'], + relations: ['subspace', 'tag', 'tag.space', 'tag.subspace'], }); if (!device) { this.throwNotFound('Device', deviceUuid); @@ -234,4 +274,19 @@ export class SubspaceDeviceService { ); } } + + async findNextTag(): Promise { + const tags = await this.tagRepository.find({ select: ['tag'] }); + + const tagNumbers = tags + .map((t) => t.tag.match(/^Tag (\d+)$/)) + .filter((match) => match) + .map((match) => parseInt(match[1])) + .sort((a, b) => a - b); + + const nextTagNumber = tagNumbers.length + ? tagNumbers[tagNumbers.length - 1] + 1 + : 1; + return nextTagNumber; + } } diff --git a/src/space/services/tag/tag.service.ts b/src/space/services/tag/tag.service.ts index 03bc42d..f5059e6 100644 --- a/src/space/services/tag/tag.service.ts +++ b/src/space/services/tag/tag.service.ts @@ -8,7 +8,6 @@ import { import { TagModel } from '@app/common/modules/space-model'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { ProductService } from 'src/product/services'; -import { ModifyTagModelDto } from 'src/space-model/dtos'; import { CreateTagDto, ModifySubspaceDto } from 'src/space/dtos'; import { ModifyTagDto } from 'src/space/dtos/tag/modify-tag.dto'; import { QueryRunner } from 'typeorm'; @@ -33,7 +32,7 @@ export class TagService { const combinedTags = this.combineTags(tags, additionalTags); this.ensureNoDuplicateTags(combinedTags); - const tagEntitiesToCreate = tags.filter((tagDto) => tagDto.uuid === null); + const tagEntitiesToCreate = tags.filter((tagDto) => !tagDto.uuid); const tagEntitiesToUpdate = tags.filter((tagDto) => tagDto.uuid !== null); try { @@ -125,7 +124,7 @@ export class TagService { tag.subspace = subspace; } - if (subspace === null && space) { + if (!subspace && space) { await queryRunner.manager.update( this.tagRepository.target, { uuid: tag.uuid }, @@ -184,7 +183,7 @@ export class TagService { const contextSpace = space ?? subspace?.space; - if (contextSpace) { + if (contextSpace && tag.tag !== existingTag.tag) { await this.checkTagReuse( tag.tag, existingTag.product.uuid,