mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-26 08:14:55 +00:00
propagate subspace allocations
This commit is contained in:
@ -1,13 +1,13 @@
|
|||||||
import { ICommand } from '@nestjs/cqrs';
|
import { ICommand } from '@nestjs/cqrs';
|
||||||
import { SpaceModelEntity } from '@app/common/modules/space-model';
|
import { SpaceModelEntity } from '@app/common/modules/space-model';
|
||||||
import { ISingleSubspaceModel } from '../interfaces';
|
import { ISubspaceModelUpdates } from '../interfaces';
|
||||||
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
||||||
|
|
||||||
export class PropogateUpdateSpaceModelCommand implements ICommand {
|
export class PropogateUpdateSpaceModelCommand implements ICommand {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly param: {
|
public readonly param: {
|
||||||
spaceModel: SpaceModelEntity;
|
spaceModel: SpaceModelEntity;
|
||||||
subspaceModels: ISingleSubspaceModel[];
|
subspaceUpdates: ISubspaceModelUpdates;
|
||||||
spaces: SpaceEntity[];
|
spaces: SpaceEntity[];
|
||||||
},
|
},
|
||||||
) {}
|
) {}
|
||||||
|
|||||||
@ -1,303 +0,0 @@
|
|||||||
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
|
||||||
import { PropogateUpdateSpaceModelCommand } from '../commands';
|
|
||||||
import {
|
|
||||||
SpaceProductAllocationRepository,
|
|
||||||
SpaceRepository,
|
|
||||||
} from '@app/common/modules/space';
|
|
||||||
import {
|
|
||||||
SubspaceProductAllocationRepository,
|
|
||||||
SubspaceRepository,
|
|
||||||
} from '@app/common/modules/space/repositories/subspace.repository';
|
|
||||||
import {
|
|
||||||
SpaceModelEntity,
|
|
||||||
SubspaceModelProductAllocationRepoitory,
|
|
||||||
TagModel,
|
|
||||||
} from '@app/common/modules/space-model';
|
|
||||||
import { In, QueryRunner } from 'typeorm';
|
|
||||||
import { TagService } from 'src/space/services/tag';
|
|
||||||
import {
|
|
||||||
ISingleSubspaceModel,
|
|
||||||
UpdatedSubspaceModelPayload,
|
|
||||||
} from '../interfaces';
|
|
||||||
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
|
||||||
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
|
||||||
|
|
||||||
@CommandHandler(PropogateUpdateSpaceModelCommand)
|
|
||||||
export class PropogateUpdateSpaceModelHandler
|
|
||||||
implements ICommandHandler<PropogateUpdateSpaceModelCommand>
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
private readonly spaceRepository: SpaceRepository,
|
|
||||||
private readonly subspaceRepository: SubspaceRepository,
|
|
||||||
private readonly tagService: TagService,
|
|
||||||
private readonly subspaceModelProductRepository: SubspaceModelProductAllocationRepoitory,
|
|
||||||
private readonly subspaceProductRepository: SubspaceProductAllocationRepository,
|
|
||||||
private readonly spaceProductRepository: SpaceProductAllocationRepository,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async execute(command: PropogateUpdateSpaceModelCommand): Promise<void> {
|
|
||||||
const { subspaceModels, spaces } = command.param;
|
|
||||||
try {
|
|
||||||
if (!subspaceModels || subspaceModels.length === 0) return;
|
|
||||||
if (!spaces || spaces.length === 0) return;
|
|
||||||
|
|
||||||
for (const subspaceModel of subspaceModels) {
|
|
||||||
if (subspaceModel.action === ModifyAction.ADD) {
|
|
||||||
await this.addSubspaceModel(subspaceModel, spaces);
|
|
||||||
} else if (subspaceModel.action === ModifyAction.DELETE) {
|
|
||||||
await this.deleteSubspaceModel(subspaceModel, spaces);
|
|
||||||
} else if (subspaceModel.action === ModifyAction.UPDATE) {
|
|
||||||
await this.updateSubspaceModel(subspaceModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error processing subspaceModel updates`, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async addSubspaceModel(
|
|
||||||
subspaceModel: ISingleSubspaceModel,
|
|
||||||
spaces: SpaceEntity[],
|
|
||||||
) {
|
|
||||||
const subspaceModelAllocations =
|
|
||||||
await this.subspaceModelProductRepository.find({
|
|
||||||
where: {
|
|
||||||
subspaceModel: {
|
|
||||||
uuid: subspaceModel.subspaceModel.uuid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
relations: ['tags', 'product'],
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const space of spaces) {
|
|
||||||
const subspace = this.subspaceRepository.create({
|
|
||||||
subspaceName: subspaceModel.subspaceModel.subspaceName,
|
|
||||||
space: space,
|
|
||||||
});
|
|
||||||
|
|
||||||
subspace.subSpaceModel = subspaceModel.subspaceModel;
|
|
||||||
await this.subspaceRepository.save(subspace);
|
|
||||||
|
|
||||||
if (subspaceModelAllocations?.length > 0) {
|
|
||||||
for (const allocation of subspaceModelAllocations) {
|
|
||||||
const subspaceAllocation = this.subspaceProductRepository.create({
|
|
||||||
subspace: subspace,
|
|
||||||
product: allocation.product,
|
|
||||||
tags: allocation.tags,
|
|
||||||
inheritedFromModel: allocation,
|
|
||||||
});
|
|
||||||
await this.subspaceProductRepository.save(subspaceAllocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteSubspaceModel(
|
|
||||||
subspaceModel: ISingleSubspaceModel,
|
|
||||||
spaces: SpaceEntity[],
|
|
||||||
) {
|
|
||||||
const subspaces = await this.subspaceRepository.find({
|
|
||||||
where: {
|
|
||||||
subSpaceModel: { uuid: subspaceModel.subspaceModel.uuid },
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
relations: [
|
|
||||||
'productAllocations',
|
|
||||||
'productAllocations.product',
|
|
||||||
'productAllocations.tags',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!subspaces.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const allocationUuidsToRemove = subspaces.flatMap((subspace) =>
|
|
||||||
subspace.productAllocations.map((allocation) => allocation.uuid),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (allocationUuidsToRemove.length) {
|
|
||||||
await this.subspaceProductRepository.delete(allocationUuidsToRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.subspaceRepository.update(
|
|
||||||
{ uuid: In(subspaces.map((s) => s.uuid)) },
|
|
||||||
{ disabled: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
const relocatedAllocations = subspaceModel.relocatedAllocations || [];
|
|
||||||
|
|
||||||
if (!relocatedAllocations.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const space of spaces) {
|
|
||||||
for (const { allocation, tags = [] } of relocatedAllocations) {
|
|
||||||
const spaceAllocation = await this.spaceProductRepository.findOne({
|
|
||||||
where: {
|
|
||||||
inheritedFromModel: { uuid: allocation.uuid },
|
|
||||||
space: { uuid: space.uuid },
|
|
||||||
},
|
|
||||||
relations: ['tags'],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (spaceAllocation) {
|
|
||||||
if (tags.length) {
|
|
||||||
spaceAllocation.tags.push(...tags);
|
|
||||||
await this.spaceProductRepository.save(spaceAllocation);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const newSpaceAllocation = this.spaceProductRepository.create({
|
|
||||||
space,
|
|
||||||
inheritedFromModel: allocation,
|
|
||||||
tags: allocation.tags,
|
|
||||||
product: allocation.product,
|
|
||||||
});
|
|
||||||
await this.spaceProductRepository.save(newSpaceAllocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateSubspaceModel(subspaceModel: ISingleSubspaceModel) {
|
|
||||||
return this.subspaceRepository.update(
|
|
||||||
{
|
|
||||||
subSpaceModel: { uuid: subspaceModel.subspaceModel.uuid },
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{ subspaceName: subspaceModel.subspaceModel.subspaceName },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
async updateSubspaceModels(
|
|
||||||
subspaceModels: UpdatedSubspaceModelPayload[],
|
|
||||||
queryRunner: QueryRunner,
|
|
||||||
): Promise<void> {
|
|
||||||
const subspaceUpdatePromises = subspaceModels.map(async (model) => {
|
|
||||||
const {
|
|
||||||
updated: tagsToUpdate,
|
|
||||||
deleted: tagsToDelete,
|
|
||||||
added: tagsToAdd,
|
|
||||||
} = model.modifiedTags;
|
|
||||||
|
|
||||||
// Perform tag operations concurrently
|
|
||||||
await Promise.all([
|
|
||||||
tagsToUpdate?.length && this.updateTags(tagsToUpdate, queryRunner),
|
|
||||||
tagsToDelete?.length && this.deleteTags(tagsToDelete, queryRunner),
|
|
||||||
tagsToAdd?.length &&
|
|
||||||
this.createTags(
|
|
||||||
tagsToAdd,
|
|
||||||
queryRunner,
|
|
||||||
model.subspaceModelUuid,
|
|
||||||
null,
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Update subspace names
|
|
||||||
const subspaces = await queryRunner.manager.find(
|
|
||||||
this.subspaceRepository.target,
|
|
||||||
{
|
|
||||||
where: {
|
|
||||||
subSpaceModel: {
|
|
||||||
uuid: model.subspaceModelUuid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (subspaces.length > 0) {
|
|
||||||
const updateSubspacePromises = subspaces.map((subspace) =>
|
|
||||||
queryRunner.manager.update(
|
|
||||||
this.subspaceRepository.target,
|
|
||||||
{ uuid: subspace.uuid },
|
|
||||||
{ subspaceName: model.subspaceName },
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await Promise.all(updateSubspacePromises);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait for all subspace model updates to complete
|
|
||||||
await Promise.all(subspaceUpdatePromises);
|
|
||||||
}
|
|
||||||
async updateTags(models: TagModel[], queryRunner: QueryRunner) {
|
|
||||||
if (!models?.length) return;
|
|
||||||
|
|
||||||
const updatePromises = models.map((model) =>
|
|
||||||
this.tagService.updateTagsFromModel(model, queryRunner),
|
|
||||||
);
|
|
||||||
await Promise.all(updatePromises);
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteTags(uuids: string[], queryRunner: QueryRunner) {
|
|
||||||
const deletePromises = uuids.map((uuid) =>
|
|
||||||
this.tagService.deleteTagFromModel(uuid, queryRunner),
|
|
||||||
);
|
|
||||||
await Promise.all(deletePromises);
|
|
||||||
}
|
|
||||||
|
|
||||||
async createTags(
|
|
||||||
models: TagModel[],
|
|
||||||
queryRunner: QueryRunner,
|
|
||||||
subspaceModelUuid?: string,
|
|
||||||
spaceModel?: SpaceModelEntity,
|
|
||||||
): Promise<void> {
|
|
||||||
if (!models.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subspaceModelUuid) {
|
|
||||||
await this.processSubspaces(subspaceModelUuid, models, queryRunner);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spaceModel) {
|
|
||||||
await this.processSpaces(spaceModel.uuid, models, queryRunner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async processSubspaces(
|
|
||||||
subspaceModelUuid: string,
|
|
||||||
models: TagModel[],
|
|
||||||
queryRunner: QueryRunner,
|
|
||||||
): Promise<void> {
|
|
||||||
const subspaces = await this.subspaceRepository.find({
|
|
||||||
where: {
|
|
||||||
subSpaceModel: {
|
|
||||||
uuid: subspaceModelUuid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (subspaces.length > 0) {
|
|
||||||
const subspacePromises = subspaces.map((subspace) =>
|
|
||||||
this.tagService.createTagsFromModel(
|
|
||||||
queryRunner,
|
|
||||||
models,
|
|
||||||
null,
|
|
||||||
subspace,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await Promise.all(subspacePromises);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async processSpaces(
|
|
||||||
spaceModelUuid: string,
|
|
||||||
models: TagModel[],
|
|
||||||
queryRunner: QueryRunner,
|
|
||||||
): Promise<void> {
|
|
||||||
const spaces = await this.spaceRepository.find({
|
|
||||||
where: {
|
|
||||||
spaceModel: {
|
|
||||||
uuid: spaceModelUuid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (spaces.length > 0) {
|
|
||||||
const spacePromises = spaces.map((space) =>
|
|
||||||
this.tagService.createTagsFromModel(queryRunner, models, space, null),
|
|
||||||
);
|
|
||||||
await Promise.all(spacePromises);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
292
src/space-model/handlers/propogate-subspace-handler.ts
Normal file
292
src/space-model/handlers/propogate-subspace-handler.ts
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||||
|
import { PropogateUpdateSpaceModelCommand } from '../commands';
|
||||||
|
import {
|
||||||
|
SpaceProductAllocationRepository,
|
||||||
|
SpaceRepository,
|
||||||
|
} from '@app/common/modules/space';
|
||||||
|
import {
|
||||||
|
SubspaceProductAllocationRepository,
|
||||||
|
SubspaceRepository,
|
||||||
|
} from '@app/common/modules/space/repositories/subspace.repository';
|
||||||
|
import { SubspaceModelProductAllocationRepoitory } from '@app/common/modules/space-model';
|
||||||
|
import { In } from 'typeorm';
|
||||||
|
import { TagService } from 'src/space/services/tag';
|
||||||
|
import { ISingleSubspaceModel } from '../interfaces';
|
||||||
|
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
||||||
|
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
||||||
|
import { IUpdatedAllocations } from '../interfaces/subspace-product-allocation-update-result.interface';
|
||||||
|
|
||||||
|
@CommandHandler(PropogateUpdateSpaceModelCommand)
|
||||||
|
export class PropogateUpdateSpaceModelHandler
|
||||||
|
implements ICommandHandler<PropogateUpdateSpaceModelCommand>
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private readonly spaceRepository: SpaceRepository,
|
||||||
|
private readonly subspaceRepository: SubspaceRepository,
|
||||||
|
private readonly tagService: TagService,
|
||||||
|
private readonly subspaceModelProductRepository: SubspaceModelProductAllocationRepoitory,
|
||||||
|
private readonly subspaceProductRepository: SubspaceProductAllocationRepository,
|
||||||
|
private readonly spaceProductRepository: SpaceProductAllocationRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async execute(command: PropogateUpdateSpaceModelCommand): Promise<void> {
|
||||||
|
const { subspaceUpdates, spaces } = command.param;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!subspaceUpdates?.subspaceModels?.length) return; // Exit if no updates
|
||||||
|
if (!spaces?.length) return; // Exit if no spaces
|
||||||
|
|
||||||
|
const subspaceModels = subspaceUpdates.subspaceModels;
|
||||||
|
|
||||||
|
// 🔹 Filter subspace models by action
|
||||||
|
const subspacesToAdd = subspaceModels.filter(
|
||||||
|
(m) => m.action === ModifyAction.ADD,
|
||||||
|
);
|
||||||
|
const subspacesToUpdate = subspaceModels.filter(
|
||||||
|
(m) => m.action === ModifyAction.UPDATE,
|
||||||
|
);
|
||||||
|
const subspacesToDelete = subspaceModels.filter(
|
||||||
|
(m) => m.action === ModifyAction.DELETE,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 1️⃣ Create Subspace Models First (if any)
|
||||||
|
await Promise.all(
|
||||||
|
subspacesToAdd.map((m) => this.addSubspaceModel(m, spaces)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2️⃣ Update Allocations
|
||||||
|
await this.updateAllocations(subspaceUpdates.updatedAllocations);
|
||||||
|
|
||||||
|
// 3️⃣ Update Existing Subspace Models (if any)
|
||||||
|
await Promise.all(
|
||||||
|
subspacesToUpdate.map((m) => this.updateSubspaceModel(m)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 4️⃣ Delete Subspace Models (if any)
|
||||||
|
await Promise.all(
|
||||||
|
subspacesToDelete.map((m) => this.deleteSubspaceModel(m, spaces)),
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('Successfully executed PropogateUpdateSpaceModelCommand');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error processing subspace model updates', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateAllocations(allocations: IUpdatedAllocations[]) {
|
||||||
|
try {
|
||||||
|
for (const allocation of allocations) {
|
||||||
|
if (!allocation) continue;
|
||||||
|
|
||||||
|
if (allocation.allocation) {
|
||||||
|
try {
|
||||||
|
const subspaceAllocations =
|
||||||
|
await this.subspaceProductRepository.find({
|
||||||
|
where: {
|
||||||
|
inheritedFromModel: { uuid: allocation.allocation.uuid },
|
||||||
|
},
|
||||||
|
relations: ['tags'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!subspaceAllocations || subspaceAllocations.length === 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (allocation.tagsAdded?.length) {
|
||||||
|
for (const subspaceAllocation of subspaceAllocations) {
|
||||||
|
subspaceAllocation.tags.push(...allocation.tagsAdded);
|
||||||
|
}
|
||||||
|
await this.subspaceProductRepository.save(subspaceAllocations);
|
||||||
|
console.log(
|
||||||
|
`Added tags to ${subspaceAllocations.length} subspace allocations.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocation.tagsRemoved?.length) {
|
||||||
|
const tagsToRemoveUUIDs = allocation.tagsRemoved.map(
|
||||||
|
(tag) => tag.uuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const subspaceAllocation of subspaceAllocations) {
|
||||||
|
subspaceAllocation.tags = subspaceAllocation.tags.filter(
|
||||||
|
(tag) => !tagsToRemoveUUIDs.includes(tag.uuid),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await this.subspaceProductRepository.save(subspaceAllocations);
|
||||||
|
console.log(
|
||||||
|
`Removed tags from ${subspaceAllocations.length} subspace allocations.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error processing allocation update:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocation.newAllocation) {
|
||||||
|
try {
|
||||||
|
const subspaceModel = allocation.newAllocation.subspaceModel;
|
||||||
|
const subspaces = await this.subspaceRepository.find({
|
||||||
|
where: { subSpaceModel: { uuid: subspaceModel.uuid } },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!subspaces || subspaces.length === 0) continue;
|
||||||
|
|
||||||
|
const newAllocations = subspaces.map((subspace) =>
|
||||||
|
this.subspaceProductRepository.create({
|
||||||
|
product: allocation.newAllocation.product,
|
||||||
|
tags: allocation.newAllocation.tags,
|
||||||
|
subspace,
|
||||||
|
inheritedFromModel: allocation.newAllocation,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.subspaceProductRepository.save(newAllocations);
|
||||||
|
console.log(
|
||||||
|
`Created ${newAllocations.length} new subspace allocations.`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating new subspace allocation:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocation.deletedAllocation) {
|
||||||
|
try {
|
||||||
|
const subspaceAllocations =
|
||||||
|
await this.subspaceProductRepository.find({
|
||||||
|
where: {
|
||||||
|
inheritedFromModel: {
|
||||||
|
uuid: allocation.deletedAllocation.uuid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!subspaceAllocations || subspaceAllocations.length === 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
await this.subspaceProductRepository.remove(subspaceAllocations);
|
||||||
|
console.log(
|
||||||
|
`Deleted ${subspaceAllocations.length} subspace allocations.`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error deleting subspace allocation:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error in updateAllocations method:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async addSubspaceModel(
|
||||||
|
subspaceModel: ISingleSubspaceModel,
|
||||||
|
spaces: SpaceEntity[],
|
||||||
|
) {
|
||||||
|
const subspaceModelAllocations =
|
||||||
|
await this.subspaceModelProductRepository.find({
|
||||||
|
where: {
|
||||||
|
subspaceModel: {
|
||||||
|
uuid: subspaceModel.subspaceModel.uuid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
relations: ['tags', 'product'],
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const space of spaces) {
|
||||||
|
const subspace = this.subspaceRepository.create({
|
||||||
|
subspaceName: subspaceModel.subspaceModel.subspaceName,
|
||||||
|
space: space,
|
||||||
|
});
|
||||||
|
|
||||||
|
subspace.subSpaceModel = subspaceModel.subspaceModel;
|
||||||
|
await this.subspaceRepository.save(subspace);
|
||||||
|
|
||||||
|
if (subspaceModelAllocations?.length > 0) {
|
||||||
|
for (const allocation of subspaceModelAllocations) {
|
||||||
|
const subspaceAllocation = this.subspaceProductRepository.create({
|
||||||
|
subspace: subspace,
|
||||||
|
product: allocation.product,
|
||||||
|
tags: allocation.tags,
|
||||||
|
inheritedFromModel: allocation,
|
||||||
|
});
|
||||||
|
await this.subspaceProductRepository.save(subspaceAllocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteSubspaceModel(
|
||||||
|
subspaceModel: ISingleSubspaceModel,
|
||||||
|
spaces: SpaceEntity[],
|
||||||
|
) {
|
||||||
|
const subspaces = await this.subspaceRepository.find({
|
||||||
|
where: {
|
||||||
|
subSpaceModel: { uuid: subspaceModel.subspaceModel.uuid },
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
relations: [
|
||||||
|
'productAllocations',
|
||||||
|
'productAllocations.product',
|
||||||
|
'productAllocations.tags',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!subspaces.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const allocationUuidsToRemove = subspaces.flatMap((subspace) =>
|
||||||
|
subspace.productAllocations.map((allocation) => allocation.uuid),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (allocationUuidsToRemove.length) {
|
||||||
|
await this.subspaceProductRepository.delete(allocationUuidsToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.subspaceRepository.update(
|
||||||
|
{ uuid: In(subspaces.map((s) => s.uuid)) },
|
||||||
|
{ disabled: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const relocatedAllocations = subspaceModel.relocatedAllocations || [];
|
||||||
|
|
||||||
|
if (!relocatedAllocations.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const space of spaces) {
|
||||||
|
for (const { allocation, tags = [] } of relocatedAllocations) {
|
||||||
|
const spaceAllocation = await this.spaceProductRepository.findOne({
|
||||||
|
where: {
|
||||||
|
inheritedFromModel: { uuid: allocation.uuid },
|
||||||
|
space: { uuid: space.uuid },
|
||||||
|
},
|
||||||
|
relations: ['tags'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (spaceAllocation) {
|
||||||
|
if (tags.length) {
|
||||||
|
spaceAllocation.tags.push(...tags);
|
||||||
|
await this.spaceProductRepository.save(spaceAllocation);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const newSpaceAllocation = this.spaceProductRepository.create({
|
||||||
|
space,
|
||||||
|
inheritedFromModel: allocation,
|
||||||
|
tags: allocation.tags,
|
||||||
|
product: allocation.product,
|
||||||
|
});
|
||||||
|
await this.spaceProductRepository.save(newSpaceAllocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateSubspaceModel(subspaceModel: ISingleSubspaceModel) {
|
||||||
|
return this.subspaceRepository.update(
|
||||||
|
{
|
||||||
|
subSpaceModel: { uuid: subspaceModel.subspaceModel.uuid },
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{ subspaceName: subspaceModel.subspaceModel.subspaceName },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import {
|
|||||||
import { ModifyTagModelDto } from '../dtos';
|
import { ModifyTagModelDto } from '../dtos';
|
||||||
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
import { ModifyAction } from '@app/common/constants/modify-action.enum';
|
||||||
import { NewTagEntity } from '@app/common/modules/tag';
|
import { NewTagEntity } from '@app/common/modules/tag';
|
||||||
|
import { IUpdatedAllocations } from './subspace-product-allocation-update-result.interface';
|
||||||
|
|
||||||
export interface IRelocatedAllocation {
|
export interface IRelocatedAllocation {
|
||||||
allocation: SpaceModelProductAllocationEntity;
|
allocation: SpaceModelProductAllocationEntity;
|
||||||
@ -16,3 +17,8 @@ export interface ISingleSubspaceModel {
|
|||||||
tags?: ModifyTagModelDto[];
|
tags?: ModifyTagModelDto[];
|
||||||
relocatedAllocations?: IRelocatedAllocation[];
|
relocatedAllocations?: IRelocatedAllocation[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISubspaceModelUpdates {
|
||||||
|
subspaceModels: ISingleSubspaceModel[];
|
||||||
|
updatedAllocations: IUpdatedAllocations[];
|
||||||
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ import { SpaceProductAllocationEntity } from '@app/common/modules/space/entities
|
|||||||
import { SubspaceEntity } from '@app/common/modules/space/entities/subspace/subspace.entity';
|
import { SubspaceEntity } from '@app/common/modules/space/entities/subspace/subspace.entity';
|
||||||
import { SubspaceProductAllocationEntity } from '@app/common/modules/space/entities/subspace/subspace-product-allocation.entity';
|
import { SubspaceProductAllocationEntity } from '@app/common/modules/space/entities/subspace/subspace-product-allocation.entity';
|
||||||
import { DeviceEntity } from '@app/common/modules/device/entities';
|
import { DeviceEntity } from '@app/common/modules/device/entities';
|
||||||
import { ISingleSubspaceModel } from '../interfaces';
|
import { ISingleSubspaceModel, ISubspaceModelUpdates } from '../interfaces';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpaceModelService {
|
export class SpaceModelService {
|
||||||
@ -199,7 +199,7 @@ export class SpaceModelService {
|
|||||||
param.projectUuid,
|
param.projectUuid,
|
||||||
);
|
);
|
||||||
await queryRunner.connect();
|
await queryRunner.connect();
|
||||||
let modifiedSubspaces: ISingleSubspaceModel[] = [];
|
let modifiedSubspaces: ISubspaceModelUpdates;
|
||||||
try {
|
try {
|
||||||
await queryRunner.startTransaction();
|
await queryRunner.startTransaction();
|
||||||
const spaces = await this.fetchModelSpaces(spaceModel);
|
const spaces = await this.fetchModelSpaces(spaceModel);
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { SubspaceModelProductAllocationService } from './subspace-model-product-
|
|||||||
import {
|
import {
|
||||||
IRelocatedAllocation,
|
IRelocatedAllocation,
|
||||||
ISingleSubspaceModel,
|
ISingleSubspaceModel,
|
||||||
|
ISubspaceModelUpdates,
|
||||||
} from 'src/space-model/interfaces';
|
} from 'src/space-model/interfaces';
|
||||||
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
|
||||||
import { SubSpaceService } from 'src/space/services/subspace';
|
import { SubSpaceService } from 'src/space/services/subspace';
|
||||||
@ -118,7 +119,7 @@ export class SubSpaceModelService {
|
|||||||
projectUuid: string,
|
projectUuid: string,
|
||||||
spaceTagUpdateDtos?: ModifyTagModelDto[],
|
spaceTagUpdateDtos?: ModifyTagModelDto[],
|
||||||
spaces?: SpaceEntity[],
|
spaces?: SpaceEntity[],
|
||||||
): Promise<ISingleSubspaceModel[]> {
|
): Promise<ISubspaceModelUpdates> {
|
||||||
try {
|
try {
|
||||||
if (!dtos || dtos.length === 0) {
|
if (!dtos || dtos.length === 0) {
|
||||||
return;
|
return;
|
||||||
@ -160,13 +161,16 @@ export class SubSpaceModelService {
|
|||||||
spaceModel,
|
spaceModel,
|
||||||
spaceTagUpdateDtos,
|
spaceTagUpdateDtos,
|
||||||
);
|
);
|
||||||
return [
|
return {
|
||||||
|
subspaceModels: [
|
||||||
createdSubspaces ?? [],
|
createdSubspaces ?? [],
|
||||||
updatedSubspaces ?? [],
|
updatedSubspaces ?? [],
|
||||||
deletedSubspaces ?? [],
|
deletedSubspaces ?? [],
|
||||||
]
|
]
|
||||||
.filter((arr) => arr.length > 0)
|
.filter((arr) => arr.length > 0)
|
||||||
.flat();
|
.flat(),
|
||||||
|
updatedAllocations: updatedAllocations,
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in modifySubspaceModels:', error);
|
console.error('Error in modifySubspaceModels:', error);
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
|
|||||||
Reference in New Issue
Block a user