import { SpaceModelEntity, SubspaceModelEntity, SubspaceProductModelEntity, SubspaceProductModelRepository, } from '@app/common/modules/space-model'; import { QueryRunner } from 'typeorm'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { SubspaceProductItemModelService } from './subspace-product-item-model.service'; import { CreateProductModelDto, ProductModelModificationDto, UpdateProductModelDto, } from '../../dtos'; import { BaseProductModelService } from '../../common'; import { ProductService } from 'src/product/services'; import { IModifiedProductModelsInterface, ProductModelInterface, } from '../../interfaces'; @Injectable() export class SubspaceProductModelService extends BaseProductModelService { constructor( private readonly subpaceProductModelRepository: SubspaceProductModelRepository, productService: ProductService, private readonly subspaceProductItemModelService: SubspaceProductItemModelService, ) { super(productService); } async createSubspaceProductModels( spaceProductModelDtos: CreateProductModelDto[], spaceModel: SpaceModelEntity, subspaceModel: SubspaceModelEntity, queryRunner: QueryRunner, ): Promise { try { if (!spaceProductModelDtos?.length) return; const productModels = await Promise.all( spaceProductModelDtos.map(async (dto) => { this.validateProductCount(dto); const product = await this.getProduct(dto.productUuid); return queryRunner.manager.create( this.subpaceProductModelRepository.target, { product, productCount: dto.productCount, subspaceModel, }, ); }), ); const savedProductModels = await queryRunner.manager.save(productModels); const newProductModels = await Promise.all( spaceProductModelDtos.map(async (dto, index) => { const savedModel = savedProductModels[index]; const productItemModels = await this.subspaceProductItemModelService.createProductItemModel( dto.items, savedModel, spaceModel, queryRunner, ); return { productModel: savedModel, productItemModels, } as ProductModelInterface; }), ); return newProductModels; } catch (error) { if (error instanceof HttpException) { throw error; } throw new HttpException( error.message || 'An unexpected error occurred while creating product models.', HttpStatus.INTERNAL_SERVER_ERROR, ); } } async updateSubspaceProductModels(dtos: UpdateProductModelDto[]) { try { for (const dto of dtos) { await this.findOne(dto.productModelUuid); const newCount = dto.productCount; if ( dto.items.add.length + dto.items.delete.length + dto.items.delete.length !== newCount ) { throw new HttpException( `Invalid list of items`, HttpStatus.BAD_REQUEST, ); } } } catch (error) {} } async modifySubspaceProductModels( dto: ProductModelModificationDto, spaceModel: SpaceModelEntity, subspaceModel: SubspaceModelEntity, queryRunner: QueryRunner, ) { const productItemModels: IModifiedProductModelsInterface = {}; try { productItemModels.add = await this.createSubspaceProductModels( dto.add, spaceModel, subspaceModel, queryRunner, ); } catch (error) { if (error instanceof HttpException) { throw error; } throw new HttpException( 'Failed to modify Subspace product model', HttpStatus.INTERNAL_SERVER_ERROR, ); } } async findOne(uuid: string): Promise { const productModel = await this.subpaceProductModelRepository.findOne({ where: { uuid, }, }); if (!productModel) throw new HttpException( `Subspace Product model with uuid ${uuid} not found`, HttpStatus.NOT_FOUND, ); return productModel; } }