mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-27 08:24:55 +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 './project-param.dto';
|
||||||
export * from './update-space-model.dto';
|
export * from './update-space-model.dto';
|
||||||
export * from './space-model-param';
|
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 { IsArray, IsOptional, IsString, ValidateNested } from 'class-validator';
|
||||||
import { CreateSubspaceModelDto } from './create-subspace-model.dto';
|
import { CreateSubspaceModelDto } from './create-subspace-model.dto';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
|
import { UpdateSubspaceModelDto } from './update-subspace-model.dto';
|
||||||
|
|
||||||
export class UpdateSubspaceModelDto {
|
export class UpdateSubspacesModelDto {
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'List of subspaces to add',
|
description: 'List of subspaces to add',
|
||||||
type: [CreateSubspaceModelDto],
|
type: [CreateSubspaceModelDto],
|
||||||
@ -14,7 +15,19 @@ export class UpdateSubspaceModelDto {
|
|||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => CreateSubspaceModelDto)
|
@Type(() => CreateSubspaceModelDto)
|
||||||
add?: 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 {
|
export class UpdateSpaceModelDto {
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'Updated name of the space model',
|
description: 'Updated name of the space model',
|
||||||
@ -25,5 +38,5 @@ export class UpdateSpaceModelDto {
|
|||||||
modelName?: string;
|
modelName?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@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 { SpaceModelParam } from '../dtos/space-model-param';
|
||||||
import { ProjectService } from 'src/project/services';
|
import { ProjectService } from 'src/project/services';
|
||||||
import { ProjectEntity } from '@app/common/modules/project/entities';
|
import { ProjectEntity } from '@app/common/modules/project/entities';
|
||||||
|
import { UpdatedSubspaceModelInterface } from '../interfaces';
|
||||||
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
import { PropogateSubspaceCommand } from '../commands';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpaceModelService {
|
export class SpaceModelService {
|
||||||
@ -27,6 +30,7 @@ export class SpaceModelService {
|
|||||||
private readonly projectService: ProjectService,
|
private readonly projectService: ProjectService,
|
||||||
private readonly subSpaceModelService: SubSpaceModelService,
|
private readonly subSpaceModelService: SubSpaceModelService,
|
||||||
private readonly spaceProductModelService: SpaceProductModelService,
|
private readonly spaceProductModelService: SpaceProductModelService,
|
||||||
|
private commandBus: CommandBus,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createSpaceModel(
|
async createSpaceModel(
|
||||||
@ -142,21 +146,27 @@ export class SpaceModelService {
|
|||||||
await queryRunner.startTransaction();
|
await queryRunner.startTransaction();
|
||||||
try {
|
try {
|
||||||
const { modelName } = dto;
|
const { modelName } = dto;
|
||||||
|
let updatedSubspaces: UpdatedSubspaceModelInterface;
|
||||||
if (modelName) spaceModel.modelName = modelName;
|
if (modelName) spaceModel.modelName = modelName;
|
||||||
|
|
||||||
await queryRunner.manager.save(spaceModel);
|
await queryRunner.manager.save(spaceModel);
|
||||||
|
|
||||||
if (dto.subspaceModels) {
|
if (dto.subspaceModels) {
|
||||||
const updatedSubspaces =
|
updatedSubspaces = await this.subSpaceModelService.modifySubSpaceModels(
|
||||||
await this.subSpaceModelService.updateSubSpaceModels(
|
dto.subspaceModels,
|
||||||
dto.subspaceModels,
|
spaceModel,
|
||||||
spaceModel,
|
queryRunner,
|
||||||
queryRunner,
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await queryRunner.commitTransaction();
|
await queryRunner.commitTransaction();
|
||||||
|
|
||||||
|
if (updatedSubspaces) {
|
||||||
|
await this.commandBus.execute(
|
||||||
|
new PropogateSubspaceCommand(updatedSubspaces),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return new SuccessResponseDto({
|
return new SuccessResponseDto({
|
||||||
message: 'SpaceModel updated successfully',
|
message: 'SpaceModel updated successfully',
|
||||||
data: spaceModel,
|
data: spaceModel,
|
||||||
|
|||||||
@ -3,9 +3,10 @@ import {
|
|||||||
SubspaceModelRepository,
|
SubspaceModelRepository,
|
||||||
} from '@app/common/modules/space-model';
|
} from '@app/common/modules/space-model';
|
||||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import { CreateSubspaceModelDto, UpdateSubspaceModelDto } from '../../dtos';
|
import { CreateSubspaceModelDto, UpdateSubspacesModelDto } from '../../dtos';
|
||||||
import { QueryRunner } from 'typeorm';
|
import { QueryRunner } from 'typeorm';
|
||||||
import { SubspaceProductModelService } from './subspace-product-model.service';
|
import { SubspaceProductModelService } from './subspace-product-model.service';
|
||||||
|
import { UpdatedSubspaceModelInterface } from 'src/space-model/interfaces';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SubSpaceModelService {
|
export class SubSpaceModelService {
|
||||||
@ -91,12 +92,12 @@ export class SubSpaceModelService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateSubSpaceModels(
|
async modifySubSpaceModels(
|
||||||
dto: UpdateSubspaceModelDto,
|
dto: UpdateSubspacesModelDto,
|
||||||
spaceModel: SpaceModelEntity,
|
spaceModel: SpaceModelEntity,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
) {
|
) {
|
||||||
const subspaces: { new?: any } = {};
|
const subspaces: UpdatedSubspaceModelInterface = {};
|
||||||
try {
|
try {
|
||||||
if (dto.add) {
|
if (dto.add) {
|
||||||
const addedSubspaces = await this.createSubSpaceModels(
|
const addedSubspaces = await this.createSubSpaceModels(
|
||||||
@ -105,6 +106,8 @@ export class SubSpaceModelService {
|
|||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
subspaces.new = addedSubspaces;
|
subspaces.new = addedSubspaces;
|
||||||
|
} else if (dto.update) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return subspaces;
|
return subspaces;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -20,13 +20,25 @@ import {
|
|||||||
import { ProjectRepository } from '@app/common/modules/project/repositiories';
|
import { ProjectRepository } from '@app/common/modules/project/repositiories';
|
||||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||||
import { SubspaceProductModelService } from './services/subspace/subspace-product-model.service';
|
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({
|
@Module({
|
||||||
imports: [ConfigModule, SpaceRepositoryModule],
|
imports: [ConfigModule, SpaceRepositoryModule, CqrsModule],
|
||||||
controllers: [SpaceModelController],
|
controllers: [SpaceModelController],
|
||||||
providers: [
|
providers: [
|
||||||
|
...CommandHandlers,
|
||||||
SpaceModelService,
|
SpaceModelService,
|
||||||
SpaceModelRepository,
|
SpaceModelRepository,
|
||||||
|
SpaceRepository,
|
||||||
ProjectRepository,
|
ProjectRepository,
|
||||||
SubSpaceModelService,
|
SubSpaceModelService,
|
||||||
SpaceProductModelService,
|
SpaceProductModelService,
|
||||||
@ -39,7 +51,10 @@ import { SubspaceProductModelService } from './services/subspace/subspace-produc
|
|||||||
SubspaceProductItemModelRepository,
|
SubspaceProductItemModelRepository,
|
||||||
SubspaceProductModelService,
|
SubspaceProductModelService,
|
||||||
SubspaceProductModelRepository,
|
SubspaceProductModelRepository,
|
||||||
|
SubspaceRepository,
|
||||||
|
SubspaceProductRepository,
|
||||||
|
SubspaceProductItemRepository,
|
||||||
],
|
],
|
||||||
exports: [],
|
exports: [CqrsModule],
|
||||||
})
|
})
|
||||||
export class SpaceModelModule {}
|
export class SpaceModelModule {}
|
||||||
|
|||||||
Reference in New Issue
Block a user