mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-26 08:54:54 +00:00
fixed update space model
This commit is contained in:
@ -1,2 +1,3 @@
|
|||||||
export * from './update-subspace.interface';
|
export * from './update-subspace.interface';
|
||||||
export * from './modify-subspace.interface';
|
export * from './modify-subspace.interface';
|
||||||
|
export * from './single-subspace.interface';
|
||||||
|
|||||||
9
src/space-model/interfaces/single-subspace.interface.ts
Normal file
9
src/space-model/interfaces/single-subspace.interface.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { SubspaceModelEntity } from '@app/common/modules/space-model';
|
||||||
|
import { ModifyTagModelDto } from '../dtos';
|
||||||
|
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
||||||
|
|
||||||
|
export interface ISingleSubspaceModel {
|
||||||
|
subspaceModel: SubspaceModelEntity;
|
||||||
|
action: ModifyAction;
|
||||||
|
tags: ModifyTagModelDto[];
|
||||||
|
}
|
||||||
@ -5,10 +5,11 @@ import {
|
|||||||
SpaceModelEntity,
|
SpaceModelEntity,
|
||||||
SpaceModelProductAllocationEntity,
|
SpaceModelProductAllocationEntity,
|
||||||
SpaceModelProductAllocationRepoitory,
|
SpaceModelProductAllocationRepoitory,
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
} from '@app/common/modules/space-model';
|
} from '@app/common/modules/space-model';
|
||||||
import { TagService as NewTagService } from 'src/tags/services';
|
import { TagService as NewTagService } from 'src/tags/services';
|
||||||
import { ProcessTagDto } from 'src/tags/dtos';
|
import { ProcessTagDto } from 'src/tags/dtos';
|
||||||
import { ModifyTagModelDto } from '../dtos';
|
import { ModifySubspaceModelDto, ModifyTagModelDto } from '../dtos';
|
||||||
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
||||||
import { NewTagEntity } from '@app/common/modules/tag';
|
import { NewTagEntity } from '@app/common/modules/tag';
|
||||||
import { ProductEntity } from '@app/common/modules/product/entities';
|
import { ProductEntity } from '@app/common/modules/product/entities';
|
||||||
@ -25,30 +26,83 @@ export class SpaceModelProductAllocationService {
|
|||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
tags: ProcessTagDto[],
|
tags: ProcessTagDto[],
|
||||||
queryRunner?: QueryRunner,
|
queryRunner?: QueryRunner,
|
||||||
|
modifySubspaceModels?: ModifySubspaceModelDto[],
|
||||||
): Promise<SpaceModelProductAllocationEntity[]> {
|
): Promise<SpaceModelProductAllocationEntity[]> {
|
||||||
try {
|
try {
|
||||||
|
if (!tags.length) return [];
|
||||||
|
|
||||||
const processedTags = await this.tagService.processTags(
|
const processedTags = await this.tagService.processTags(
|
||||||
tags,
|
tags,
|
||||||
projectUuid,
|
projectUuid,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
|
|
||||||
const productAllocations: SpaceModelProductAllocationEntity[] = [];
|
const productAllocations: SpaceModelProductAllocationEntity[] = [];
|
||||||
|
const existingAllocations = new Map<
|
||||||
|
string,
|
||||||
|
SpaceModelProductAllocationEntity
|
||||||
|
>();
|
||||||
|
|
||||||
for (const tag of processedTags) {
|
for (const tag of processedTags) {
|
||||||
let allocation = await this.getAllocationByProduct(
|
let isTagNeeded = true;
|
||||||
tag.product,
|
|
||||||
spaceModel,
|
|
||||||
queryRunner,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!allocation) {
|
if (modifySubspaceModels) {
|
||||||
allocation = this.createNewAllocation(spaceModel, tag, queryRunner);
|
const relatedSubspaces = await queryRunner.manager.find(
|
||||||
productAllocations.push(allocation);
|
SubspaceModelProductAllocationEntity,
|
||||||
} else if (
|
{
|
||||||
!allocation.tags.some((existingTag) => existingTag.uuid === tag.uuid)
|
where: {
|
||||||
) {
|
product: tag.product,
|
||||||
allocation.tags.push(tag);
|
subspaceModel: { spaceModel: { uuid: spaceModel.uuid } },
|
||||||
await this.saveAllocation(allocation, queryRunner);
|
tags: { uuid: tag.uuid },
|
||||||
|
},
|
||||||
|
relations: ['subspaceModel', 'tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const subspaceWithTag of relatedSubspaces) {
|
||||||
|
const modifyingSubspace = modifySubspaceModels.find(
|
||||||
|
(subspace) =>
|
||||||
|
subspace.action === ModifyAction.UPDATE &&
|
||||||
|
subspace.uuid === subspaceWithTag.subspaceModel.uuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
modifyingSubspace &&
|
||||||
|
modifyingSubspace.tags &&
|
||||||
|
modifyingSubspace.tags.some(
|
||||||
|
(subspaceTag) =>
|
||||||
|
subspaceTag.action === ModifyAction.DELETE &&
|
||||||
|
subspaceTag.tagUuid === tag.uuid,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
isTagNeeded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTagNeeded) {
|
||||||
|
await this.validateTagWithinSpaceModel(queryRunner, tag, spaceModel);
|
||||||
|
|
||||||
|
let allocation = existingAllocations.get(tag.product.uuid);
|
||||||
|
if (!allocation) {
|
||||||
|
allocation = await this.getAllocationByProduct(
|
||||||
|
tag.product,
|
||||||
|
spaceModel,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
|
if (allocation) {
|
||||||
|
existingAllocations.set(tag.product.uuid, allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allocation) {
|
||||||
|
allocation = this.createNewAllocation(spaceModel, tag, queryRunner);
|
||||||
|
productAllocations.push(allocation);
|
||||||
|
} else if (!allocation.tags.some((t) => t.uuid === tag.uuid)) {
|
||||||
|
allocation.tags.push(tag);
|
||||||
|
await this.saveAllocation(allocation, queryRunner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,10 +121,17 @@ export class SpaceModelProductAllocationService {
|
|||||||
projectUuid: string,
|
projectUuid: string,
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
|
modifySubspaceModels?: ModifySubspaceModelDto[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.processAddActions(dtos, projectUuid, spaceModel, queryRunner),
|
this.processAddActions(
|
||||||
|
dtos,
|
||||||
|
projectUuid,
|
||||||
|
spaceModel,
|
||||||
|
queryRunner,
|
||||||
|
modifySubspaceModels,
|
||||||
|
),
|
||||||
this.processDeleteActions(dtos, queryRunner),
|
this.processDeleteActions(dtos, queryRunner),
|
||||||
]);
|
]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -83,6 +144,7 @@ export class SpaceModelProductAllocationService {
|
|||||||
projectUuid: string,
|
projectUuid: string,
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
|
modifySubspaceModels?: ModifySubspaceModelDto[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const addDtos: ProcessTagDto[] = dtos
|
const addDtos: ProcessTagDto[] = dtos
|
||||||
.filter((dto) => dto.action === ModifyAction.ADD)
|
.filter((dto) => dto.action === ModifyAction.ADD)
|
||||||
@ -98,6 +160,7 @@ export class SpaceModelProductAllocationService {
|
|||||||
spaceModel,
|
spaceModel,
|
||||||
addDtos,
|
addDtos,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
|
modifySubspaceModels,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,40 +235,80 @@ export class SpaceModelProductAllocationService {
|
|||||||
private async processDeleteActions(
|
private async processDeleteActions(
|
||||||
dtos: ModifyTagModelDto[],
|
dtos: ModifyTagModelDto[],
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
): Promise<void> {
|
): Promise<SpaceModelProductAllocationEntity[]> {
|
||||||
const deleteDtos = dtos.filter((dto) => dto.action === ModifyAction.DELETE);
|
try {
|
||||||
|
if (!dtos || dtos.length === 0) {
|
||||||
|
throw new Error('No DTOs provided for deletion.');
|
||||||
|
}
|
||||||
|
|
||||||
await Promise.all(
|
const tagUuidsToDelete = dtos
|
||||||
deleteDtos.map(async (dto) => {
|
.filter((dto) => dto.action === ModifyAction.DELETE && dto.tagUuid)
|
||||||
if (!dto.tagUuid) return;
|
.map((dto) => dto.tagUuid);
|
||||||
|
|
||||||
const allocation = await queryRunner.manager.findOne(
|
if (tagUuidsToDelete.length === 0) return [];
|
||||||
SpaceModelProductAllocationEntity,
|
|
||||||
{
|
const allocationsToUpdate = await queryRunner.manager.find(
|
||||||
where: { tags: { uuid: dto.tagUuid } },
|
SpaceModelProductAllocationEntity,
|
||||||
relations: ['tags'],
|
{
|
||||||
},
|
where: { tags: { uuid: In(tagUuidsToDelete) } },
|
||||||
|
relations: ['tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allocationsToUpdate || allocationsToUpdate.length === 0) return [];
|
||||||
|
|
||||||
|
const deletedAllocations: SpaceModelProductAllocationEntity[] = [];
|
||||||
|
const allocationUpdates: SpaceModelProductAllocationEntity[] = [];
|
||||||
|
|
||||||
|
for (const allocation of allocationsToUpdate) {
|
||||||
|
const updatedTags = allocation.tags.filter(
|
||||||
|
(tag) => !tagUuidsToDelete.includes(tag.uuid),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!allocation) {
|
if (updatedTags.length === allocation.tags.length) {
|
||||||
throw new HttpException(
|
continue;
|
||||||
`Allocation with tag ${dto.tagUuid} not found`,
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingTag = allocation.tags.find(
|
if (updatedTags.length === 0) {
|
||||||
(tag) => tag.uuid === dto.tagUuid,
|
deletedAllocations.push(allocation);
|
||||||
);
|
} else {
|
||||||
if (!existingTag) return;
|
allocation.tags = updatedTags;
|
||||||
|
allocationUpdates.push(allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await queryRunner.manager
|
if (allocationUpdates.length > 0) {
|
||||||
.createQueryBuilder()
|
await queryRunner.manager.save(
|
||||||
.relation(SpaceModelProductAllocationEntity, 'tags')
|
SpaceModelProductAllocationEntity,
|
||||||
.of(allocation)
|
allocationUpdates,
|
||||||
.remove(existingTag);
|
);
|
||||||
}),
|
}
|
||||||
);
|
|
||||||
|
if (deletedAllocations.length > 0) {
|
||||||
|
await queryRunner.manager.remove(
|
||||||
|
SpaceModelProductAllocationEntity,
|
||||||
|
deletedAllocations,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.delete()
|
||||||
|
.from('space_model_product_tags')
|
||||||
|
.where(
|
||||||
|
'space_model_product_allocation_id NOT IN ' +
|
||||||
|
queryRunner.manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.select('uuid')
|
||||||
|
.from(SpaceModelProductAllocationEntity, 'allocation')
|
||||||
|
.getQuery(),
|
||||||
|
)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
return deletedAllocations;
|
||||||
|
} catch (error) {
|
||||||
|
throw this.handleError(error, `Failed to delete tags in space model`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getAllocationByTagUuid(
|
private async getAllocationByTagUuid(
|
||||||
@ -217,4 +320,35 @@ export class SpaceModelProductAllocationService {
|
|||||||
relations: ['tags'],
|
relations: ['tags'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async validateTagWithinSpaceModel(
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
tag: NewTagEntity,
|
||||||
|
spaceModel: SpaceModelEntity,
|
||||||
|
) {
|
||||||
|
const existingAllocationsForProduct = await queryRunner.manager.find(
|
||||||
|
SpaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: { spaceModel, product: tag.product },
|
||||||
|
relations: ['tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
//Flatten all existing tags for this product in the space
|
||||||
|
const existingTagsForProduct = existingAllocationsForProduct.flatMap(
|
||||||
|
(allocation) => allocation.tags,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if the tag is already assigned to the same product in this subspace
|
||||||
|
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 (${spaceModel.uuid}).`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -223,6 +223,7 @@ export class SpaceModelService {
|
|||||||
param.projectUuid,
|
param.projectUuid,
|
||||||
spaceModel,
|
spaceModel,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
|
dto.subspaceModels,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await queryRunner.commitTransaction();
|
await queryRunner.commitTransaction();
|
||||||
@ -255,14 +256,12 @@ export class SpaceModelService {
|
|||||||
const spaceModel = await this.validateSpaceModel(param.spaceModelUuid);
|
const spaceModel = await this.validateSpaceModel(param.spaceModelUuid);
|
||||||
|
|
||||||
if (spaceModel.subspaceModels?.length) {
|
if (spaceModel.subspaceModels?.length) {
|
||||||
const deleteSubspaceDtos = spaceModel.subspaceModels.map(
|
const deleteSubspaceUuids = spaceModel.subspaceModels.map(
|
||||||
(subspace) => ({
|
(subspace) => subspace.uuid,
|
||||||
subspaceUuid: subspace.uuid,
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.subSpaceModelService.deleteSubspaceModels(
|
await this.subSpaceModelService.clearModels(
|
||||||
deleteSubspaceDtos,
|
deleteSubspaceUuids,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,10 +9,8 @@ import {
|
|||||||
} from '@app/common/modules/space-model';
|
} from '@app/common/modules/space-model';
|
||||||
import { NewTagEntity } from '@app/common/modules/tag';
|
import { NewTagEntity } from '@app/common/modules/tag';
|
||||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import {
|
import { ModifyTagModelDto } from 'src/space-model/dtos';
|
||||||
ModifySubspaceModelDto,
|
import { ISingleSubspaceModel } from 'src/space-model/interfaces';
|
||||||
ModifyTagModelDto,
|
|
||||||
} from 'src/space-model/dtos';
|
|
||||||
import { ProcessTagDto } from 'src/tags/dtos';
|
import { ProcessTagDto } from 'src/tags/dtos';
|
||||||
import { TagService as NewTagService } from 'src/tags/services';
|
import { TagService as NewTagService } from 'src/tags/services';
|
||||||
import { In, QueryRunner } from 'typeorm';
|
import { In, QueryRunner } from 'typeorm';
|
||||||
@ -179,225 +177,6 @@ export class SubspaceModelProductAllocationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async processAddActions(
|
|
||||||
dtos: ModifyTagModelDto[],
|
|
||||||
projectUuid: string,
|
|
||||||
subspaceModel: SubspaceModelEntity,
|
|
||||||
otherSubspaceModelUpdateDtos: ModifySubspaceModelDto[],
|
|
||||||
queryRunner: QueryRunner,
|
|
||||||
spaceModel: SpaceModelEntity,
|
|
||||||
spaceTagUpdateDtos?: ModifyTagModelDto[],
|
|
||||||
): Promise<{
|
|
||||||
updatedSubspaceDtos: ModifySubspaceModelDto[];
|
|
||||||
addedAllocations: SubspaceModelProductAllocationEntity[];
|
|
||||||
}> {
|
|
||||||
let addedAllocations: SubspaceModelProductAllocationEntity[] = [];
|
|
||||||
const updatedAllocations: SubspaceModelProductAllocationEntity[] = [];
|
|
||||||
const spaceAllocationToExclude: SpaceModelProductAllocationEntity[] = [];
|
|
||||||
|
|
||||||
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) {
|
|
||||||
let processedTags = await this.tagService.processTags(
|
|
||||||
addDtos,
|
|
||||||
projectUuid,
|
|
||||||
queryRunner,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const subspaceDto of otherSubspaceModelUpdateDtos) {
|
|
||||||
if (subspaceDto.action === ModifyAction.UPDATE && subspaceDto.tags) {
|
|
||||||
// Tag is deleted from one subspace and added in another subspace
|
|
||||||
const deletedTags = subspaceDto.tags.filter(
|
|
||||||
(tagDto) =>
|
|
||||||
tagDto.action === ModifyAction.DELETE &&
|
|
||||||
processedTags.some((tag) => tag.uuid === tagDto.tagUuid),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const deletedTag of deletedTags) {
|
|
||||||
const allocation = await queryRunner.manager.findOne(
|
|
||||||
SubspaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
where: {
|
|
||||||
subspaceModel: { uuid: subspaceDto.uuid },
|
|
||||||
},
|
|
||||||
relations: ['tags', 'product', 'subspace'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const isCommonTag = allocation.tags.some(
|
|
||||||
(tag) => tag.uuid === deletedTag.tagUuid,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (allocation && isCommonTag) {
|
|
||||||
const tagEntity = allocation.tags.find(
|
|
||||||
(tag) => tag.uuid === deletedTag.tagUuid,
|
|
||||||
);
|
|
||||||
|
|
||||||
allocation.tags = allocation.tags.filter(
|
|
||||||
(tag) => tag.uuid !== deletedTag.tagUuid,
|
|
||||||
);
|
|
||||||
|
|
||||||
await queryRunner.manager.save(allocation);
|
|
||||||
|
|
||||||
const productAllocationExistInSubspace =
|
|
||||||
await queryRunner.manager.findOne(
|
|
||||||
SubspaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
where: {
|
|
||||||
subspaceModel: { uuid: subspaceDto.uuid },
|
|
||||||
product: { uuid: allocation.product.uuid },
|
|
||||||
},
|
|
||||||
relations: ['tags'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (productAllocationExistInSubspace) {
|
|
||||||
productAllocationExistInSubspace.tags.push(tagEntity);
|
|
||||||
await queryRunner.manager.save(
|
|
||||||
productAllocationExistInSubspace,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const newProductAllocation = queryRunner.manager.create(
|
|
||||||
SubspaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
subspaceModel: subspaceModel,
|
|
||||||
product: allocation.product,
|
|
||||||
tags: [deletedTag],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
await queryRunner.manager.save(newProductAllocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
updatedAllocations.push(allocation);
|
|
||||||
|
|
||||||
// Remove the tag from processedTags to prevent duplication
|
|
||||||
processedTags = processedTags.filter(
|
|
||||||
(tag) => tag.uuid !== deletedTag.tagUuid,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove the tag from subspaceDto.tags to ensure it's not processed again while processing other dtos.
|
|
||||||
subspaceDto.tags = subspaceDto.tags.filter(
|
|
||||||
(tagDto) => tagDto.tagUuid !== deletedTag.tagUuid,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (subspaceDto.action === ModifyAction.DELETE) {
|
|
||||||
const allocation = await queryRunner.manager.findOne(
|
|
||||||
SubspaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
where: { subspaceModel: { uuid: subspaceDto.uuid } },
|
|
||||||
relations: ['tags'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const repeatedTags = allocation?.tags.filter((tag) =>
|
|
||||||
processedTags.some(
|
|
||||||
(processedTag) => processedTag.uuid === tag.uuid,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (repeatedTags.length > 0) {
|
|
||||||
allocation.tags = allocation.tags.filter(
|
|
||||||
(tag) =>
|
|
||||||
!repeatedTags.some(
|
|
||||||
(repeatedTag) => repeatedTag.uuid === tag.uuid,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await queryRunner.manager.save(allocation);
|
|
||||||
|
|
||||||
const productAllocationExistInSubspace =
|
|
||||||
await queryRunner.manager.findOne(
|
|
||||||
SubspaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
where: {
|
|
||||||
subspaceModel: { uuid: subspaceDto.uuid },
|
|
||||||
product: { uuid: allocation.product.uuid },
|
|
||||||
},
|
|
||||||
relations: ['tags'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (productAllocationExistInSubspace) {
|
|
||||||
productAllocationExistInSubspace.tags.push(...repeatedTags);
|
|
||||||
await queryRunner.manager.save(productAllocationExistInSubspace);
|
|
||||||
} else {
|
|
||||||
const newProductAllocation = queryRunner.manager.create(
|
|
||||||
SubspaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
subspaceModel: subspaceModel,
|
|
||||||
product: allocation.product,
|
|
||||||
tags: repeatedTags,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
await queryRunner.manager.save(newProductAllocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
const newAllocation = queryRunner.manager.create(
|
|
||||||
SubspaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
subspaceModel: subspaceModel,
|
|
||||||
product: allocation.product,
|
|
||||||
tags: repeatedTags,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
await queryRunner.manager.save(newAllocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spaceTagUpdateDtos) {
|
|
||||||
const deletedSpaceTags = spaceTagUpdateDtos.filter(
|
|
||||||
(tagDto) =>
|
|
||||||
tagDto.action === ModifyAction.DELETE &&
|
|
||||||
processedTags.some((tag) => tag.uuid === tagDto.tagUuid),
|
|
||||||
);
|
|
||||||
for (const deletedTag of deletedSpaceTags) {
|
|
||||||
const allocation = await queryRunner.manager.findOne(
|
|
||||||
SpaceModelProductAllocationEntity,
|
|
||||||
{
|
|
||||||
where: {
|
|
||||||
spaceModel: { uuid: spaceModel.uuid },
|
|
||||||
tags: { uuid: deletedTag.tagUuid },
|
|
||||||
},
|
|
||||||
relations: ['tags', 'subspace'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
|
||||||
allocation &&
|
|
||||||
allocation.tags.some((tag) => tag.uuid === deletedTag.tagUuid)
|
|
||||||
) {
|
|
||||||
spaceAllocationToExclude.push(allocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new product allocations
|
|
||||||
const newAllocations = await this.createProductAllocations(
|
|
||||||
subspaceModel,
|
|
||||||
processedTags,
|
|
||||||
queryRunner,
|
|
||||||
spaceAllocationToExclude,
|
|
||||||
);
|
|
||||||
addedAllocations = [...newAllocations, ...updatedAllocations]; // Combine newly created and updated allocations
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
updatedSubspaceDtos: otherSubspaceModelUpdateDtos, // Updated subspace DTOs
|
|
||||||
addedAllocations, // Newly created allocations
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async processDeleteActions(
|
async processDeleteActions(
|
||||||
dtos: ModifyTagModelDto[],
|
dtos: ModifyTagModelDto[],
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
@ -477,42 +256,253 @@ export class SubspaceModelProductAllocationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateProductAllocations(
|
async updateAllocations(
|
||||||
dtos: ModifyTagModelDto[],
|
subspaceModels: ISingleSubspaceModel[],
|
||||||
projectUuid: string,
|
projectUuid: string,
|
||||||
subspaceModel: SubspaceModelEntity,
|
|
||||||
otherSubspaceModelUpdateDtos: ModifySubspaceModelDto[],
|
|
||||||
spaceModel: SpaceModelEntity,
|
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
|
spaceModel: SpaceModelEntity,
|
||||||
spaceTagUpdateDtos?: ModifyTagModelDto[],
|
spaceTagUpdateDtos?: ModifyTagModelDto[],
|
||||||
): Promise<{
|
) {
|
||||||
addedAllocations: SubspaceModelProductAllocationEntity[];
|
const spaceAllocationToExclude: SpaceModelProductAllocationEntity[] = [];
|
||||||
deletedAllocations: SubspaceModelProductAllocationEntity[];
|
|
||||||
updatedSubspaceDtos: ModifySubspaceModelDto[];
|
for (const subspaceModel of subspaceModels) {
|
||||||
}> {
|
const tagDtos = subspaceModel.tags;
|
||||||
|
if (tagDtos.length > 0) {
|
||||||
|
const tagsToAddDto: ProcessTagDto[] = tagDtos
|
||||||
|
.filter((dto) => dto.action === ModifyAction.ADD)
|
||||||
|
.map((dto) => ({
|
||||||
|
name: dto.name,
|
||||||
|
productUuid: dto.productUuid,
|
||||||
|
uuid: dto.newTagUuid,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const tagsToDeleteDto = tagDtos.filter(
|
||||||
|
(dto) => dto.action === ModifyAction.DELETE,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (tagsToAddDto.length > 0) {
|
||||||
|
let processedTags = await this.tagService.processTags(
|
||||||
|
tagsToAddDto,
|
||||||
|
projectUuid,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const subspaceDto of subspaceModels) {
|
||||||
|
if (
|
||||||
|
subspaceDto !== subspaceModel &&
|
||||||
|
subspaceDto.action === ModifyAction.UPDATE &&
|
||||||
|
subspaceDto.tags
|
||||||
|
) {
|
||||||
|
// Tag is deleted from one subspace and added in another subspace
|
||||||
|
const deletedTags = subspaceDto.tags.filter(
|
||||||
|
(tagDto) =>
|
||||||
|
tagDto.action === ModifyAction.DELETE &&
|
||||||
|
processedTags.some((tag) => tag.uuid === tagDto.tagUuid),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const deletedTag of deletedTags) {
|
||||||
|
const allocation = await queryRunner.manager.findOne(
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
subspaceModel: { uuid: subspaceDto.subspaceModel.uuid },
|
||||||
|
},
|
||||||
|
relations: ['tags', 'product', 'subspace'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const isCommonTag = allocation.tags.some(
|
||||||
|
(tag) => tag.uuid === deletedTag.tagUuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (allocation && isCommonTag) {
|
||||||
|
const tagEntity = allocation.tags.find(
|
||||||
|
(tag) => tag.uuid === deletedTag.tagUuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
allocation.tags = allocation.tags.filter(
|
||||||
|
(tag) => tag.uuid !== deletedTag.tagUuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.manager.save(allocation);
|
||||||
|
|
||||||
|
const productAllocationExistInSubspace =
|
||||||
|
await queryRunner.manager.findOne(
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
subspaceModel: {
|
||||||
|
uuid: subspaceDto.subspaceModel.uuid,
|
||||||
|
},
|
||||||
|
product: { uuid: allocation.product.uuid },
|
||||||
|
},
|
||||||
|
relations: ['tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (productAllocationExistInSubspace) {
|
||||||
|
productAllocationExistInSubspace.tags.push(tagEntity);
|
||||||
|
await queryRunner.manager.save(
|
||||||
|
productAllocationExistInSubspace,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const newProductAllocation = queryRunner.manager.create(
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
subspaceModel: subspaceModel.subspaceModel,
|
||||||
|
product: allocation.product,
|
||||||
|
tags: [tagEntity],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.manager.save(newProductAllocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the tag from processedTags to prevent duplication
|
||||||
|
processedTags = processedTags.filter(
|
||||||
|
(tag) => tag.uuid !== deletedTag.tagUuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove the tag from subspaceDto.tags to ensure it's not processed again while processing other dtos.
|
||||||
|
subspaceDto.tags = subspaceDto.tags.filter(
|
||||||
|
(tagDto) => tagDto.tagUuid !== deletedTag.tagUuid,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
subspaceDto !== subspaceModel &&
|
||||||
|
subspaceDto.action === ModifyAction.DELETE
|
||||||
|
) {
|
||||||
|
const allocation = await queryRunner.manager.findOne(
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
subspaceModel: { uuid: subspaceDto.subspaceModel.uuid },
|
||||||
|
},
|
||||||
|
relations: ['tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const repeatedTags = allocation?.tags.filter((tag) =>
|
||||||
|
processedTags.some(
|
||||||
|
(processedTag) => processedTag.uuid === tag.uuid,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (repeatedTags.length > 0) {
|
||||||
|
allocation.tags = allocation.tags.filter(
|
||||||
|
(tag) =>
|
||||||
|
!repeatedTags.some(
|
||||||
|
(repeatedTag) => repeatedTag.uuid === tag.uuid,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.manager.save(allocation);
|
||||||
|
|
||||||
|
const productAllocationExistInSubspace =
|
||||||
|
await queryRunner.manager.findOne(
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
subspaceModel: { uuid: subspaceDto.subspaceModel.uuid },
|
||||||
|
product: { uuid: allocation.product.uuid },
|
||||||
|
},
|
||||||
|
relations: ['tags'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (productAllocationExistInSubspace) {
|
||||||
|
productAllocationExistInSubspace.tags.push(...repeatedTags);
|
||||||
|
await queryRunner.manager.save(
|
||||||
|
productAllocationExistInSubspace,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const newProductAllocation = queryRunner.manager.create(
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
subspaceModel: subspaceModel.subspaceModel,
|
||||||
|
product: allocation.product,
|
||||||
|
tags: repeatedTags,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.manager.save(newProductAllocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newAllocation = queryRunner.manager.create(
|
||||||
|
SubspaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
subspaceModel: subspaceModel.subspaceModel,
|
||||||
|
product: allocation.product,
|
||||||
|
tags: repeatedTags,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.manager.save(newAllocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spaceTagUpdateDtos) {
|
||||||
|
const deletedSpaceTags = spaceTagUpdateDtos.filter(
|
||||||
|
(tagDto) =>
|
||||||
|
tagDto.action === ModifyAction.DELETE &&
|
||||||
|
processedTags.some((tag) => tag.uuid === tagDto.tagUuid),
|
||||||
|
);
|
||||||
|
for (const deletedTag of deletedSpaceTags) {
|
||||||
|
const allocation = await queryRunner.manager.findOne(
|
||||||
|
SpaceModelProductAllocationEntity,
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
spaceModel: { uuid: spaceModel.uuid },
|
||||||
|
tags: { uuid: deletedTag.tagUuid },
|
||||||
|
},
|
||||||
|
relations: ['tags', 'subspace'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
allocation &&
|
||||||
|
allocation.tags.some((tag) => tag.uuid === deletedTag.tagUuid)
|
||||||
|
) {
|
||||||
|
spaceAllocationToExclude.push(allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new product allocations
|
||||||
|
await this.createProductAllocations(
|
||||||
|
subspaceModel.subspaceModel,
|
||||||
|
processedTags,
|
||||||
|
queryRunner,
|
||||||
|
spaceAllocationToExclude,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (tagsToDeleteDto.length > 0) {
|
||||||
|
await this.processDeleteActions(tagsToDeleteDto, queryRunner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearAllAllocations(subspaceIds: string[], queryRunner: QueryRunner) {
|
||||||
try {
|
try {
|
||||||
const addedSubspaceTags = await this.processAddActions(
|
await queryRunner.manager.delete(SubspaceModelProductAllocationEntity, {
|
||||||
dtos,
|
subspaceModel: In(subspaceIds),
|
||||||
projectUuid,
|
});
|
||||||
subspaceModel,
|
|
||||||
otherSubspaceModelUpdateDtos,
|
|
||||||
queryRunner,
|
|
||||||
spaceModel,
|
|
||||||
spaceTagUpdateDtos,
|
|
||||||
);
|
|
||||||
|
|
||||||
const deletedTagAllocations = await this.processDeleteActions(
|
await queryRunner.manager
|
||||||
dtos,
|
.createQueryBuilder()
|
||||||
queryRunner,
|
.delete()
|
||||||
);
|
.from('subspace_model_product_tags') // Replace with entity name if you have one
|
||||||
|
.where(
|
||||||
return {
|
'"subspace_model_product_allocation_uuid" IN (:...subspaceIds)',
|
||||||
addedAllocations: addedSubspaceTags.addedAllocations,
|
{
|
||||||
deletedAllocations: deletedTagAllocations,
|
subspaceIds,
|
||||||
updatedSubspaceDtos: addedSubspaceTags.updatedSubspaceDtos,
|
},
|
||||||
};
|
)
|
||||||
|
.execute();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw this.handleError(error, 'Error while updating product allocations');
|
throw this.handleError(error, `Failed to clear all allocations`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,17 +9,17 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
|||||||
import { CreateSubspaceModelDto, ModifyTagModelDto } from '../../dtos';
|
import { CreateSubspaceModelDto, ModifyTagModelDto } from '../../dtos';
|
||||||
import { In, Not, QueryFailedError, QueryRunner } from 'typeorm';
|
import { In, Not, QueryFailedError, QueryRunner } from 'typeorm';
|
||||||
import { ModifySubspaceModelDto } from 'src/space-model/dtos/subspaces-model-dtos';
|
import { ModifySubspaceModelDto } from 'src/space-model/dtos/subspaces-model-dtos';
|
||||||
import { TagModelService } from '../tag-model.service';
|
|
||||||
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
||||||
import { ProcessTagDto } from 'src/tags/dtos';
|
import { ProcessTagDto } from 'src/tags/dtos';
|
||||||
import { TagService } from 'src/tags/services';
|
import { TagService } from 'src/tags/services';
|
||||||
import { SubspaceModelProductAllocationService } from './subspace-model-product-allocation.service';
|
import { SubspaceModelProductAllocationService } from './subspace-model-product-allocation.service';
|
||||||
|
import { ISingleSubspaceModel } from 'src/space-model/interfaces';
|
||||||
|
import { SubspaceEntity } from '@app/common/modules/space/entities/subspace/subspace.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SubSpaceModelService {
|
export class SubSpaceModelService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly subspaceModelRepository: SubspaceModelRepository,
|
private readonly subspaceModelRepository: SubspaceModelRepository,
|
||||||
private readonly tagModelService: TagModelService,
|
|
||||||
private readonly tagService: TagService,
|
private readonly tagService: TagService,
|
||||||
private readonly productAllocationService: SubspaceModelProductAllocationService,
|
private readonly productAllocationService: SubspaceModelProductAllocationService,
|
||||||
) {}
|
) {}
|
||||||
@ -74,36 +74,26 @@ export class SubSpaceModelService {
|
|||||||
dtos: ModifySubspaceModelDto[],
|
dtos: ModifySubspaceModelDto[],
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
projectUuid: string,
|
): Promise<ISingleSubspaceModel[]> {
|
||||||
otherSubspaceModelUpdateDtos?: ModifySubspaceModelDto[],
|
if (!dtos.length) return [];
|
||||||
spaceTagUpdateDtos?: ModifyTagModelDto[],
|
|
||||||
) {
|
|
||||||
for (const dto of dtos) {
|
|
||||||
if (dto.subspaceName) {
|
|
||||||
await this.checkDuplicateNames(dto.subspaceName, spaceModel.uuid);
|
|
||||||
const subspaceModel = queryRunner.manager.create(
|
|
||||||
this.subspaceModelRepository.target,
|
|
||||||
{
|
|
||||||
subspaceName: dto.subspaceName,
|
|
||||||
spaceModel,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const savedSubspace = await queryRunner.manager.save(subspaceModel);
|
|
||||||
|
|
||||||
|
const subspaceNames = dtos.map((dto) => dto.subspaceName);
|
||||||
|
await this.checkDuplicateNamesBatch(subspaceNames, spaceModel.uuid);
|
||||||
|
|
||||||
if (dto.tags) {
|
const subspaceEntities = dtos.map((dto) =>
|
||||||
await this.productAllocationService.updateProductAllocations(
|
queryRunner.manager.create(SubspaceModelEntity, {
|
||||||
dto.tags,
|
subspaceName: dto.subspaceName,
|
||||||
projectUuid,
|
spaceModel,
|
||||||
subspaceModel,
|
}),
|
||||||
otherSubspaceModelUpdateDtos ? otherSubspaceModelUpdateDtos : [],
|
);
|
||||||
spaceModel,
|
|
||||||
queryRunner,
|
const savedSubspaces = await queryRunner.manager.save(subspaceEntities);
|
||||||
spaceTagUpdateDtos,
|
|
||||||
);
|
return savedSubspaces.map((subspace, index) => ({
|
||||||
}
|
subspaceModel: subspace,
|
||||||
}
|
action: ModifyAction.ADD,
|
||||||
}
|
tags: dtos[index].tags ? dtos[index].tags : [],
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async modifySubspaceModels(
|
async modifySubspaceModels(
|
||||||
@ -121,19 +111,22 @@ export class SubSpaceModelService {
|
|||||||
const combinedDtos = dtos.filter((dto) => dto.action !== ModifyAction.ADD);
|
const combinedDtos = dtos.filter((dto) => dto.action !== ModifyAction.ADD);
|
||||||
const deleteDtos = dtos.filter((dto) => dto.action !== ModifyAction.DELETE);
|
const deleteDtos = dtos.filter((dto) => dto.action !== ModifyAction.DELETE);
|
||||||
|
|
||||||
await this.updateSubspaceModel(
|
const updatedModels = await this.updateSubspaceModel(
|
||||||
combinedDtos,
|
combinedDtos,
|
||||||
spaceModel,
|
spaceModel,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
projectUuid,
|
|
||||||
spaceTagUpdateDtos,
|
|
||||||
);
|
);
|
||||||
await this.handleAddAction(
|
const addedModels = await this.handleAddAction(
|
||||||
addDtos,
|
addDtos,
|
||||||
spaceModel,
|
spaceModel,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
|
);
|
||||||
|
const combineModels = [...addedModels, ...updatedModels];
|
||||||
|
await this.productAllocationService.updateAllocations(
|
||||||
|
combineModels,
|
||||||
projectUuid,
|
projectUuid,
|
||||||
combinedDtos,
|
queryRunner,
|
||||||
|
spaceModel,
|
||||||
spaceTagUpdateDtos,
|
spaceTagUpdateDtos,
|
||||||
);
|
);
|
||||||
await this.deleteSubspaceModels(deleteDtos, queryRunner);
|
await this.deleteSubspaceModels(deleteDtos, queryRunner);
|
||||||
@ -155,14 +148,10 @@ export class SubSpaceModelService {
|
|||||||
throw new Error('Invalid subspace UUIDs provided.');
|
throw new Error('Invalid subspace UUIDs provided.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const subspaces = await queryRunner.manager.find(SubspaceModelEntity, {
|
const subspaces = await this.getSubspacesByUuids(
|
||||||
where: { uuid: In(subspaceUuids) },
|
queryRunner,
|
||||||
relations: [
|
subspaceUuids,
|
||||||
'productAllocations',
|
);
|
||||||
'productAllocations.tags',
|
|
||||||
'spaceModel',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!subspaces.length) return deleteResults;
|
if (!subspaces.length) return deleteResults;
|
||||||
|
|
||||||
@ -273,57 +262,73 @@ export class SubSpaceModelService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async clearModels(subspaceUuids: string[], queryRunner: QueryRunner) {
|
||||||
|
try {
|
||||||
|
const subspaces = await this.getSubspacesByUuids(
|
||||||
|
queryRunner,
|
||||||
|
subspaceUuids,
|
||||||
|
);
|
||||||
|
if (!subspaces.length) return;
|
||||||
|
await queryRunner.manager.update(
|
||||||
|
SubspaceModelEntity,
|
||||||
|
{ uuid: In(subspaceUuids) },
|
||||||
|
{ disabled: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.productAllocationService.clearAllAllocations(
|
||||||
|
subspaceUuids,
|
||||||
|
queryRunner,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error instanceof HttpException
|
||||||
|
? error.message
|
||||||
|
: 'An unexpected error occurred while clearing subspace models',
|
||||||
|
error instanceof HttpException
|
||||||
|
? error.getStatus()
|
||||||
|
: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async updateSubspaceModel(
|
async updateSubspaceModel(
|
||||||
dtos: ModifySubspaceModelDto[],
|
dtos: ModifySubspaceModelDto[],
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
projectUuid: string,
|
): Promise<ISingleSubspaceModel[]> {
|
||||||
spaceTagUpdateDtos?: ModifyTagModelDto[],
|
if (!dtos.length) return [];
|
||||||
) {
|
|
||||||
for (const dto of dtos) {
|
|
||||||
const otherDtos = dtos.filter((d) => d !== dto);
|
|
||||||
|
|
||||||
if (dto.subspaceName) {
|
const updatedSubspaces: {
|
||||||
await this.checkDuplicateNames(dto.subspaceName, spaceModel.uuid);
|
subspaceModel: SubspaceModelEntity;
|
||||||
const subspace = queryRunner.manager.create(
|
tags: ModifyTagModelDto[];
|
||||||
this.subspaceModelRepository.target,
|
action: ModifyAction.UPDATE;
|
||||||
{
|
}[] = [];
|
||||||
subspaceName: dto.subspaceName,
|
|
||||||
spaceModel,
|
for (const dto of dtos) {
|
||||||
},
|
if (!dto.subspaceName) continue;
|
||||||
);
|
|
||||||
const savedSubspace = await queryRunner.manager.save(subspace);
|
await this.checkDuplicateNames(dto.subspaceName, spaceModel.uuid);
|
||||||
if (dto.tags) {
|
|
||||||
await this.productAllocationService.updateProductAllocations(
|
const existingSubspace = await queryRunner.manager.findOne(
|
||||||
dto.tags,
|
this.subspaceModelRepository.target,
|
||||||
projectUuid,
|
{ where: { uuid: dto.uuid } },
|
||||||
savedSubspace,
|
);
|
||||||
otherDtos,
|
|
||||||
spaceModel,
|
if (
|
||||||
queryRunner,
|
existingSubspace &&
|
||||||
spaceTagUpdateDtos,
|
existingSubspace.subspaceName !== dto.subspaceName
|
||||||
);
|
) {
|
||||||
}
|
existingSubspace.subspaceName = dto.subspaceName;
|
||||||
|
await queryRunner.manager.save(existingSubspace);
|
||||||
|
updatedSubspaces.push({
|
||||||
|
subspaceModel: existingSubspace,
|
||||||
|
tags: dto.tags ?? [],
|
||||||
|
action: ModifyAction.UPDATE,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private async findOne(subspaceUuid: string): Promise<SubspaceModelEntity> {
|
return updatedSubspaces;
|
||||||
const subspace = await this.subspaceModelRepository.findOne({
|
|
||||||
where: { uuid: subspaceUuid, disabled: false },
|
|
||||||
relations: [
|
|
||||||
'productAllocations',
|
|
||||||
'spaceModel',
|
|
||||||
'productAllocations.tags',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
if (!subspace) {
|
|
||||||
throw new HttpException(
|
|
||||||
`SubspaceModel with UUID ${subspaceUuid} not found.`,
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return subspace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async checkDuplicateNames(
|
private async checkDuplicateNames(
|
||||||
@ -350,6 +355,32 @@ export class SubSpaceModelService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async checkDuplicateNamesBatch(
|
||||||
|
subspaceNames: string[],
|
||||||
|
spaceModelUuid: string,
|
||||||
|
): Promise<void> {
|
||||||
|
if (!subspaceNames.length) return;
|
||||||
|
|
||||||
|
const existingSubspaces = await this.subspaceModelRepository.find({
|
||||||
|
where: {
|
||||||
|
subspaceName: In(subspaceNames),
|
||||||
|
spaceModel: { uuid: spaceModelUuid },
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
select: ['subspaceName'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingSubspaces.length > 0) {
|
||||||
|
const duplicateNames = existingSubspaces.map(
|
||||||
|
(subspace) => subspace.subspaceName,
|
||||||
|
);
|
||||||
|
throw new HttpException(
|
||||||
|
`Duplicate subspace names found: ${duplicateNames.join(', ')}`,
|
||||||
|
HttpStatus.CONFLICT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async validateNamesInDTO(names: string[]) {
|
private async validateNamesInDTO(names: string[]) {
|
||||||
const seenNames = new Set<string>();
|
const seenNames = new Set<string>();
|
||||||
const duplicateNames = new Set<string>();
|
const duplicateNames = new Set<string>();
|
||||||
@ -379,4 +410,18 @@ export class SubSpaceModelService {
|
|||||||
): ModifyTagModelDto[] {
|
): ModifyTagModelDto[] {
|
||||||
return subspaceModels.flatMap((subspace) => subspace.tags || []);
|
return subspaceModels.flatMap((subspace) => subspace.tags || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getSubspacesByUuids(
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
subspaceUuids: string[],
|
||||||
|
): Promise<SubspaceModelEntity[]> {
|
||||||
|
return await queryRunner.manager.find(SubspaceModelEntity, {
|
||||||
|
where: { uuid: In(subspaceUuids) },
|
||||||
|
relations: [
|
||||||
|
'productAllocations',
|
||||||
|
'productAllocations.tags',
|
||||||
|
'spaceModel',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user