mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-26 16:14:55 +00:00
added space product service
This commit is contained in:
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@ -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';
|
||||||
|
|||||||
1
src/space/services/space-products/index.ts
Normal file
1
src/space/services/space-products/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './space-products.service';
|
||||||
95
src/space/services/space-products/space-products.service.ts
Normal file
95
src/space/services/space-products/space-products.service.ts
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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,
|
||||||
|
|||||||
@ -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],
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user