updated subspace models update/delete

This commit is contained in:
hannathkadher
2024-12-22 13:26:03 +04:00
parent 9245c47ef5
commit 1df462712b
5 changed files with 290 additions and 87 deletions

View File

@ -7,7 +7,7 @@ import {
IsOptional, IsOptional,
ValidateNested, ValidateNested,
} from 'class-validator'; } from 'class-validator';
import { CreateProductModelDto } from '../product-model-dtos'; import { ProductModelModificationDto } from '../product-model-dtos';
export class UpdateSubspaceModelDto { export class UpdateSubspaceModelDto {
@ApiProperty({ @ApiProperty({
@ -23,12 +23,11 @@ export class UpdateSubspaceModelDto {
subspaceUuid: string; subspaceUuid: string;
@ApiProperty({ @ApiProperty({
description: 'List of products included in the model', description: 'Products models modified in the model',
type: [CreateProductModelDto], type: ProductModelModificationDto,
}) })
@IsArray()
@IsOptional() @IsOptional()
@ValidateNested({ each: true }) @ValidateNested({ each: true })
@Type(() => CreateProductModelDto) @Type(() => ProductModelModificationDto)
spaceProductModels?: CreateProductModelDto[]; updatedProductModels?: ProductModelModificationDto;
} }

View File

@ -30,12 +30,20 @@ export interface IModifiedProductItemsModelsInterface {
export interface IUpdateSubspaceModelInterface { export interface IUpdateSubspaceModelInterface {
subspaceName?: string; subspaceName?: string;
uuid: string; uuid: string;
productModels?: IModifiedProductItemsModelsInterface[];
} }
export interface IDeletedSubsaceModelInterface { export interface IDeletedSubsaceModelInterface {
uuid: string; uuid: string;
} }
export interface IUpdatedProductModelInterface {
productModelUuid: string;
productModifiedItemModel: IModifiedProductItemsModelsInterface;
}
export interface IModifiedProductModelsInterface { export interface IModifiedProductModelsInterface {
add?: ProductModelInterface[]; add?: ProductModelInterface[];
update?: IUpdatedProductModelInterface[];
delete?: string[];
} }

View File

@ -72,49 +72,95 @@ export class SubSpaceModelService {
async updateSubspaceModels( async updateSubspaceModels(
updateDtos: UpdateSubspaceModelDto[], updateDtos: UpdateSubspaceModelDto[],
spaceModel: SpaceModelEntity,
queryRunner: QueryRunner, queryRunner: QueryRunner,
) { ): Promise<IUpdateSubspaceModelInterface[]> {
const updateResults: IUpdateSubspaceModelInterface[] = []; try {
const updateResults: IUpdateSubspaceModelInterface[] = [];
const updatePromises = updateDtos.map(async (dto) => {
try { try {
for (const dto of updateDtos) {
const subspaceModel = await this.findOne(dto.subspaceUuid); const subspaceModel = await this.findOne(dto.subspaceUuid);
if (!subspaceModel) {
throw new HttpException(
`Subspace model with UUID ${dto.subspaceUuid} not found.`,
HttpStatus.NOT_FOUND,
);
}
const updateResult: IUpdateSubspaceModelInterface = { const updateResult: IUpdateSubspaceModelInterface = {
uuid: dto.subspaceUuid, uuid: dto.subspaceUuid,
}; };
if (dto.subspaceName) { if (dto.subspaceName) {
subspaceModel.subspaceName = dto.subspaceName; await this.updateSubspaceName(
await queryRunner.manager.update( dto.subspaceUuid,
this.subspaceModelRepository.target, dto.subspaceName,
{ uuid: dto.subspaceUuid }, queryRunner,
{ subspaceName: dto.subspaceName },
); );
subspaceModel.subspaceName = dto.subspaceName;
updateResult.subspaceName = dto.subspaceName; updateResult.subspaceName = dto.subspaceName;
} }
updateResults.push(updateResult); if (dto.updatedProductModels) {
await this.subSpaceProducetModelService.modifySubspaceProductModels(
dto.updatedProductModels,
spaceModel,
subspaceModel,
queryRunner,
);
} }
updateResults.push(updateResult);
} catch (error) {
throw new HttpException(
`Failed to update subspace model with UUID ${dto.subspaceUuid}: ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
});
await Promise.all(updatePromises);
return updateResults; return updateResults;
} catch (error) { } catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException( throw new HttpException(
error.message || 'Failed to update SpaceModels', error.message || 'Failed to update subspace models.',
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} }
} }
async deleteSubspaceModels( private async updateSubspaceName(
dtos: DeleteSubspaceModelDto[], uuid: string,
subspaceName: string,
queryRunner: QueryRunner, queryRunner: QueryRunner,
) { ): Promise<void> {
const deleteResults: IDeletedSubsaceModelInterface[] = []; await queryRunner.manager.update(
this.subspaceModelRepository.target,
{ uuid },
{ subspaceName },
);
}
async deleteSubspaceModels(
deleteDtos: DeleteSubspaceModelDto[],
queryRunner: QueryRunner,
): Promise<IDeletedSubsaceModelInterface[]> {
try { try {
for (const dto of dtos) { const deleteResults: IDeletedSubsaceModelInterface[] = [];
await this.findOne(dto.subspaceUuid);
const deletePromises = deleteDtos.map(async (dto) => {
try {
const subspaceModel = await this.findOne(dto.subspaceUuid);
if (!subspaceModel) {
throw new HttpException(
`Subspace model with UUID ${dto.subspaceUuid} not found.`,
HttpStatus.NOT_FOUND,
);
}
await queryRunner.manager.update( await queryRunner.manager.update(
this.subspaceModelRepository.target, this.subspaceModelRepository.target,
@ -122,12 +168,30 @@ export class SubSpaceModelService {
{ disabled: true }, { disabled: true },
); );
deleteResults.push({ uuid: dto.subspaceUuid }); if (subspaceModel.productModels.length > 0) {
await this.subSpaceProducetModelService.disableProductModels(
subspaceModel.productModels,
queryRunner,
);
} }
deleteResults.push({ uuid: dto.subspaceUuid });
} catch (error) {
throw new HttpException(
`Failed to delete subspace model with UUID ${dto.subspaceUuid}: ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
});
await Promise.all(deletePromises);
return deleteResults; return deleteResults;
} catch (error) { } catch (error) {
console.error(`Bulk delete operation failed: ${error.message}`); throw new HttpException(
throw new Error('Bulk delete operation failed.'); 'Bulk delete operation failed. Please try again.',
HttpStatus.INTERNAL_SERVER_ERROR,
);
} }
} }
@ -136,6 +200,7 @@ export class SubSpaceModelService {
where: { where: {
uuid: subspaceUuid, uuid: subspaceUuid,
}, },
relations: ['productModels', 'productModels.itemModels'],
}); });
if (!subspace) { if (!subspace) {
throw new HttpException( throw new HttpException(
@ -181,36 +246,48 @@ export class SubSpaceModelService {
dto: ModifySubspacesModelDto, dto: ModifySubspacesModelDto,
spaceModel: SpaceModelEntity, spaceModel: SpaceModelEntity,
queryRunner: QueryRunner, queryRunner: QueryRunner,
) { ): Promise<IModifySubspaceModelInterface> {
const subspaces: IModifySubspaceModelInterface = { const subspaces: IModifySubspaceModelInterface = {
spaceModelUuid: spaceModel.uuid, spaceModelUuid: spaceModel.uuid,
}; };
try { try {
const actions = [];
if (dto.add) { if (dto.add) {
const addedSubspaces = await this.createSubSpaceModels( actions.push(
dto.add, this.createSubSpaceModels(dto.add, spaceModel, queryRunner).then(
spaceModel, (addedSubspaces) => {
queryRunner,
);
subspaces.new = addedSubspaces; subspaces.new = addedSubspaces;
} else if (dto.update) { },
const updatedSubspaces = await this.updateSubspaceModels( ),
dto.update,
queryRunner,
); );
subspaces.update = updatedSubspaces;
} else if (dto.delete) {
const deletedSubspaces = await this.deleteSubspaceModels(
dto.delete,
queryRunner,
);
subspaces.delete = deletedSubspaces;
} }
if (dto.update) {
actions.push(
this.updateSubspaceModels(dto.update, spaceModel, queryRunner).then(
(updatedSubspaces) => {
subspaces.update = updatedSubspaces;
},
),
);
}
if (dto.delete) {
actions.push(
this.deleteSubspaceModels(dto.delete, queryRunner).then(
(deletedSubspaces) => {
subspaces.delete = deletedSubspaces;
},
),
);
}
await Promise.all(actions);
return subspaces; return subspaces;
} catch (error) { } catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException( throw new HttpException(
error.message || 'Failed to modify SpaceModels', error.message || 'Failed to modify SpaceModels',
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,

View File

@ -92,6 +92,7 @@ export class SubspaceProductItemModelService extends BaseProductItemService {
queryRunner: QueryRunner, queryRunner: QueryRunner,
): Promise<string[]> { ): Promise<string[]> {
try { try {
if (dtos.length === 0) return;
const productItemModels = await Promise.all( const productItemModels = await Promise.all(
dtos.map(async (dto) => { dtos.map(async (dto) => {
const productItemModel = await this.findOne(dto.productModelUuid); const productItemModel = await this.findOne(dto.productModelUuid);
@ -100,16 +101,27 @@ export class SubspaceProductItemModelService extends BaseProductItemService {
}), }),
); );
const response = (await this.saveProductItems( const disabledItemModels = await this.disableProductItemModels(
productItemModels,
queryRunner,
);
return disabledItemModels.map((item) => item.uuid);
} catch (error) {
this.handleException(error, 'Failed to delete SpaceModels.');
}
}
async disableProductItemModels(
productItemModels: SubspaceProductItemModelEntity[],
queryRunner: QueryRunner,
): Promise<SubspaceProductItemModelEntity[]> {
productItemModels.forEach((model) => (model.disabled = true));
return (await this.saveProductItems(
productItemModels, productItemModels,
this.subspaceProductItemRepository, this.subspaceProductItemRepository,
queryRunner, queryRunner,
)) as SubspaceProductItemModelEntity[]; )) as SubspaceProductItemModelEntity[];
return response.map((item) => item.uuid);
} catch (error) {
this.handleException(error, 'Failed to modify SpaceModels.');
}
} }
async findOne(uuid: string): Promise<SubspaceProductItemModelEntity> { async findOne(uuid: string): Promise<SubspaceProductItemModelEntity> {

View File

@ -4,12 +4,13 @@ import {
SubspaceProductModelEntity, SubspaceProductModelEntity,
SubspaceProductModelRepository, SubspaceProductModelRepository,
} from '@app/common/modules/space-model'; } from '@app/common/modules/space-model';
import { QueryRunner } from 'typeorm'; import { In, QueryRunner } from 'typeorm';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { SubspaceProductItemModelService } from './subspace-product-item-model.service'; import { SubspaceProductItemModelService } from './subspace-product-item-model.service';
import { import {
CreateProductModelDto, CreateProductModelDto,
DeleteProductModelDto,
ProductModelModificationDto, ProductModelModificationDto,
UpdateProductModelDto, UpdateProductModelDto,
} from '../../dtos'; } from '../../dtos';
@ -17,6 +18,7 @@ import { BaseProductModelService } from '../../common';
import { ProductService } from 'src/product/services'; import { ProductService } from 'src/product/services';
import { import {
IModifiedProductModelsInterface, IModifiedProductModelsInterface,
IUpdatedProductModelInterface,
ProductModelInterface, ProductModelInterface,
} from '../../interfaces'; } from '../../interfaces';
@ -83,34 +85,138 @@ export class SubspaceProductModelService extends BaseProductModelService {
} }
} }
async updateSubspaceProductModels(dtos: UpdateProductModelDto[]) { async updateSubspaceProductModels(
try { dtos: UpdateProductModelDto[],
for (const dto of dtos) {
await this.findOne(dto.productModelUuid);
}
} catch (error) {}
}
async modifySubspaceProductModels(
dto: ProductModelModificationDto,
spaceModel: SpaceModelEntity, spaceModel: SpaceModelEntity,
subspaceModel: SubspaceModelEntity,
queryRunner: QueryRunner, queryRunner: QueryRunner,
) { ): Promise<IUpdatedProductModelInterface[]> {
const productItemModels: IModifiedProductModelsInterface = {};
try { try {
productItemModels.add = await this.createSubspaceProductModels( const updatedProductModels = await Promise.all(
dto.add, dtos.map(async (dto) => {
const productModel = await this.findOne(dto.productModelUuid);
const productModifiedItemModel =
await this.subspaceProductItemModelService.modifyProductItemModel(
dto.items,
productModel,
spaceModel, spaceModel,
subspaceModel,
queryRunner, queryRunner,
); );
return {
productModelUuid: productModel.uuid,
productModifiedItemModel,
};
}),
);
return updatedProductModels;
} catch (error) { } catch (error) {
if (error instanceof HttpException) { if (error instanceof HttpException) {
throw error; throw error;
} }
throw new HttpException( throw new HttpException(
'Failed to modify Subspace product model', 'Failed to update Subspace product model',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async removeSubspaceProductModels(
deleteDtos: DeleteProductModelDto[],
transactionRunner: QueryRunner,
): Promise<string[]> {
try {
const productModels = await Promise.all(
deleteDtos.map((dto) => this.findOne(dto.productModelUuid)),
);
return await this.disableProductModels(productModels, transactionRunner);
} catch (error) {
throw new HttpException(
'Failed to remove subspace product models',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async disableProductModels(
productModels: SubspaceProductModelEntity[],
transactionRunner: QueryRunner,
): Promise<string[]> {
try {
const productModelUuids = productModels.map((model) => model.uuid);
await transactionRunner.manager.update(
this.subpaceProductModelRepository.target,
{ uuid: In(productModelUuids) },
{ disabled: true },
);
const itemModelDisables = productModels.map((model) =>
model.itemModels.length > 0
? this.subspaceProductItemModelService.disableProductItemModels(
model.itemModels,
transactionRunner,
)
: Promise.resolve(),
);
await Promise.all(itemModelDisables);
return productModelUuids;
} catch (error) {
throw new HttpException(
'Failed to disable product models',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async modifySubspaceProductModels(
modificationDto: ProductModelModificationDto,
spaceEntity: SpaceModelEntity,
subspaceEntity: SubspaceModelEntity,
transactionRunner: QueryRunner,
): Promise<IModifiedProductModelsInterface> {
const modifiedProductModels: IModifiedProductModelsInterface = {};
try {
await Promise.all([
modificationDto.add
? this.createSubspaceProductModels(
modificationDto.add,
spaceEntity,
subspaceEntity,
transactionRunner,
).then((addedModels) => {
modifiedProductModels.add = addedModels;
})
: Promise.resolve(),
modificationDto.update
? this.updateSubspaceProductModels(
modificationDto.update,
spaceEntity,
transactionRunner,
).then((updatedModels) => {
modifiedProductModels.update = updatedModels;
})
: Promise.resolve(),
modificationDto.delete
? this.removeSubspaceProductModels(
modificationDto.delete,
transactionRunner,
).then((deletedModels) => {
modifiedProductModels.delete = deletedModels;
})
: Promise.resolve(),
]);
return modifiedProductModels;
} catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException(
'Failed to modify subspace product models',
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} }
@ -121,6 +227,7 @@ export class SubspaceProductModelService extends BaseProductModelService {
where: { where: {
uuid, uuid,
}, },
relations: ['itemModels'],
}); });
if (!productModel) if (!productModel)
throw new HttpException( throw new HttpException(