mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-26 19:24:53 +00:00
update space service
This commit is contained in:
@ -4,6 +4,7 @@ import { InviteSpaceEntity } from '../entities/invite-space.entity';
|
|||||||
import { SpaceLinkEntity } from '../entities/space-link.entity';
|
import { SpaceLinkEntity } from '../entities/space-link.entity';
|
||||||
import { SpaceEntity } from '../entities/space.entity';
|
import { SpaceEntity } from '../entities/space.entity';
|
||||||
import { TagEntity } from '../entities/tag.entity';
|
import { TagEntity } from '../entities/tag.entity';
|
||||||
|
import { SpaceProductAllocationEntity } from '../entities/space-product-allocation.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpaceRepository extends Repository<SpaceEntity> {
|
export class SpaceRepository extends Repository<SpaceEntity> {
|
||||||
@ -32,3 +33,9 @@ export class InviteSpaceRepository extends Repository<InviteSpaceEntity> {
|
|||||||
super(InviteSpaceEntity, dataSource.createEntityManager());
|
super(InviteSpaceEntity, dataSource.createEntityManager());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Injectable()
|
||||||
|
export class SpaceProductAllocationRepository extends Repository<SpaceProductAllocationEntity> {
|
||||||
|
constructor(private dataSource: DataSource) {
|
||||||
|
super(SpaceProductAllocationEntity, dataSource.createEntityManager());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -20,10 +20,14 @@ import { CqrsModule } from '@nestjs/cqrs';
|
|||||||
import {
|
import {
|
||||||
InviteSpaceRepository,
|
InviteSpaceRepository,
|
||||||
SpaceLinkRepository,
|
SpaceLinkRepository,
|
||||||
|
SpaceProductAllocationRepository,
|
||||||
SpaceRepository,
|
SpaceRepository,
|
||||||
TagRepository,
|
TagRepository,
|
||||||
} from '@app/common/modules/space';
|
} from '@app/common/modules/space';
|
||||||
import { SubspaceRepository } from '@app/common/modules/space/repositories/subspace.repository';
|
import {
|
||||||
|
SubspaceProductAllocationRepository,
|
||||||
|
SubspaceRepository,
|
||||||
|
} from '@app/common/modules/space/repositories/subspace.repository';
|
||||||
import {
|
import {
|
||||||
SpaceLinkService,
|
SpaceLinkService,
|
||||||
SpaceService,
|
SpaceService,
|
||||||
@ -40,6 +44,8 @@ import { TagService as NewTagService } from 'src/tags/services/tags.service';
|
|||||||
import { NewTagRepository } from '@app/common/modules/tag/repositories/tag-repository';
|
import { NewTagRepository } from '@app/common/modules/tag/repositories/tag-repository';
|
||||||
import { SpaceModelProductAllocationService } from './services/space-model-product-allocation.service';
|
import { SpaceModelProductAllocationService } from './services/space-model-product-allocation.service';
|
||||||
import { SubspaceModelProductAllocationService } from './services/subspace/subspace-model-product-allocation.service';
|
import { SubspaceModelProductAllocationService } from './services/subspace/subspace-model-product-allocation.service';
|
||||||
|
import { SpaceProductAllocationService } from 'src/space/services/space-product-allocation.service';
|
||||||
|
import { SubspaceProductAllocationService } from 'src/space/services/subspace/subspace-product-allocation.service';
|
||||||
|
|
||||||
const CommandHandlers = [
|
const CommandHandlers = [
|
||||||
PropogateUpdateSpaceModelHandler,
|
PropogateUpdateSpaceModelHandler,
|
||||||
@ -80,6 +86,10 @@ const CommandHandlers = [
|
|||||||
SpaceModelProductAllocationService,
|
SpaceModelProductAllocationService,
|
||||||
SubspaceModelProductAllocationRepoitory,
|
SubspaceModelProductAllocationRepoitory,
|
||||||
SubspaceModelProductAllocationService,
|
SubspaceModelProductAllocationService,
|
||||||
|
SpaceProductAllocationService,
|
||||||
|
SubspaceProductAllocationService,
|
||||||
|
SpaceProductAllocationRepository,
|
||||||
|
SubspaceProductAllocationRepository,
|
||||||
],
|
],
|
||||||
exports: [CqrsModule, SpaceModelService],
|
exports: [CqrsModule, SpaceModelService],
|
||||||
})
|
})
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
ValidateNested,
|
ValidateNested,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { AddSubspaceDto } from './subspace';
|
import { AddSubspaceDto } from './subspace';
|
||||||
import { CreateTagDto } from './tag';
|
import { ProcessTagDto } from 'src/tags/dtos';
|
||||||
|
|
||||||
export class AddSpaceDto {
|
export class AddSpaceDto {
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
@ -79,11 +79,11 @@ export class AddSpaceDto {
|
|||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'List of tags associated with the space model',
|
description: 'List of tags associated with the space model',
|
||||||
type: [CreateTagDto],
|
type: [ProcessTagDto],
|
||||||
})
|
})
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => CreateTagDto)
|
@Type(() => ProcessTagDto)
|
||||||
tags?: CreateTagDto[];
|
tags?: ProcessTagDto[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AddUserSpaceDto {
|
export class AddUserSpaceDto {
|
||||||
|
|||||||
334
src/space/services/space-product-allocation.service.ts
Normal file
334
src/space/services/space-product-allocation.service.ts
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
||||||
|
import { ProductEntity } from '@app/common/modules/product/entities';
|
||||||
|
import { SpaceProductAllocationRepository } from '@app/common/modules/space';
|
||||||
|
import { SpaceProductAllocationEntity } from '@app/common/modules/space/entities/space-product-allocation.entity';
|
||||||
|
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
||||||
|
import { NewTagEntity } from '@app/common/modules/tag';
|
||||||
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { In, QueryRunner } from 'typeorm';
|
||||||
|
import { SubspaceProductAllocationEntity } from '@app/common/modules/space/entities/subspace/subspace-product-allocation.entity';
|
||||||
|
import { ModifyTagDto } from '../dtos/tag/modify-tag.dto';
|
||||||
|
import { ModifySubspaceDto } from '../dtos';
|
||||||
|
import { ProcessTagDto } from 'src/tags/dtos';
|
||||||
|
import { TagService as NewTagService } from 'src/tags/services';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SpaceProductAllocationService {
|
||||||
|
constructor(
|
||||||
|
private readonly tagService: NewTagService,
|
||||||
|
private readonly spaceProductAllocationRepository: SpaceProductAllocationRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async createSpaceProductAllocations(
|
||||||
|
space: SpaceEntity,
|
||||||
|
processedTags: NewTagEntity[],
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
modifySubspaces?: ModifySubspaceDto[],
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
if (!processedTags.length) return;
|
||||||
|
|
||||||
|
const productAllocations: SpaceProductAllocationEntity[] = [];
|
||||||
|
const existingAllocations = new Map<
|
||||||
|
string,
|
||||||
|
SpaceProductAllocationEntity
|
||||||
|
>();
|
||||||
|
|
||||||
|
for (const tag of processedTags) {
|
||||||
|
let isTagNeeded = true;
|
||||||
|
|
||||||
|
if (modifySubspaces) {
|
||||||
|
const relatedSubspaces = await queryRunner.manager.find(
|
||||||
|
SubspaceProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
product: tag.product,
|
||||||
|
subspace: { space: { uuid: space.uuid } },
|
||||||
|
tags: { uuid: tag.uuid },
|
||||||
|
},
|
||||||
|
relations: ['subspace', 'tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const subspaceWithTag of relatedSubspaces) {
|
||||||
|
const modifyingSubspace = modifySubspaces.find(
|
||||||
|
(subspace) =>
|
||||||
|
subspace.action === ModifyAction.UPDATE &&
|
||||||
|
subspace.uuid === subspaceWithTag.subspace.uuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
modifyingSubspace &&
|
||||||
|
modifyingSubspace.tags &&
|
||||||
|
modifyingSubspace.tags.some(
|
||||||
|
(subspaceTag) =>
|
||||||
|
subspaceTag.action === ModifyAction.DELETE &&
|
||||||
|
subspaceTag.tagUuid === tag.uuid,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
isTagNeeded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTagNeeded) {
|
||||||
|
await this.validateTagWithinSpace(queryRunner, tag, space);
|
||||||
|
|
||||||
|
let allocation = existingAllocations.get(tag.product.uuid);
|
||||||
|
if (!allocation) {
|
||||||
|
allocation = await this.getAllocationByProduct(
|
||||||
|
tag.product,
|
||||||
|
space,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
|
if (allocation) {
|
||||||
|
existingAllocations.set(tag.product.uuid, allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allocation) {
|
||||||
|
allocation = this.createNewAllocation(space, tag, queryRunner);
|
||||||
|
productAllocations.push(allocation);
|
||||||
|
} else if (!allocation.tags.some((t) => t.uuid === tag.uuid)) {
|
||||||
|
allocation.tags.push(tag);
|
||||||
|
await this.saveAllocation(allocation, queryRunner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productAllocations.length > 0) {
|
||||||
|
await this.saveAllocations(productAllocations, queryRunner);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw this.handleError(
|
||||||
|
error,
|
||||||
|
'Failed to create space product allocations',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async updateSpaceProductAllocations(
|
||||||
|
dtos: ModifyTagDto[],
|
||||||
|
projectUuid: string,
|
||||||
|
space: SpaceEntity,
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
modifySubspace?: ModifySubspaceDto[],
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
await Promise.all([
|
||||||
|
this.processAddActions(
|
||||||
|
dtos,
|
||||||
|
projectUuid,
|
||||||
|
space,
|
||||||
|
queryRunner,
|
||||||
|
modifySubspace,
|
||||||
|
),
|
||||||
|
|
||||||
|
this.processDeleteActions(dtos, queryRunner),
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
throw this.handleError(error, 'Error while updating product allocations');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private async processDeleteActions(
|
||||||
|
dtos: ModifyTagDto[],
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
): Promise<SpaceProductAllocationEntity[]> {
|
||||||
|
try {
|
||||||
|
if (!dtos || dtos.length === 0) {
|
||||||
|
throw new Error('No DTOs provided for deletion.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const tagUuidsToDelete = dtos
|
||||||
|
.filter((dto) => dto.action === ModifyAction.DELETE && dto.tagUuid)
|
||||||
|
.map((dto) => dto.tagUuid);
|
||||||
|
|
||||||
|
if (tagUuidsToDelete.length === 0) return [];
|
||||||
|
|
||||||
|
const allocationsToUpdate = await queryRunner.manager.find(
|
||||||
|
SpaceProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: { tags: { uuid: In(tagUuidsToDelete) } },
|
||||||
|
relations: ['tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allocationsToUpdate || allocationsToUpdate.length === 0) return [];
|
||||||
|
|
||||||
|
const deletedAllocations: SpaceProductAllocationEntity[] = [];
|
||||||
|
const allocationUpdates: SpaceProductAllocationEntity[] = [];
|
||||||
|
|
||||||
|
for (const allocation of allocationsToUpdate) {
|
||||||
|
const updatedTags = allocation.tags.filter(
|
||||||
|
(tag) => !tagUuidsToDelete.includes(tag.uuid),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (updatedTags.length === allocation.tags.length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedTags.length === 0) {
|
||||||
|
deletedAllocations.push(allocation);
|
||||||
|
} else {
|
||||||
|
allocation.tags = updatedTags;
|
||||||
|
allocationUpdates.push(allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocationUpdates.length > 0) {
|
||||||
|
await queryRunner.manager.save(
|
||||||
|
SpaceProductAllocationEntity,
|
||||||
|
allocationUpdates,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deletedAllocations.length > 0) {
|
||||||
|
await queryRunner.manager.remove(
|
||||||
|
SpaceProductAllocationEntity,
|
||||||
|
deletedAllocations,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.delete()
|
||||||
|
.from('space_product_tags')
|
||||||
|
.where(
|
||||||
|
'space_product_allocation_id NOT IN ' +
|
||||||
|
queryRunner.manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.select('uuid')
|
||||||
|
.from(SpaceProductAllocationEntity, 'allocation')
|
||||||
|
.getQuery(),
|
||||||
|
)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
return deletedAllocations;
|
||||||
|
} catch (error) {
|
||||||
|
throw this.handleError(error, `Failed to delete tags in space`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private async processAddActions(
|
||||||
|
dtos: ModifyTagDto[],
|
||||||
|
projectUuid: string,
|
||||||
|
space: SpaceEntity,
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
modifySubspace?: ModifySubspaceDto[],
|
||||||
|
): Promise<void> {
|
||||||
|
const addDtos: ProcessTagDto[] = dtos
|
||||||
|
.filter((dto) => dto.action === ModifyAction.ADD)
|
||||||
|
.map((dto) => ({
|
||||||
|
name: dto.name,
|
||||||
|
productUuid: dto.productUuid,
|
||||||
|
uuid: dto.newTagUuid,
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (addDtos.length > 0) {
|
||||||
|
const processedTags = await this.tagService.processTags(
|
||||||
|
addDtos,
|
||||||
|
projectUuid,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.createSpaceProductAllocations(
|
||||||
|
space,
|
||||||
|
processedTags,
|
||||||
|
queryRunner,
|
||||||
|
modifySubspace,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private async validateTagWithinSpace(
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
tag: NewTagEntity,
|
||||||
|
space: SpaceEntity,
|
||||||
|
) {
|
||||||
|
const existingAllocationsForProduct = await queryRunner.manager.find(
|
||||||
|
SpaceProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: { space, product: tag.product },
|
||||||
|
relations: ['tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingTagsForProduct = existingAllocationsForProduct.flatMap(
|
||||||
|
(allocation) => allocation.tags,
|
||||||
|
);
|
||||||
|
|
||||||
|
const isDuplicateTag = existingTagsForProduct.some(
|
||||||
|
(existingTag) => existingTag.uuid === tag.uuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDuplicateTag) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Tag ${tag.uuid} is already allocated to product ${tag.product.uuid} within this space (${space.uuid}).`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getAllocationByProduct(
|
||||||
|
product: ProductEntity,
|
||||||
|
space: SpaceEntity,
|
||||||
|
queryRunner?: QueryRunner,
|
||||||
|
): Promise<SpaceProductAllocationEntity | null> {
|
||||||
|
return queryRunner
|
||||||
|
? queryRunner.manager.findOne(SpaceProductAllocationEntity, {
|
||||||
|
where: { space, product: product },
|
||||||
|
relations: ['tags'],
|
||||||
|
})
|
||||||
|
: this.spaceProductAllocationRepository.findOne({
|
||||||
|
where: { space, product: product },
|
||||||
|
relations: ['tags'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private createNewAllocation(
|
||||||
|
space: SpaceEntity,
|
||||||
|
tag: NewTagEntity,
|
||||||
|
queryRunner?: QueryRunner,
|
||||||
|
): SpaceProductAllocationEntity {
|
||||||
|
return queryRunner
|
||||||
|
? queryRunner.manager.create(SpaceProductAllocationEntity, {
|
||||||
|
space,
|
||||||
|
product: tag.product,
|
||||||
|
tags: [tag],
|
||||||
|
})
|
||||||
|
: this.spaceProductAllocationRepository.create({
|
||||||
|
space,
|
||||||
|
product: tag.product,
|
||||||
|
tags: [tag],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async saveAllocation(
|
||||||
|
allocation: SpaceProductAllocationEntity,
|
||||||
|
queryRunner?: QueryRunner,
|
||||||
|
) {
|
||||||
|
queryRunner
|
||||||
|
? await queryRunner.manager.save(SpaceProductAllocationEntity, allocation)
|
||||||
|
: await this.spaceProductAllocationRepository.save(allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async saveAllocations(
|
||||||
|
allocations: SpaceProductAllocationEntity[],
|
||||||
|
queryRunner?: QueryRunner,
|
||||||
|
) {
|
||||||
|
queryRunner
|
||||||
|
? await queryRunner.manager.save(
|
||||||
|
SpaceProductAllocationEntity,
|
||||||
|
allocations,
|
||||||
|
)
|
||||||
|
: await this.spaceProductAllocationRepository.save(allocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleError(error: any, message: string): HttpException {
|
||||||
|
return new HttpException(
|
||||||
|
error instanceof HttpException ? error.message : message,
|
||||||
|
error instanceof HttpException
|
||||||
|
? error.getStatus()
|
||||||
|
: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,7 +12,6 @@ import {
|
|||||||
AddSpaceDto,
|
AddSpaceDto,
|
||||||
AddSubspaceDto,
|
AddSubspaceDto,
|
||||||
CommunitySpaceParam,
|
CommunitySpaceParam,
|
||||||
CreateTagDto,
|
|
||||||
GetSpaceParam,
|
GetSpaceParam,
|
||||||
UpdateSpaceDto,
|
UpdateSpaceDto,
|
||||||
} from '../dtos';
|
} from '../dtos';
|
||||||
@ -29,11 +28,15 @@ import {
|
|||||||
} from '@app/common/constants/orphan-constant';
|
} from '@app/common/constants/orphan-constant';
|
||||||
import { CommandBus } from '@nestjs/cqrs';
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
import { TagService } from './tag';
|
import { TagService } from './tag';
|
||||||
|
import { TagService as NewTagService } from 'src/tags/services/tags.service';
|
||||||
import { SpaceModelService } from 'src/space-model/services';
|
import { SpaceModelService } from 'src/space-model/services';
|
||||||
import { DisableSpaceCommand } from '../commands';
|
import { DisableSpaceCommand } from '../commands';
|
||||||
import { GetSpaceDto } from '../dtos/get.space.dto';
|
import { GetSpaceDto } from '../dtos/get.space.dto';
|
||||||
import { removeCircularReferences } from '@app/common/helper/removeCircularReferences';
|
import { removeCircularReferences } from '@app/common/helper/removeCircularReferences';
|
||||||
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
||||||
|
import { ProcessTagDto } from 'src/tags/dtos';
|
||||||
|
import { SpaceProductAllocationService } from './space-product-allocation.service';
|
||||||
|
import { SubspaceProductAllocationService } from './subspace/subspace-product-allocation.service';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpaceService {
|
export class SpaceService {
|
||||||
constructor(
|
constructor(
|
||||||
@ -44,8 +47,11 @@ export class SpaceService {
|
|||||||
private readonly subSpaceService: SubSpaceService,
|
private readonly subSpaceService: SubSpaceService,
|
||||||
private readonly validationService: ValidationService,
|
private readonly validationService: ValidationService,
|
||||||
private readonly tagService: TagService,
|
private readonly tagService: TagService,
|
||||||
|
private readonly newTagService: NewTagService,
|
||||||
private readonly spaceModelService: SpaceModelService,
|
private readonly spaceModelService: SpaceModelService,
|
||||||
private commandBus: CommandBus,
|
private commandBus: CommandBus,
|
||||||
|
private readonly spaceProductAllocationService: SpaceProductAllocationService,
|
||||||
|
private readonly subspaceProductAllocationService: SubspaceProductAllocationService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createSpace(
|
async createSpace(
|
||||||
@ -93,6 +99,10 @@ export class SpaceService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const newSpace = await queryRunner.manager.save(space);
|
const newSpace = await queryRunner.manager.save(space);
|
||||||
|
const subspaceTags =
|
||||||
|
this.subSpaceService.extractTagsFromSubspace(subspaces);
|
||||||
|
const allTags = [...tags, ...subspaceTags];
|
||||||
|
this.validateUniqueTags(allTags);
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
spaceModelUuid &&
|
spaceModelUuid &&
|
||||||
@ -106,10 +116,17 @@ export class SpaceService {
|
|||||||
)
|
)
|
||||||
: Promise.resolve(),
|
: Promise.resolve(),
|
||||||
subspaces?.length
|
subspaces?.length
|
||||||
? this.createSubspaces(subspaces, newSpace, queryRunner, tags)
|
? this.createSubspaces(
|
||||||
|
subspaces,
|
||||||
|
newSpace,
|
||||||
|
queryRunner,
|
||||||
|
tags,
|
||||||
|
projectUuid,
|
||||||
|
)
|
||||||
: Promise.resolve(),
|
: Promise.resolve(),
|
||||||
|
|
||||||
tags?.length
|
tags?.length
|
||||||
? this.createTags(tags, queryRunner, newSpace)
|
? this.createTags(tags, projectUuid, queryRunner, space)
|
||||||
: Promise.resolve(),
|
: Promise.resolve(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -121,6 +138,8 @@ export class SpaceService {
|
|||||||
message: 'Space created successfully',
|
message: 'Space created successfully',
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log('error', error);
|
||||||
|
|
||||||
await queryRunner.rollbackTransaction();
|
await queryRunner.rollbackTransaction();
|
||||||
|
|
||||||
if (error instanceof HttpException) {
|
if (error instanceof HttpException) {
|
||||||
@ -131,7 +150,31 @@ export class SpaceService {
|
|||||||
await queryRunner.release();
|
await queryRunner.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private validateUniqueTags(allTags: ProcessTagDto[]) {
|
||||||
|
const tagUuidSet = new Set<string>();
|
||||||
|
const tagNameProductSet = new Set<string>();
|
||||||
|
|
||||||
|
for (const tag of allTags) {
|
||||||
|
if (tag.uuid) {
|
||||||
|
if (tagUuidSet.has(tag.uuid)) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Duplicate tag UUID found: ${tag.uuid}`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
tagUuidSet.add(tag.uuid);
|
||||||
|
} else {
|
||||||
|
const tagKey = `${tag.name}-${tag.productUuid}`;
|
||||||
|
if (tagNameProductSet.has(tagKey)) {
|
||||||
|
throw new HttpException(
|
||||||
|
`Duplicate tag found with name "${tag.name}" and product "${tag.productUuid}".`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
tagNameProductSet.add(tagKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
async createFromModel(
|
async createFromModel(
|
||||||
spaceModelUuid: string,
|
spaceModelUuid: string,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
@ -408,6 +451,8 @@ export class SpaceService {
|
|||||||
modifiedSubspaces,
|
modifiedSubspaces,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
space,
|
space,
|
||||||
|
projectUuid,
|
||||||
|
updateSpaceDto.tags,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +468,15 @@ export class SpaceService {
|
|||||||
space,
|
space,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (updateSpaceDto.tags) {
|
||||||
|
await this.spaceProductAllocationService.updateSpaceProductAllocations(
|
||||||
|
updateSpaceDto.tags,
|
||||||
|
projectUuid,
|
||||||
|
space,
|
||||||
|
queryRunner,
|
||||||
|
updateSpaceDto.subspace,
|
||||||
|
);
|
||||||
|
}
|
||||||
await queryRunner.commitTransaction();
|
await queryRunner.commitTransaction();
|
||||||
|
|
||||||
return new SuccessResponseDto({
|
return new SuccessResponseDto({
|
||||||
@ -603,21 +656,33 @@ export class SpaceService {
|
|||||||
subspaces: AddSubspaceDto[],
|
subspaces: AddSubspaceDto[],
|
||||||
space: SpaceEntity,
|
space: SpaceEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
tags: CreateTagDto[],
|
tags: ProcessTagDto[],
|
||||||
|
projectUuid: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
space.subspaces = await this.subSpaceService.createSubspacesFromDto(
|
space.subspaces = await this.subSpaceService.createSubspacesFromDto(
|
||||||
subspaces,
|
subspaces,
|
||||||
space,
|
space,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
tags,
|
tags,
|
||||||
|
projectUuid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createTags(
|
private async createTags(
|
||||||
tags: CreateTagDto[],
|
tags: ProcessTagDto[],
|
||||||
|
projectUuid: string,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
space: SpaceEntity,
|
space: SpaceEntity,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
space.tags = await this.tagService.createTags(tags, queryRunner, space);
|
const processedTags = await this.newTagService.processTags(
|
||||||
|
tags,
|
||||||
|
projectUuid,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
|
await this.spaceProductAllocationService.createSpaceProductAllocations(
|
||||||
|
space,
|
||||||
|
processedTags,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import {
|
|||||||
SpaceLinkRepository,
|
SpaceLinkRepository,
|
||||||
TagRepository,
|
TagRepository,
|
||||||
InviteSpaceRepository,
|
InviteSpaceRepository,
|
||||||
|
SpaceProductAllocationRepository,
|
||||||
} from '@app/common/modules/space/repositories';
|
} from '@app/common/modules/space/repositories';
|
||||||
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
||||||
import {
|
import {
|
||||||
@ -54,7 +55,10 @@ import {
|
|||||||
} from '@app/common/modules/space-model';
|
} from '@app/common/modules/space-model';
|
||||||
import { CommunityModule } from 'src/community/community.module';
|
import { CommunityModule } from 'src/community/community.module';
|
||||||
import { ValidationService } from './services';
|
import { ValidationService } from './services';
|
||||||
import { SubspaceRepository } from '@app/common/modules/space/repositories/subspace.repository';
|
import {
|
||||||
|
SubspaceProductAllocationRepository,
|
||||||
|
SubspaceRepository,
|
||||||
|
} from '@app/common/modules/space/repositories/subspace.repository';
|
||||||
import { TagService } from './services/tag';
|
import { TagService } from './services/tag';
|
||||||
import {
|
import {
|
||||||
SpaceModelService,
|
SpaceModelService,
|
||||||
@ -76,6 +80,8 @@ import { TagService as NewTagService } from 'src/tags/services/tags.service';
|
|||||||
import { NewTagRepository } from '@app/common/modules/tag/repositories/tag-repository';
|
import { NewTagRepository } from '@app/common/modules/tag/repositories/tag-repository';
|
||||||
import { SpaceModelProductAllocationService } from 'src/space-model/services/space-model-product-allocation.service';
|
import { SpaceModelProductAllocationService } from 'src/space-model/services/space-model-product-allocation.service';
|
||||||
import { SubspaceModelProductAllocationService } from 'src/space-model/services/subspace/subspace-model-product-allocation.service';
|
import { SubspaceModelProductAllocationService } from 'src/space-model/services/subspace/subspace-model-product-allocation.service';
|
||||||
|
import { SpaceProductAllocationService } from './services/space-product-allocation.service';
|
||||||
|
import { SubspaceProductAllocationService } from './services/subspace/subspace-product-allocation.service';
|
||||||
|
|
||||||
export const CommandHandlers = [DisableSpaceHandler];
|
export const CommandHandlers = [DisableSpaceHandler];
|
||||||
|
|
||||||
@ -141,6 +147,10 @@ export const CommandHandlers = [DisableSpaceHandler];
|
|||||||
NewTagRepository,
|
NewTagRepository,
|
||||||
SpaceModelProductAllocationService,
|
SpaceModelProductAllocationService,
|
||||||
SubspaceModelProductAllocationService,
|
SubspaceModelProductAllocationService,
|
||||||
|
SpaceProductAllocationService,
|
||||||
|
SubspaceProductAllocationService,
|
||||||
|
SpaceProductAllocationRepository,
|
||||||
|
SubspaceProductAllocationRepository,
|
||||||
],
|
],
|
||||||
exports: [SpaceService],
|
exports: [SpaceService],
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user