mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-10 15:17:41 +00:00
added linking
This commit is contained in:
@ -5,11 +5,15 @@ import {
|
||||
SubspaceModelProductAllocationEntity,
|
||||
} from '@app/common/modules/space-model';
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { CreateSpaceModelDto, UpdateSpaceModelDto } from '../dtos';
|
||||
import {
|
||||
CreateSpaceModelDto,
|
||||
LinkSpacesToModelDto,
|
||||
UpdateSpaceModelDto,
|
||||
} from '../dtos';
|
||||
import { ProjectParam } from 'src/community/dtos';
|
||||
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
||||
import { SubSpaceModelService } from './subspace/subspace-model.service';
|
||||
import { DataSource, QueryRunner, SelectQueryBuilder } from 'typeorm';
|
||||
import { DataSource, In, QueryRunner, SelectQueryBuilder } from 'typeorm';
|
||||
import {
|
||||
TypeORMCustomModel,
|
||||
TypeORMCustomModelFindAllQuery,
|
||||
@ -21,7 +25,20 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||
import { CommandBus } from '@nestjs/cqrs';
|
||||
import { ProcessTagDto } from 'src/tags/dtos';
|
||||
import { SpaceModelProductAllocationService } from './space-model-product-allocation.service';
|
||||
import { SpaceRepository } from '@app/common/modules/space';
|
||||
import {
|
||||
SpaceProductAllocationRepository,
|
||||
SpaceRepository,
|
||||
} from '@app/common/modules/space';
|
||||
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
||||
import {
|
||||
SubspaceProductAllocationRepository,
|
||||
SubspaceRepository,
|
||||
} from '@app/common/modules/space/repositories/subspace.repository';
|
||||
import {
|
||||
ORPHAN_COMMUNITY_NAME,
|
||||
ORPHAN_SPACE_NAME,
|
||||
} from '@app/common/constants/orphan-constant';
|
||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||
|
||||
@Injectable()
|
||||
export class SpaceModelService {
|
||||
@ -33,6 +50,10 @@ export class SpaceModelService {
|
||||
private commandBus: CommandBus,
|
||||
private readonly spaceModelProductAllocationService: SpaceModelProductAllocationService,
|
||||
private readonly spaceRepository: SpaceRepository,
|
||||
private readonly spaceProductAllocationRepository: SpaceProductAllocationRepository,
|
||||
private readonly subspaceRepository: SubspaceRepository,
|
||||
private readonly subspaceProductAllocationRepository: SubspaceProductAllocationRepository,
|
||||
private readonly deviceRepository: DeviceRepository,
|
||||
) {}
|
||||
|
||||
async createSpaceModel(
|
||||
@ -286,6 +307,205 @@ export class SpaceModelService {
|
||||
}
|
||||
}
|
||||
|
||||
async linkSpaceModel(
|
||||
params: SpaceModelParam,
|
||||
dto: LinkSpacesToModelDto,
|
||||
): Promise<BaseResponseDto> {
|
||||
const project = await this.validateProject(params.projectUuid);
|
||||
|
||||
try {
|
||||
const spaceModel = await this.spaceModelRepository.findOne({
|
||||
where: { uuid: params.spaceModelUuid },
|
||||
relations: [
|
||||
'productAllocations',
|
||||
'subspaceModels',
|
||||
'subspaceModels.productAllocations',
|
||||
],
|
||||
});
|
||||
|
||||
if (!spaceModel) {
|
||||
throw new HttpException(
|
||||
`Space Model with UUID ${params.spaceModelUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
if (!spaceModel.productAllocations.length) {
|
||||
throw new HttpException(
|
||||
`Space Model ${params.spaceModelUuid} has no product allocations`,
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
|
||||
const spaces = await this.spaceRepository.find({
|
||||
where: { uuid: In(dto.spaceUuids), disabled: false },
|
||||
relations: [
|
||||
'spaceModel',
|
||||
'devices',
|
||||
'subspaces',
|
||||
'productAllocations',
|
||||
'subspaces.productAllocations',
|
||||
'community',
|
||||
],
|
||||
});
|
||||
|
||||
if (!spaces.length) {
|
||||
throw new HttpException(
|
||||
`No spaces found for the given UUIDs`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
spaces.map(async (space) => {
|
||||
const hasDependencies =
|
||||
space.devices.length > 0 ||
|
||||
space.subspaces.length > 0 ||
|
||||
space.productAllocations.length > 0;
|
||||
|
||||
if (!hasDependencies && !space.spaceModel) {
|
||||
await this.linkToSpace(space, spaceModel);
|
||||
} else if (dto.overwrite) {
|
||||
await this.overwriteSpace(space, project);
|
||||
await this.linkToSpace(space, spaceModel);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
return new SuccessResponseDto({
|
||||
message: 'Spaces linked successfully',
|
||||
data: dto.spaceUuids,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
`Failed to link space model: ${error.message}`,
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async linkToSpace(
|
||||
space: SpaceEntity,
|
||||
spaceModel: SpaceModelEntity,
|
||||
): Promise<void> {
|
||||
try {
|
||||
space.spaceModel = spaceModel;
|
||||
await this.spaceRepository.save(space);
|
||||
|
||||
const spaceProductAllocations = spaceModel.productAllocations.map(
|
||||
(modelAllocation) =>
|
||||
this.spaceProductAllocationRepository.create({
|
||||
space,
|
||||
inheritedFromModel: modelAllocation,
|
||||
product: modelAllocation.product,
|
||||
tags: modelAllocation.tags,
|
||||
}),
|
||||
);
|
||||
await this.spaceProductAllocationRepository.save(spaceProductAllocations);
|
||||
|
||||
if (!spaceModel.subspaceModels.length) {
|
||||
throw new HttpException(
|
||||
`Space Model ${spaceModel.uuid} has no subspaces`,
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
spaceModel.subspaceModels.map(async (subspaceModel) => {
|
||||
const subspace = this.subspaceRepository.create({
|
||||
subspaceName: subspaceModel.subspaceName,
|
||||
subSpaceModel: subspaceModel,
|
||||
space: space,
|
||||
});
|
||||
|
||||
await this.subspaceRepository.save(subspace);
|
||||
|
||||
const subspaceAllocations = subspaceModel.productAllocations.map(
|
||||
(modelAllocation) =>
|
||||
this.subspaceProductAllocationRepository.create({
|
||||
subspace,
|
||||
inheritedFromModel: modelAllocation,
|
||||
product: modelAllocation.product,
|
||||
tags: modelAllocation.tags,
|
||||
}),
|
||||
);
|
||||
|
||||
if (subspaceAllocations.length) {
|
||||
await this.subspaceProductAllocationRepository.save(
|
||||
subspaceAllocations,
|
||||
);
|
||||
}
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
`Failed to link space ${space.uuid} to space model ${spaceModel.uuid}: ${error.message}`,
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async overwriteSpace(
|
||||
space: SpaceEntity,
|
||||
project: ProjectEntity,
|
||||
): Promise<void> {
|
||||
try {
|
||||
if (space.productAllocations.length) {
|
||||
await this.spaceProductAllocationRepository.delete({
|
||||
uuid: In(
|
||||
space.productAllocations.map((allocation) => allocation.uuid),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
space.subspaces.map(async (subspace) => {
|
||||
await this.subspaceRepository.update(
|
||||
{ uuid: subspace.uuid },
|
||||
{ disabled: true },
|
||||
);
|
||||
|
||||
if (subspace.productAllocations.length) {
|
||||
await this.subspaceProductAllocationRepository.delete({
|
||||
uuid: In(
|
||||
subspace.productAllocations.map(
|
||||
(allocation) => allocation.uuid,
|
||||
),
|
||||
),
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
if (space.devices.length > 0) {
|
||||
const orphanSpace = await this.spaceRepository.findOne({
|
||||
where: {
|
||||
community: {
|
||||
name: `${ORPHAN_COMMUNITY_NAME}-${project.name}`,
|
||||
},
|
||||
spaceName: ORPHAN_SPACE_NAME,
|
||||
},
|
||||
});
|
||||
|
||||
if (!orphanSpace) {
|
||||
throw new HttpException(
|
||||
`Orphan space not found in community ${project.name}`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
await this.deviceRepository.update(
|
||||
{ uuid: In(space.devices.map((device) => device.uuid)) },
|
||||
{ spaceDevice: orphanSpace },
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to overwrite space ${space.uuid}: ${error.message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async validateName(modelName: string, projectUuid: string): Promise<void> {
|
||||
const isModelExist = await this.spaceModelRepository.findOne({
|
||||
where: { modelName, project: { uuid: projectUuid }, disabled: false },
|
||||
|
Reference in New Issue
Block a user