updated delete action

This commit is contained in:
hannathkadher
2025-02-24 20:04:36 +04:00
parent 4391339e5e
commit acc8f3ef4d
2 changed files with 158 additions and 56 deletions

View File

@ -401,7 +401,7 @@ export class SubspaceModelProductAllocationService {
async processDeleteActions( async processDeleteActions(
dtos: ModifyTagModelDto[], dtos: ModifyTagModelDto[],
queryRunner: QueryRunner, queryRunner: QueryRunner,
): Promise<void> { ): Promise<SubspaceModelProductAllocationEntity[]> {
try { try {
if (!dtos || dtos.length === 0) { if (!dtos || dtos.length === 0) {
throw new Error('No DTOs provided for deletion.'); throw new Error('No DTOs provided for deletion.');
@ -411,7 +411,7 @@ export class SubspaceModelProductAllocationService {
.filter((dto) => dto.action === ModifyAction.DELETE && dto.tagUuid) .filter((dto) => dto.action === ModifyAction.DELETE && dto.tagUuid)
.map((dto) => dto.tagUuid); .map((dto) => dto.tagUuid);
if (tagUuidsToDelete.length === 0) return; if (tagUuidsToDelete.length === 0) return [];
const allocationsToUpdate = await queryRunner.manager.find( const allocationsToUpdate = await queryRunner.manager.find(
SubspaceModelProductAllocationEntity, SubspaceModelProductAllocationEntity,
@ -421,9 +421,11 @@ export class SubspaceModelProductAllocationService {
}, },
); );
if (!allocationsToUpdate || allocationsToUpdate.length === 0) return; if (!allocationsToUpdate || allocationsToUpdate.length === 0) return [];
const deletedAllocations: SubspaceModelProductAllocationEntity[] = [];
const allocationUpdates: SubspaceModelProductAllocationEntity[] = []; const allocationUpdates: SubspaceModelProductAllocationEntity[] = [];
for (const allocation of allocationsToUpdate) { for (const allocation of allocationsToUpdate) {
const updatedTags = allocation.tags.filter( const updatedTags = allocation.tags.filter(
(tag) => !tagUuidsToDelete.includes(tag.uuid), (tag) => !tagUuidsToDelete.includes(tag.uuid),
@ -433,8 +435,12 @@ export class SubspaceModelProductAllocationService {
continue; continue;
} }
allocation.tags = updatedTags; if (updatedTags.length === 0) {
allocationUpdates.push(allocation); deletedAllocations.push(allocation);
} else {
allocation.tags = updatedTags;
allocationUpdates.push(allocation);
}
} }
if (allocationUpdates.length > 0) { if (allocationUpdates.length > 0) {
@ -444,6 +450,13 @@ export class SubspaceModelProductAllocationService {
); );
} }
if (deletedAllocations.length > 0) {
await queryRunner.manager.remove(
SubspaceModelProductAllocationEntity,
deletedAllocations,
);
}
await queryRunner.manager await queryRunner.manager
.createQueryBuilder() .createQueryBuilder()
.delete() .delete()
@ -457,6 +470,8 @@ export class SubspaceModelProductAllocationService {
.getQuery(), .getQuery(),
) )
.execute(); .execute();
return deletedAllocations;
} catch (error) { } catch (error) {
throw this.handleError(error, `Failed to delete tags in subspace model`); throw this.handleError(error, `Failed to delete tags in subspace model`);
} }
@ -470,20 +485,32 @@ export class SubspaceModelProductAllocationService {
spaceModel: SpaceModelEntity, spaceModel: SpaceModelEntity,
queryRunner: QueryRunner, queryRunner: QueryRunner,
spaceTagUpdateDtos?: ModifyTagModelDto[], spaceTagUpdateDtos?: ModifyTagModelDto[],
): Promise<void> { ): Promise<{
addedAllocations: SubspaceModelProductAllocationEntity[];
deletedAllocations: SubspaceModelProductAllocationEntity[];
updatedSubspaceDtos: ModifySubspaceModelDto[];
}> {
try { try {
await Promise.all([ const addedSubspaceTags = await this.processAddActions(
this.processAddActions( dtos,
dtos, projectUuid,
projectUuid, subspaceModel,
subspaceModel, otherSubspaceModelUpdateDtos,
otherSubspaceModelUpdateDtos, queryRunner,
queryRunner, spaceModel,
spaceModel, spaceTagUpdateDtos,
spaceTagUpdateDtos, );
),
this.processDeleteActions(dtos, queryRunner), const deletedTagAllocations = await this.processDeleteActions(
]); dtos,
queryRunner,
);
return {
addedAllocations: addedSubspaceTags.addedAllocations,
deletedAllocations: deletedTagAllocations,
updatedSubspaceDtos: addedSubspaceTags.updatedSubspaceDtos,
};
} catch (error) { } catch (error) {
throw this.handleError(error, 'Error while updating product allocations'); throw this.handleError(error, 'Error while updating product allocations');
} }

View File

@ -2,12 +2,12 @@ import {
SpaceModelEntity, SpaceModelEntity,
SpaceModelProductAllocationEntity, SpaceModelProductAllocationEntity,
SubspaceModelEntity, SubspaceModelEntity,
SubspaceModelProductAllocationEntity,
SubspaceModelRepository, SubspaceModelRepository,
} from '@app/common/modules/space-model'; } from '@app/common/modules/space-model';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateSubspaceModelDto, ModifyTagModelDto } from '../../dtos'; import { CreateSubspaceModelDto, ModifyTagModelDto } from '../../dtos';
import { Not, QueryRunner } from 'typeorm'; import { In, Not, QueryFailedError, QueryRunner } from 'typeorm';
import { IDeletedSubsaceModelInterface } from 'src/space-model/interfaces';
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 { TagModelService } from '../tag-model.service';
import { ModifyAction } from '@app/common/constants/modify-action.enum'; import { ModifyAction } from '@app/common/constants/modify-action.enum';
@ -89,6 +89,8 @@ export class SubSpaceModelService {
}, },
); );
const savedSubspace = await queryRunner.manager.save(subspaceModel); const savedSubspace = await queryRunner.manager.save(subspaceModel);
if (dto.tags) { if (dto.tags) {
await this.productAllocationService.updateProductAllocations( await this.productAllocationService.updateProductAllocations(
dto.tags, dto.tags,
@ -111,61 +113,98 @@ export class SubSpaceModelService {
projectUuid: string, projectUuid: string,
spaceTagUpdateDtos?: ModifyTagModelDto[], spaceTagUpdateDtos?: ModifyTagModelDto[],
) { ) {
if (!dtos || dtos.length === 0) {
return;
}
const addDtos = dtos.filter((dto) => dto.action === ModifyAction.ADD); const addDtos = dtos.filter((dto) => dto.action === ModifyAction.ADD);
const otherDtos = 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(
combinedDtos,
spaceModel,
queryRunner,
projectUuid,
spaceTagUpdateDtos,
);
await this.handleAddAction( await this.handleAddAction(
addDtos, addDtos,
spaceModel, spaceModel,
queryRunner, queryRunner,
projectUuid, projectUuid,
otherDtos, combinedDtos,
spaceTagUpdateDtos, spaceTagUpdateDtos,
); );
await this.updateSubspaceModel(
otherDtos,
spaceModel,
queryRunner,
projectUuid,
spaceTagUpdateDtos,
);
await this.deleteSubspaceModels(deleteDtos, queryRunner); await this.deleteSubspaceModels(deleteDtos, queryRunner);
} }
async deleteSubspaceModels( async deleteSubspaceModels(
deleteDtos: ModifySubspaceModelDto[], deleteDtos: ModifySubspaceModelDto[],
queryRunner: QueryRunner, queryRunner: QueryRunner,
): Promise<IDeletedSubsaceModelInterface[]> { ) {
const deleteResults = []; try {
if (!deleteDtos || deleteDtos.length === 0) {
throw new Error('No subspaces provided for deletion.');
}
for (const dto of deleteDtos) { const deleteResults = [];
const subspaceModel = await this.findOne(dto.uuid); const subspaceUuids = deleteDtos.map((dto) => dto.uuid).filter(Boolean);
if (subspaceUuids.length === 0) {
throw new Error('Invalid subspace UUIDs provided.');
}
const subspaces = await queryRunner.manager.find(SubspaceModelEntity, {
where: { uuid: In(subspaceUuids) },
relations: [
'productAllocations',
'productAllocations.tags',
'spaceModel',
],
});
if (!subspaces.length) return deleteResults;
await queryRunner.manager.update( await queryRunner.manager.update(
this.subspaceModelRepository.target, SubspaceModelEntity,
{ uuid: dto.uuid }, { uuid: In(subspaceUuids) },
{ disabled: true }, { disabled: true },
); );
if (subspaceModel.productAllocations?.length) { const allocationsToRemove = subspaces.flatMap(
for (const allocation of subspaceModel.productAllocations) { (subspace) => subspace.productAllocations,
);
if (allocationsToRemove.length > 0) {
const spaceAllocationsMap = new Map<
string,
SpaceModelProductAllocationEntity
>();
for (const allocation of allocationsToRemove) {
const product = allocation.product; const product = allocation.product;
const tags = allocation.tags; const tags = allocation.tags;
const spaceModel = allocation.subspaceModel.spaceModel;
const spaceAllocation = await queryRunner.manager.findOne( const spaceAllocationKey = `${spaceModel.uuid}-${product.uuid}`;
SpaceModelProductAllocationEntity,
{ if (!spaceAllocationsMap.has(spaceAllocationKey)) {
where: { const spaceAllocation = await queryRunner.manager.findOne(
spaceModel: subspaceModel.spaceModel, SpaceModelProductAllocationEntity,
product: { uuid: product.uuid }, {
where: {
spaceModel: { uuid: spaceModel.uuid },
product: { uuid: product.uuid },
},
relations: ['tags'],
}, },
relations: ['tags'], );
}, if (spaceAllocation) {
); spaceAllocationsMap.set(spaceAllocationKey, spaceAllocation);
}
}
const spaceAllocation = spaceAllocationsMap.get(spaceAllocationKey);
if (spaceAllocation) { if (spaceAllocation) {
const existingTagUuids = new Set( const existingTagUuids = new Set(
spaceAllocation.tags.map((tag) => tag.uuid), spaceAllocation.tags.map((tag) => tag.uuid),
@ -173,29 +212,65 @@ export class SubSpaceModelService {
const newTags = tags.filter( const newTags = tags.filter(
(tag) => !existingTagUuids.has(tag.uuid), (tag) => !existingTagUuids.has(tag.uuid),
); );
spaceAllocation.tags.push(...newTags);
await queryRunner.manager.save(spaceAllocation); if (newTags.length > 0) {
spaceAllocation.tags.push(...newTags);
await queryRunner.manager.save(spaceAllocation);
}
} else { } else {
const newSpaceAllocation = queryRunner.manager.create( const newSpaceAllocation = queryRunner.manager.create(
SpaceModelProductAllocationEntity, SpaceModelProductAllocationEntity,
{ {
spaceModel: subspaceModel.spaceModel, spaceModel: spaceModel,
product: product, product: product,
tags: tags, tags: tags,
}, },
); );
await queryRunner.manager.save(newSpaceAllocation); await queryRunner.manager.save(newSpaceAllocation);
} }
await queryRunner.manager.remove(allocation);
} }
await queryRunner.manager.remove(
SubspaceModelProductAllocationEntity,
allocationsToRemove,
);
} }
deleteResults.push({ uuid: dto.uuid }); await queryRunner.manager
} .createQueryBuilder()
.delete()
.from('subspace_model_product_tags')
.where(
'subspace_model_product_allocation_id NOT IN ' +
queryRunner.manager
.createQueryBuilder()
.select('uuid')
.from(SubspaceModelProductAllocationEntity, 'allocation')
.getQuery(),
)
.execute();
return deleteResults; deleteResults.push(...subspaceUuids.map((uuid) => ({ uuid })));
return deleteResults;
} catch (error) {
if (error instanceof QueryFailedError) {
throw new HttpException(
`Database query failed: ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
} else if (error instanceof TypeError) {
throw new HttpException(
`Invalid data encountered: ${error.message}`,
HttpStatus.BAD_REQUEST,
);
} else {
throw new HttpException(
`Unexpected error during subspace deletion: ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
} }
async updateSubspaceModel( async updateSubspaceModel(