added space product service

This commit is contained in:
hannathkadher
2024-11-20 16:34:44 +04:00
parent bc1638aba4
commit 11564eece7
6 changed files with 128 additions and 1 deletions

View File

@ -1,10 +1,13 @@
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { import {
IsArray,
IsBoolean, IsBoolean,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsString, IsString,
IsUUID, IsUUID,
ValidateNested,
} from 'class-validator'; } from 'class-validator';
export class AddSpaceDto { export class AddSpaceDto {
@ -32,6 +35,11 @@ export class AddSpaceDto {
}) })
@IsBoolean() @IsBoolean()
isPrivate: boolean; isPrivate: boolean;
@IsArray()
@ValidateNested({ each: true })
@Type(() => ProductAssignmentDto)
products: ProductAssignmentDto[];
} }
export class AddUserSpaceDto { export class AddUserSpaceDto {
@ -69,7 +77,16 @@ export class AddUserSpaceUsingCodeDto {
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
public inviteCode: string; public inviteCode: string;
constructor(dto: Partial<AddUserSpaceDto>) { constructor(dto: Partial<AddUserSpaceDto>) {
Object.assign(this, dto); Object.assign(this, dto);
} }
} }
class ProductAssignmentDto {
@IsNotEmpty()
productId: string;
@IsNotEmpty()
count: number;
}

View File

@ -3,3 +3,4 @@ export * from './space-user.service';
export * from './space-device.service'; export * from './space-device.service';
export * from './subspace'; export * from './subspace';
export * from './space-scene.service'; export * from './space-scene.service';
export * from './space-products';

View File

@ -0,0 +1 @@
export * from './space-products.service';

View File

@ -0,0 +1,95 @@
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { ProductRepository } from '@app/common/modules/product/repositories';
import { SpaceEntity } from '@app/common/modules/space/entities';
import { SpaceProductEntity } from '@app/common/modules/space/entities/space-product.entity';
import { SpaceProductRepository } from '@app/common/modules/space/repositories';
import { In } from 'typeorm';
@Injectable()
export class SpaceProductService {
constructor(
private readonly productRepository: ProductRepository,
private readonly spaceProductRepository: SpaceProductRepository,
) {}
async assignProductsToSpace(
space: SpaceEntity,
products: { productId: string; count: number }[],
): Promise<SpaceProductEntity[]> {
try {
const uniqueProducts = this.validateUniqueProducts(products);
const productEntities = await this.getProductEntities(uniqueProducts);
const spaceProductEntities = uniqueProducts.map(
({ productId, count }) => {
const product = productEntities.get(productId);
if (!product) {
throw new HttpException(
`Product with ID ${productId} not found`,
HttpStatus.NOT_FOUND,
);
}
return this.spaceProductRepository.create({
space,
product,
productCount: count,
});
},
);
return await this.spaceProductRepository.save(spaceProductEntities);
} catch (error) {
console.error('Error assigning products to space:', error);
if (!(error instanceof HttpException)) {
throw new HttpException(
'An error occurred while assigning products to the space',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
throw error;
}
}
private validateUniqueProducts(
products: { productId: string; count: number }[],
): { productId: string; count: number }[] {
const productIds = new Set();
const uniqueProducts = [];
for (const product of products) {
if (productIds.has(product.productId)) {
throw new HttpException(
`Duplicate product ID found: ${product.productId}`,
HttpStatus.BAD_REQUEST,
);
}
productIds.add(product.productId);
uniqueProducts.push(product);
}
return uniqueProducts;
}
private async getProductEntities(
products: { productId: string; count: number }[],
): Promise<Map<string, any>> {
try {
const productIds = products.map((p) => p.productId);
const productEntities = await this.productRepository.find({
where: { prodId: In(productIds) },
});
return new Map(productEntities.map((p) => [p.prodId, p]));
} catch (error) {
console.error('Error fetching product entities:', error);
throw new HttpException(
'Failed to fetch product entities',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
}

View File

@ -11,12 +11,14 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { CommunityRepository } from '@app/common/modules/community/repositories'; import { CommunityRepository } from '@app/common/modules/community/repositories';
import { SpaceEntity } from '@app/common/modules/space/entities'; import { SpaceEntity } from '@app/common/modules/space/entities';
import { generateRandomString } from '@app/common/helper/randomString'; import { generateRandomString } from '@app/common/helper/randomString';
import { SpaceProductService } from './space-products';
@Injectable() @Injectable()
export class SpaceService { export class SpaceService {
constructor( constructor(
private readonly spaceRepository: SpaceRepository, private readonly spaceRepository: SpaceRepository,
private readonly communityRepository: CommunityRepository, private readonly communityRepository: CommunityRepository,
private readonly spaceProductService: SpaceProductService,
) {} ) {}
async createSpace( async createSpace(
@ -25,7 +27,7 @@ export class SpaceService {
): Promise<BaseResponseDto> { ): Promise<BaseResponseDto> {
let parent: SpaceEntity | null = null; let parent: SpaceEntity | null = null;
const { parentUuid } = addSpaceDto; const { parentUuid, products } = addSpaceDto;
const community = await this.communityRepository.findOne({ const community = await this.communityRepository.findOne({
where: { uuid: communityId }, where: { uuid: communityId },
}); });
@ -60,6 +62,13 @@ export class SpaceService {
await this.spaceRepository.save(newSpace); await this.spaceRepository.save(newSpace);
if (products && products.length > 0) {
await this.spaceProductService.assignProductsToSpace(
newSpace,
products,
);
}
return new SuccessResponseDto({ return new SuccessResponseDto({
statusCode: HttpStatus.CREATED, statusCode: HttpStatus.CREATED,
data: newSpace, data: newSpace,

View File

@ -11,6 +11,7 @@ import {
} from './controllers'; } from './controllers';
import { import {
SpaceDeviceService, SpaceDeviceService,
SpaceProductService,
SpaceSceneService, SpaceSceneService,
SpaceService, SpaceService,
SpaceUserService, SpaceUserService,
@ -18,6 +19,7 @@ import {
SubSpaceService, SubSpaceService,
} from './services'; } from './services';
import { import {
SpaceProductRepository,
SpaceRepository, SpaceRepository,
SubspaceRepository, SubspaceRepository,
} from '@app/common/modules/space/repositories'; } from '@app/common/modules/space/repositories';
@ -71,6 +73,8 @@ import { SceneDeviceRepository } from '@app/common/modules/scene-device/reposito
DeviceStatusFirebaseService, DeviceStatusFirebaseService,
DeviceStatusLogRepository, DeviceStatusLogRepository,
SceneDeviceRepository, SceneDeviceRepository,
SpaceProductService,
SpaceProductRepository,
], ],
exports: [SpaceService], exports: [SpaceService],
}) })