From acc8f3ef4d1599e3220efa3a1c1da4351e59ec7e Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Mon, 24 Feb 2025 20:04:36 +0400 Subject: [PATCH] updated delete action --- ...bspace-model-product-allocation.service.ts | 63 +++++--- .../subspace/subspace-model.service.ts | 151 +++++++++++++----- 2 files changed, 158 insertions(+), 56 deletions(-) diff --git a/src/space-model/services/subspace/subspace-model-product-allocation.service.ts b/src/space-model/services/subspace/subspace-model-product-allocation.service.ts index 97d4165..0023357 100644 --- a/src/space-model/services/subspace/subspace-model-product-allocation.service.ts +++ b/src/space-model/services/subspace/subspace-model-product-allocation.service.ts @@ -401,7 +401,7 @@ export class SubspaceModelProductAllocationService { async processDeleteActions( dtos: ModifyTagModelDto[], queryRunner: QueryRunner, - ): Promise { + ): Promise { try { if (!dtos || dtos.length === 0) { throw new Error('No DTOs provided for deletion.'); @@ -411,7 +411,7 @@ export class SubspaceModelProductAllocationService { .filter((dto) => dto.action === ModifyAction.DELETE && dto.tagUuid) .map((dto) => dto.tagUuid); - if (tagUuidsToDelete.length === 0) return; + if (tagUuidsToDelete.length === 0) return []; const allocationsToUpdate = await queryRunner.manager.find( 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[] = []; + for (const allocation of allocationsToUpdate) { const updatedTags = allocation.tags.filter( (tag) => !tagUuidsToDelete.includes(tag.uuid), @@ -433,8 +435,12 @@ export class SubspaceModelProductAllocationService { continue; } - allocation.tags = updatedTags; - allocationUpdates.push(allocation); + if (updatedTags.length === 0) { + deletedAllocations.push(allocation); + } else { + allocation.tags = updatedTags; + allocationUpdates.push(allocation); + } } if (allocationUpdates.length > 0) { @@ -444,6 +450,13 @@ export class SubspaceModelProductAllocationService { ); } + if (deletedAllocations.length > 0) { + await queryRunner.manager.remove( + SubspaceModelProductAllocationEntity, + deletedAllocations, + ); + } + await queryRunner.manager .createQueryBuilder() .delete() @@ -457,6 +470,8 @@ export class SubspaceModelProductAllocationService { .getQuery(), ) .execute(); + + return deletedAllocations; } catch (error) { throw this.handleError(error, `Failed to delete tags in subspace model`); } @@ -470,20 +485,32 @@ export class SubspaceModelProductAllocationService { spaceModel: SpaceModelEntity, queryRunner: QueryRunner, spaceTagUpdateDtos?: ModifyTagModelDto[], - ): Promise { + ): Promise<{ + addedAllocations: SubspaceModelProductAllocationEntity[]; + deletedAllocations: SubspaceModelProductAllocationEntity[]; + updatedSubspaceDtos: ModifySubspaceModelDto[]; + }> { try { - await Promise.all([ - this.processAddActions( - dtos, - projectUuid, - subspaceModel, - otherSubspaceModelUpdateDtos, - queryRunner, - spaceModel, - spaceTagUpdateDtos, - ), - this.processDeleteActions(dtos, queryRunner), - ]); + const addedSubspaceTags = await this.processAddActions( + dtos, + projectUuid, + subspaceModel, + otherSubspaceModelUpdateDtos, + queryRunner, + spaceModel, + spaceTagUpdateDtos, + ); + + const deletedTagAllocations = await this.processDeleteActions( + dtos, + queryRunner, + ); + + return { + addedAllocations: addedSubspaceTags.addedAllocations, + deletedAllocations: deletedTagAllocations, + updatedSubspaceDtos: addedSubspaceTags.updatedSubspaceDtos, + }; } catch (error) { throw this.handleError(error, 'Error while updating product allocations'); } diff --git a/src/space-model/services/subspace/subspace-model.service.ts b/src/space-model/services/subspace/subspace-model.service.ts index 603ea3e..5778e1e 100644 --- a/src/space-model/services/subspace/subspace-model.service.ts +++ b/src/space-model/services/subspace/subspace-model.service.ts @@ -2,12 +2,12 @@ import { SpaceModelEntity, SpaceModelProductAllocationEntity, SubspaceModelEntity, + SubspaceModelProductAllocationEntity, SubspaceModelRepository, } from '@app/common/modules/space-model'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { CreateSubspaceModelDto, ModifyTagModelDto } from '../../dtos'; -import { Not, QueryRunner } from 'typeorm'; -import { IDeletedSubsaceModelInterface } from 'src/space-model/interfaces'; +import { In, Not, QueryFailedError, QueryRunner } from 'typeorm'; 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'; @@ -89,6 +89,8 @@ export class SubSpaceModelService { }, ); const savedSubspace = await queryRunner.manager.save(subspaceModel); + + if (dto.tags) { await this.productAllocationService.updateProductAllocations( dto.tags, @@ -111,61 +113,98 @@ export class SubSpaceModelService { projectUuid: string, spaceTagUpdateDtos?: ModifyTagModelDto[], ) { + if (!dtos || dtos.length === 0) { + return; + } + 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); + await this.updateSubspaceModel( + combinedDtos, + spaceModel, + queryRunner, + projectUuid, + spaceTagUpdateDtos, + ); await this.handleAddAction( addDtos, spaceModel, queryRunner, projectUuid, - otherDtos, + combinedDtos, spaceTagUpdateDtos, ); - - await this.updateSubspaceModel( - otherDtos, - spaceModel, - queryRunner, - projectUuid, - spaceTagUpdateDtos, - ); - await this.deleteSubspaceModels(deleteDtos, queryRunner); } async deleteSubspaceModels( deleteDtos: ModifySubspaceModelDto[], queryRunner: QueryRunner, - ): Promise { - const deleteResults = []; + ) { + try { + if (!deleteDtos || deleteDtos.length === 0) { + throw new Error('No subspaces provided for deletion.'); + } - for (const dto of deleteDtos) { - const subspaceModel = await this.findOne(dto.uuid); + const deleteResults = []; + 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( - this.subspaceModelRepository.target, - { uuid: dto.uuid }, + SubspaceModelEntity, + { uuid: In(subspaceUuids) }, { disabled: true }, ); - if (subspaceModel.productAllocations?.length) { - for (const allocation of subspaceModel.productAllocations) { + const allocationsToRemove = subspaces.flatMap( + (subspace) => subspace.productAllocations, + ); + if (allocationsToRemove.length > 0) { + const spaceAllocationsMap = new Map< + string, + SpaceModelProductAllocationEntity + >(); + + for (const allocation of allocationsToRemove) { const product = allocation.product; const tags = allocation.tags; + const spaceModel = allocation.subspaceModel.spaceModel; - const spaceAllocation = await queryRunner.manager.findOne( - SpaceModelProductAllocationEntity, - { - where: { - spaceModel: subspaceModel.spaceModel, - product: { uuid: product.uuid }, + const spaceAllocationKey = `${spaceModel.uuid}-${product.uuid}`; + + if (!spaceAllocationsMap.has(spaceAllocationKey)) { + const spaceAllocation = await queryRunner.manager.findOne( + SpaceModelProductAllocationEntity, + { + 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) { const existingTagUuids = new Set( spaceAllocation.tags.map((tag) => tag.uuid), @@ -173,29 +212,65 @@ export class SubSpaceModelService { const newTags = tags.filter( (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 { const newSpaceAllocation = queryRunner.manager.create( SpaceModelProductAllocationEntity, { - spaceModel: subspaceModel.spaceModel, + spaceModel: spaceModel, product: product, tags: tags, }, ); - 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(