mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-27 10:34:53 +00:00
propagate add
This commit is contained in:
1
src/space-model/commands/index.ts
Normal file
1
src/space-model/commands/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './propogate-subspace-update-command';
|
||||
@ -0,0 +1,6 @@
|
||||
import { ICommand } from '@nestjs/cqrs';
|
||||
import { UpdatedSubspaceModelInterface } from '../interfaces';
|
||||
|
||||
export class PropogateSubspaceCommand implements ICommand {
|
||||
constructor(public readonly param: UpdatedSubspaceModelInterface) {}
|
||||
}
|
||||
@ -5,3 +5,4 @@ export * from './create-subspace-model.dto';
|
||||
export * from './project-param.dto';
|
||||
export * from './update-space-model.dto';
|
||||
export * from './space-model-param';
|
||||
export * from './update-subspace-model.dto';
|
||||
|
||||
@ -2,8 +2,9 @@ import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsArray, IsOptional, IsString, ValidateNested } from 'class-validator';
|
||||
import { CreateSubspaceModelDto } from './create-subspace-model.dto';
|
||||
import { Type } from 'class-transformer';
|
||||
import { UpdateSubspaceModelDto } from './update-subspace-model.dto';
|
||||
|
||||
export class UpdateSubspaceModelDto {
|
||||
export class UpdateSubspacesModelDto {
|
||||
@ApiProperty({
|
||||
description: 'List of subspaces to add',
|
||||
type: [CreateSubspaceModelDto],
|
||||
@ -14,7 +15,19 @@ export class UpdateSubspaceModelDto {
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => CreateSubspaceModelDto)
|
||||
add?: CreateSubspaceModelDto[];
|
||||
|
||||
@ApiProperty({
|
||||
description: 'List of subspaces to add',
|
||||
type: [CreateSubspaceModelDto],
|
||||
required: false,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => UpdateSubspaceModelDto)
|
||||
update?: UpdateSubspaceModelDto[];
|
||||
}
|
||||
|
||||
export class UpdateSpaceModelDto {
|
||||
@ApiProperty({
|
||||
description: 'Updated name of the space model',
|
||||
@ -25,5 +38,5 @@ export class UpdateSpaceModelDto {
|
||||
modelName?: string;
|
||||
|
||||
@IsOptional()
|
||||
subspaceModels?: UpdateSubspaceModelDto;
|
||||
subspaceModels?: UpdateSubspacesModelDto;
|
||||
}
|
||||
|
||||
30
src/space-model/dtos/update-subspace-model.dto.ts
Normal file
30
src/space-model/dtos/update-subspace-model.dto.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsNotEmpty,
|
||||
IsString,
|
||||
IsArray,
|
||||
IsOptional,
|
||||
ValidateNested,
|
||||
} from 'class-validator';
|
||||
import { CreateSpaceProductModelDto } from './create-space-product-model.dto';
|
||||
|
||||
export class UpdateSubspaceModelDto {
|
||||
@ApiProperty({
|
||||
description: 'Name of the subspace',
|
||||
example: 'Living Room',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
subspaceName?: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'List of products included in the model',
|
||||
type: [CreateSpaceProductModelDto],
|
||||
})
|
||||
@IsArray()
|
||||
@IsOptional()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => CreateSpaceProductModelDto)
|
||||
spaceProductModels?: CreateSpaceProductModelDto[];
|
||||
}
|
||||
1
src/space-model/handlers/index.ts
Normal file
1
src/space-model/handlers/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './propate-subspace-handler';
|
||||
177
src/space-model/handlers/propate-subspace-handler.ts
Normal file
177
src/space-model/handlers/propate-subspace-handler.ts
Normal file
@ -0,0 +1,177 @@
|
||||
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||
import { PropogateSubspaceCommand } from '../commands';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { SpaceEntity, SpaceRepository } from '@app/common/modules/space';
|
||||
import {
|
||||
SubspaceProductItemRepository,
|
||||
SubspaceProductRepository,
|
||||
SubspaceRepository,
|
||||
} from '@app/common/modules/space/repositories/subspace.repository';
|
||||
|
||||
@CommandHandler(PropogateSubspaceCommand)
|
||||
export class PropogateSubspaceHandler
|
||||
implements ICommandHandler<PropogateSubspaceCommand>
|
||||
{
|
||||
private readonly logger = new Logger(PropogateSubspaceHandler.name);
|
||||
|
||||
constructor(
|
||||
private readonly spaceRepository: SpaceRepository,
|
||||
private readonly subspaceRepository: SubspaceRepository,
|
||||
private readonly productRepository: SubspaceProductRepository,
|
||||
private readonly productItemRepository: SubspaceProductItemRepository,
|
||||
) {}
|
||||
|
||||
async execute(command: PropogateSubspaceCommand): Promise<void> {
|
||||
try {
|
||||
const newSubspaceModels = command.param?.new;
|
||||
|
||||
if (!newSubspaceModels || newSubspaceModels.length === 0) {
|
||||
this.logger.warn('No new subspace models provided.');
|
||||
return;
|
||||
}
|
||||
|
||||
const spaceModelUuid =
|
||||
newSubspaceModels[0]?.subspaceModel?.spaceModel?.uuid;
|
||||
|
||||
if (!spaceModelUuid) {
|
||||
this.logger.error(
|
||||
'Space model UUID is missing in the command parameters.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const spaces = await this.getSpacesByModel(spaceModelUuid);
|
||||
|
||||
if (spaces.length === 0) {
|
||||
this.logger.warn(`No spaces found for model UUID: ${spaceModelUuid}`);
|
||||
return;
|
||||
}
|
||||
|
||||
await this.processSubspaces(newSubspaceModels, spaces);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
'Error in PropogateSubspaceHandler execution',
|
||||
error.stack,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async processSubspaces(
|
||||
newSubspaceModels: any[],
|
||||
spaces: SpaceEntity[],
|
||||
) {
|
||||
for (const newSubspaceModel of newSubspaceModels) {
|
||||
for (const space of spaces) {
|
||||
try {
|
||||
const subspace = await this.createSubspace(newSubspaceModel, space);
|
||||
|
||||
if (newSubspaceModel.productModels?.length > 0) {
|
||||
await this.processProducts(
|
||||
newSubspaceModel.productModels,
|
||||
subspace,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to create subspace for space ID: ${space.uuid}`,
|
||||
error.stack,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async createSubspace(newSubspaceModel: any, space: SpaceEntity) {
|
||||
const subspace = this.subspaceRepository.create({
|
||||
subspaceName: newSubspaceModel.subspaceModel.subspaceName,
|
||||
space,
|
||||
subSpaceModel: newSubspaceModel.subspaceModel,
|
||||
});
|
||||
|
||||
const createdSubspace = await this.subspaceRepository.save(subspace);
|
||||
this.logger.log(
|
||||
`Subspace created for space ${space.uuid} with name ${createdSubspace.subspaceName}`,
|
||||
);
|
||||
return createdSubspace;
|
||||
}
|
||||
|
||||
private async processProducts(productModels: any[], subspace: any) {
|
||||
for (const productModel of productModels) {
|
||||
try {
|
||||
const subspaceProduct = await this.createSubspaceProduct(
|
||||
productModel,
|
||||
subspace,
|
||||
);
|
||||
|
||||
if (productModel.productItemModels?.length > 0) {
|
||||
await this.processProductItems(
|
||||
productModel.productItemModels,
|
||||
subspaceProduct,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to create product for subspace ID: ${subspace.id}`,
|
||||
error.stack,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async createSubspaceProduct(productModel: any, subspace: any) {
|
||||
const subspaceProduct = this.productRepository.create({
|
||||
product: productModel.productModel.product,
|
||||
subspace,
|
||||
productCount: productModel.productModel.productCount,
|
||||
model: productModel.productModel,
|
||||
});
|
||||
|
||||
const createdSubspaceProduct =
|
||||
await this.productRepository.save(subspaceProduct);
|
||||
this.logger.log(
|
||||
`Product added to subspace ${subspace.id} with count ${createdSubspaceProduct.productCount}`,
|
||||
);
|
||||
return createdSubspaceProduct;
|
||||
}
|
||||
|
||||
private async processProductItems(
|
||||
productItemModels: any[],
|
||||
subspaceProduct: any,
|
||||
) {
|
||||
for (const productItemModel of productItemModels) {
|
||||
try {
|
||||
const subspaceProductItem = this.productItemRepository.create({
|
||||
tag: productItemModel.tag,
|
||||
subspaceProduct,
|
||||
model: productItemModel,
|
||||
});
|
||||
|
||||
await this.productItemRepository.save(subspaceProductItem);
|
||||
this.logger.log(
|
||||
`Product item added to subspace product ${subspaceProduct.id} with tag ${subspaceProductItem.tag}`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to create product item for subspace product ID: ${subspaceProduct.id}`,
|
||||
error.stack,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async getSpacesByModel(uuid: string): Promise<SpaceEntity[]> {
|
||||
try {
|
||||
return await this.spaceRepository.find({
|
||||
where: {
|
||||
spaceModel: { uuid },
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to fetch spaces for model UUID: ${uuid}`,
|
||||
error.stack,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
src/space-model/interfaces/index.ts
Normal file
1
src/space-model/interfaces/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './update-subspace.interface'
|
||||
19
src/space-model/interfaces/update-subspace.interface.ts
Normal file
19
src/space-model/interfaces/update-subspace.interface.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import {
|
||||
SubspaceModelEntity,
|
||||
SubspaceProductItemModelEntity,
|
||||
SubspaceProductModelEntity,
|
||||
} from '@app/common/modules/space-model';
|
||||
|
||||
export interface AddSubspaceModelInterface {
|
||||
subspaceModel: SubspaceModelEntity;
|
||||
productModels: ProductModelInterface[];
|
||||
}
|
||||
|
||||
export interface ProductModelInterface {
|
||||
productModel: SubspaceProductModelEntity;
|
||||
productItemModels: SubspaceProductItemModelEntity[];
|
||||
}
|
||||
|
||||
export interface UpdatedSubspaceModelInterface {
|
||||
new?: AddSubspaceModelInterface[];
|
||||
}
|
||||
@ -18,6 +18,9 @@ import { SpaceModelDto } from '@app/common/modules/space-model/dtos';
|
||||
import { SpaceModelParam } from '../dtos/space-model-param';
|
||||
import { ProjectService } from 'src/project/services';
|
||||
import { ProjectEntity } from '@app/common/modules/project/entities';
|
||||
import { UpdatedSubspaceModelInterface } from '../interfaces';
|
||||
import { CommandBus } from '@nestjs/cqrs';
|
||||
import { PropogateSubspaceCommand } from '../commands';
|
||||
|
||||
@Injectable()
|
||||
export class SpaceModelService {
|
||||
@ -27,6 +30,7 @@ export class SpaceModelService {
|
||||
private readonly projectService: ProjectService,
|
||||
private readonly subSpaceModelService: SubSpaceModelService,
|
||||
private readonly spaceProductModelService: SpaceProductModelService,
|
||||
private commandBus: CommandBus,
|
||||
) {}
|
||||
|
||||
async createSpaceModel(
|
||||
@ -142,21 +146,27 @@ export class SpaceModelService {
|
||||
await queryRunner.startTransaction();
|
||||
try {
|
||||
const { modelName } = dto;
|
||||
let updatedSubspaces: UpdatedSubspaceModelInterface;
|
||||
if (modelName) spaceModel.modelName = modelName;
|
||||
|
||||
await queryRunner.manager.save(spaceModel);
|
||||
|
||||
if (dto.subspaceModels) {
|
||||
const updatedSubspaces =
|
||||
await this.subSpaceModelService.updateSubSpaceModels(
|
||||
dto.subspaceModels,
|
||||
spaceModel,
|
||||
queryRunner,
|
||||
);
|
||||
updatedSubspaces = await this.subSpaceModelService.modifySubSpaceModels(
|
||||
dto.subspaceModels,
|
||||
spaceModel,
|
||||
queryRunner,
|
||||
);
|
||||
}
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
if (updatedSubspaces) {
|
||||
await this.commandBus.execute(
|
||||
new PropogateSubspaceCommand(updatedSubspaces),
|
||||
);
|
||||
}
|
||||
|
||||
return new SuccessResponseDto({
|
||||
message: 'SpaceModel updated successfully',
|
||||
data: spaceModel,
|
||||
|
||||
@ -3,9 +3,10 @@ import {
|
||||
SubspaceModelRepository,
|
||||
} from '@app/common/modules/space-model';
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { CreateSubspaceModelDto, UpdateSubspaceModelDto } from '../../dtos';
|
||||
import { CreateSubspaceModelDto, UpdateSubspacesModelDto } from '../../dtos';
|
||||
import { QueryRunner } from 'typeorm';
|
||||
import { SubspaceProductModelService } from './subspace-product-model.service';
|
||||
import { UpdatedSubspaceModelInterface } from 'src/space-model/interfaces';
|
||||
|
||||
@Injectable()
|
||||
export class SubSpaceModelService {
|
||||
@ -91,12 +92,12 @@ export class SubSpaceModelService {
|
||||
}
|
||||
}
|
||||
|
||||
async updateSubSpaceModels(
|
||||
dto: UpdateSubspaceModelDto,
|
||||
async modifySubSpaceModels(
|
||||
dto: UpdateSubspacesModelDto,
|
||||
spaceModel: SpaceModelEntity,
|
||||
queryRunner: QueryRunner,
|
||||
) {
|
||||
const subspaces: { new?: any } = {};
|
||||
const subspaces: UpdatedSubspaceModelInterface = {};
|
||||
try {
|
||||
if (dto.add) {
|
||||
const addedSubspaces = await this.createSubSpaceModels(
|
||||
@ -105,6 +106,8 @@ export class SubSpaceModelService {
|
||||
queryRunner,
|
||||
);
|
||||
subspaces.new = addedSubspaces;
|
||||
} else if (dto.update) {
|
||||
|
||||
}
|
||||
return subspaces;
|
||||
} catch (error) {
|
||||
|
||||
@ -20,13 +20,25 @@ import {
|
||||
import { ProjectRepository } from '@app/common/modules/project/repositiories';
|
||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||
import { SubspaceProductModelService } from './services/subspace/subspace-product-model.service';
|
||||
import { PropogateSubspaceHandler } from './handlers';
|
||||
import { CqrsModule } from '@nestjs/cqrs';
|
||||
import { SpaceRepository } from '@app/common/modules/space';
|
||||
import {
|
||||
SubspaceProductItemRepository,
|
||||
SubspaceProductRepository,
|
||||
SubspaceRepository,
|
||||
} from '@app/common/modules/space/repositories/subspace.repository';
|
||||
|
||||
const CommandHandlers = [PropogateSubspaceHandler];
|
||||
|
||||
@Module({
|
||||
imports: [ConfigModule, SpaceRepositoryModule],
|
||||
imports: [ConfigModule, SpaceRepositoryModule, CqrsModule],
|
||||
controllers: [SpaceModelController],
|
||||
providers: [
|
||||
...CommandHandlers,
|
||||
SpaceModelService,
|
||||
SpaceModelRepository,
|
||||
SpaceRepository,
|
||||
ProjectRepository,
|
||||
SubSpaceModelService,
|
||||
SpaceProductModelService,
|
||||
@ -39,7 +51,10 @@ import { SubspaceProductModelService } from './services/subspace/subspace-produc
|
||||
SubspaceProductItemModelRepository,
|
||||
SubspaceProductModelService,
|
||||
SubspaceProductModelRepository,
|
||||
SubspaceRepository,
|
||||
SubspaceProductRepository,
|
||||
SubspaceProductItemRepository,
|
||||
],
|
||||
exports: [],
|
||||
exports: [CqrsModule],
|
||||
})
|
||||
export class SpaceModelModule {}
|
||||
|
||||
Reference in New Issue
Block a user