propagate add

This commit is contained in:
hannathkadher
2024-12-19 09:12:26 +04:00
parent 23d3cd620c
commit a771fa8ee5
12 changed files with 291 additions and 14 deletions

View File

@ -0,0 +1 @@
export * from './propogate-subspace-update-command';

View File

@ -0,0 +1,6 @@
import { ICommand } from '@nestjs/cqrs';
import { UpdatedSubspaceModelInterface } from '../interfaces';
export class PropogateSubspaceCommand implements ICommand {
constructor(public readonly param: UpdatedSubspaceModelInterface) {}
}

View File

@ -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';

View File

@ -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;
}

View 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[];
}

View File

@ -0,0 +1 @@
export * from './propate-subspace-handler';

View 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;
}
}
}

View File

@ -0,0 +1 @@
export * from './update-subspace.interface'

View 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[];
}

View File

@ -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,

View File

@ -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) {

View File

@ -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 {}