From 6864e000b8b3956d6451a6d81567d6fb3f9b5b64 Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Thu, 6 Mar 2025 02:33:48 +0300 Subject: [PATCH] add space linking when create or update space --- .../services/space-model.service.ts | 40 ++++++++++++++--- src/space/dtos/update.space.dto.ts | 7 +++ src/space/services/space.service.ts | 44 +++++++++++++++++-- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/space-model/services/space-model.service.ts b/src/space-model/services/space-model.service.ts index c25fcbd..f5d2cf3 100644 --- a/src/space-model/services/space-model.service.ts +++ b/src/space-model/services/space-model.service.ts @@ -40,6 +40,9 @@ import { ORPHAN_SPACE_NAME, } from '@app/common/constants/orphan-constant'; import { DeviceRepository } from '@app/common/modules/device/repositories'; +import { SpaceProductAllocationEntity } from '@app/common/modules/space/entities/space-product-allocation.entity'; +import { SubspaceEntity } from '@app/common/modules/space/entities/subspace/subspace.entity'; +import { SubspaceProductAllocationEntity } from '@app/common/modules/space/entities/subspace/subspace-product-allocation.entity'; @Injectable() export class SpaceModelService { @@ -387,10 +390,15 @@ export class SpaceModelService { async linkToSpace( space: SpaceEntity, spaceModel: SpaceModelEntity, + queryRunner?: QueryRunner, // Make queryRunner optional ): Promise { try { space.spaceModel = spaceModel; - await this.spaceRepository.save(space); + if (queryRunner) { + await queryRunner.manager.save(SpaceEntity, space); + } else { + await this.spaceRepository.save(space); + } const spaceProductAllocations = spaceModel.productAllocations.map( (modelAllocation) => @@ -401,8 +409,17 @@ export class SpaceModelService { tags: modelAllocation.tags, }), ); - await this.spaceProductAllocationRepository.save(spaceProductAllocations); + if (queryRunner) { + await queryRunner.manager.save( + SpaceProductAllocationEntity, + spaceProductAllocations, + ); + } else { + await this.spaceProductAllocationRepository.save( + spaceProductAllocations, + ); + } await Promise.all( spaceModel.subspaceModels.map(async (subspaceModel) => { const subspace = this.subspaceRepository.create({ @@ -411,7 +428,11 @@ export class SpaceModelService { space: space, }); - await this.subspaceRepository.save(subspace); + if (queryRunner) { + await queryRunner.manager.save(SubspaceEntity, subspace); + } else { + await this.subspaceRepository.save(subspace); + } const subspaceAllocations = subspaceModel.productAllocations.map( (modelAllocation) => @@ -424,9 +445,16 @@ export class SpaceModelService { ); if (subspaceAllocations.length) { - await this.subspaceProductAllocationRepository.save( - subspaceAllocations, - ); + if (queryRunner) { + await queryRunner.manager.save( + SubspaceProductAllocationEntity, + subspaceAllocations, + ); + } else { + await this.subspaceProductAllocationRepository.save( + subspaceAllocations, + ); + } } }), ); diff --git a/src/space/dtos/update.space.dto.ts b/src/space/dtos/update.space.dto.ts index 02efb86..31ff54f 100644 --- a/src/space/dtos/update.space.dto.ts +++ b/src/space/dtos/update.space.dto.ts @@ -58,4 +58,11 @@ export class UpdateSpaceDto { @ValidateNested({ each: true }) @Type(() => ModifyTagDto) tags?: ModifyTagDto[]; + @ApiProperty({ + description: 'UUID of the Space', + example: 'd290f1ee-6c54-4b01-90e6-d701748f0851', + }) + @IsString() + @IsOptional() + spaceModelUuid?: string; } diff --git a/src/space/services/space.service.ts b/src/space/services/space.service.ts index 53638c2..8df7cf5 100644 --- a/src/space/services/space.service.ts +++ b/src/space/services/space.service.ts @@ -104,10 +104,23 @@ export class SpaceService { this.subSpaceService.extractTagsFromSubspace(subspaces); const allTags = [...tags, ...subspaceTags]; this.validateUniqueTags(allTags); + if (spaceModelUuid) { + const hasDependencies = subspaces?.length > 0 || tags?.length > 0; + if (!hasDependencies && !newSpace.spaceModel) { + await this.spaceModelService.linkToSpace( + newSpace, + spaceModel, + queryRunner, + ); + } else if (hasDependencies) { + throw new HttpException( + `Space cannot be linked to a model because it has existing dependencies (subspaces or tags).`, + HttpStatus.BAD_REQUEST, + ); + } + } await Promise.all([ - spaceModelUuid && - this.createFromModel(spaceModelUuid, queryRunner, newSpace), direction && parent ? this.spaceLinkService.saveSpaceLink( parent.uuid, @@ -125,9 +138,8 @@ export class SpaceService { projectUuid, ) : Promise.resolve(), - tags?.length - ? this.createTags(tags, projectUuid, queryRunner, space) + ? this.createTags(tags, projectUuid, queryRunner, newSpace) : Promise.resolve(), ]); @@ -454,6 +466,30 @@ export class SpaceService { this.updateSpaceProperties(space, updateSpaceDto); + if (updateSpaceDto.spaceModelUuid) { + const spaceModel = await this.validationService.validateSpaceModel( + updateSpaceDto.spaceModelUuid, + ); + + const hasDependencies = + space.devices?.length > 0 || + space.subspaces?.length > 0 || + space.productAllocations?.length > 0; + + if (!hasDependencies && !space.spaceModel) { + await this.spaceModelService.linkToSpace( + space, + spaceModel, + queryRunner, + ); + } else if (hasDependencies) { + throw new HttpException( + `Space cannot be linked to a model because it has existing dependencies (devices, subspaces, or product allocations).`, + HttpStatus.BAD_REQUEST, + ); + } + } + const hasSubspace = updateSpaceDto.subspace?.length > 0; const hasTags = updateSpaceDto.tags?.length > 0;