diff --git a/src/space-model/common/services/base-product-item-model.service.ts b/src/space-model/common/services/base-product-item-model.service.ts index 80c8119..4d67e6d 100644 --- a/src/space-model/common/services/base-product-item-model.service.ts +++ b/src/space-model/common/services/base-product-item-model.service.ts @@ -57,4 +57,23 @@ export abstract class BaseProductItemService { ); } } + + protected async saveProductItems( + productItems: T[], + targetRepository: any, + queryRunner: QueryRunner, + ): Promise { + try { + const savedItem = await queryRunner.manager.save( + targetRepository, + productItems, + ); + return savedItem; + } catch (error) { + throw new HttpException( + error.message || 'An error occurred while creating product items.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/src/space-model/interfaces/update-subspace.interface.ts b/src/space-model/interfaces/update-subspace.interface.ts index a49491f..05982a4 100644 --- a/src/space-model/interfaces/update-subspace.interface.ts +++ b/src/space-model/interfaces/update-subspace.interface.ts @@ -21,6 +21,12 @@ export interface IModifySubspaceModelInterface { delete?: IDeletedSubsaceModelInterface[]; } +export interface IModifiedProductItemsModelsInterface { + new?: SubspaceProductItemModelEntity[]; + update?: SubspaceProductItemModelEntity[]; + delete?: string[]; +} + export interface IUpdateSubspaceModelInterface { subspaceName?: string; uuid: string; diff --git a/src/space-model/services/subspace/subspace-product-item-model.service.ts b/src/space-model/services/subspace/subspace-product-item-model.service.ts index 85989f8..cdd0688 100644 --- a/src/space-model/services/subspace/subspace-product-item-model.service.ts +++ b/src/space-model/services/subspace/subspace-product-item-model.service.ts @@ -7,7 +7,13 @@ import { SubspaceProductModelEntity, } from '@app/common/modules/space-model'; import { BaseProductItemService } from '../../common'; -import { CreateProductItemModelDto } from '../../dtos'; +import { + CreateProductItemModelDto, + DeleteProductItemModelDto, + ProductItemModelModificationDto, + UpdateProductItemModelDto, +} from '../../dtos'; +import { IModifiedProductItemsModelsInterface } from 'src/space-model/interfaces'; @Injectable() export class SubspaceProductItemModelService extends BaseProductItemService { @@ -17,7 +23,7 @@ export class SubspaceProductItemModelService extends BaseProductItemService { super(); } - async createProdutItemModel( + async createProductItemModel( itemModelDtos: CreateProductItemModelDto[], subspaceProductModel: SubspaceProductModelEntity, spaceModel: SpaceModelEntity, @@ -29,7 +35,9 @@ export class SubspaceProductItemModelService extends BaseProductItemService { HttpStatus.BAD_REQUEST, ); } + await this.validateTags(itemModelDtos, queryRunner, spaceModel); + try { const productItems = itemModelDtos.map((dto) => queryRunner.manager.create(this.subspaceProductItemRepository.target, { @@ -37,19 +45,131 @@ export class SubspaceProductItemModelService extends BaseProductItemService { subspaceProductModel, }), ); - - await queryRunner.manager.save(productItems); - return productItems; + return await this.saveProductItems( + productItems, + this.subspaceProductItemRepository, + queryRunner, + ); } catch (error) { - if (error instanceof HttpException) { - throw error; - } - - throw new HttpException( - error.message || - 'An unexpected error occurred while creating product items.', - HttpStatus.INTERNAL_SERVER_ERROR, + this.handleException( + error, + 'An unexpected error occurred while creating product items.', ); } } + + async updateProductItemModel( + dtos: UpdateProductItemModelDto[], + spaceModel: SpaceModelEntity, + queryRunner: QueryRunner, + ): Promise { + try { + await this.validateTags(dtos, queryRunner, spaceModel); + + const productItemModels = await Promise.all( + dtos.map(async (dto) => { + const productItemModel = await this.findOne(dto.productModelUuid); + productItemModel.tag = dto.tag; + return productItemModel; + }), + ); + + return (await this.saveProductItems( + productItemModels, + this.subspaceProductItemRepository, + queryRunner, + )) as SubspaceProductItemModelEntity[]; + } catch (error) { + this.handleException( + error, + 'Failed to save Subspace Product Item Model.', + ); + } + } + + async deleteProductModel( + dtos: DeleteProductItemModelDto[], + queryRunner: QueryRunner, + ): Promise { + try { + const productItemModels = await Promise.all( + dtos.map(async (dto) => { + const productItemModel = await this.findOne(dto.productModelUuid); + productItemModel.disabled = true; + return productItemModel; + }), + ); + + const response = (await this.saveProductItems( + productItemModels, + this.subspaceProductItemRepository, + queryRunner, + )) as SubspaceProductItemModelEntity[]; + + return response.map((item) => item.uuid); + } catch (error) { + this.handleException(error, 'Failed to modify SpaceModels.'); + } + } + + async findOne(uuid: string): Promise { + const productItemModel = await this.subspaceProductItemRepository.findOne({ + where: { uuid }, + }); + + if (!productItemModel) { + throw new HttpException( + `Product item model not found for ${uuid}`, + HttpStatus.NOT_FOUND, + ); + } + + return productItemModel; + } + + async modifyProductItemModel( + dto: ProductItemModelModificationDto, + productModel: SubspaceProductModelEntity, + spaceModel: SpaceModelEntity, + queryRunner: QueryRunner, + ): Promise { + const productItemModels: IModifiedProductItemsModelsInterface = {}; + + try { + if (dto.add) { + productItemModels.new = await this.createProductItemModel( + dto.add, + productModel, + spaceModel, + queryRunner, + ); + } + if (dto.update) { + productItemModels.update = await this.updateProductItemModel( + dto.update, + spaceModel, + queryRunner, + ); + } + if (dto.delete) { + productItemModels.delete = await this.deleteProductModel( + dto.delete, + queryRunner, + ); + } + return productItemModels; + } catch (error) { + this.handleException(error, 'Failed to modify SpaceModels.'); + } + } + + private handleException(error: unknown, defaultMessage: string): never { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( + (error as Error).message || defaultMessage, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } } diff --git a/src/space-model/services/subspace/subspace-product-model.service.ts b/src/space-model/services/subspace/subspace-product-model.service.ts index 9dfe733..4e145bc 100644 --- a/src/space-model/services/subspace/subspace-product-model.service.ts +++ b/src/space-model/services/subspace/subspace-product-model.service.ts @@ -50,7 +50,7 @@ export class SubspaceProductModelService extends BaseProductModelService { spaceProductModelDtos.map(async (dto, index) => { const savedModel = savedProductModels[index]; const productItemModels = - await this.subspaceProductItemModelService.createProdutItemModel( + await this.subspaceProductItemModelService.createProductItemModel( dto.items, savedModel, spaceModel,