mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-15 18:27:05 +00:00
fix commissioning
This commit is contained in:
@ -3,6 +3,7 @@ import { RoleType } from './role.type.enum';
|
|||||||
export const RolePermissions = {
|
export const RolePermissions = {
|
||||||
[RoleType.SUPER_ADMIN]: [
|
[RoleType.SUPER_ADMIN]: [
|
||||||
'DEVICE_SINGLE_CONTROL',
|
'DEVICE_SINGLE_CONTROL',
|
||||||
|
'COMMISSION_DEVICE',
|
||||||
'DEVICE_VIEW',
|
'DEVICE_VIEW',
|
||||||
'DEVICE_DELETE',
|
'DEVICE_DELETE',
|
||||||
'DEVICE_UPDATE',
|
'DEVICE_UPDATE',
|
||||||
@ -58,6 +59,7 @@ export const RolePermissions = {
|
|||||||
'PRODUCT_ADD',
|
'PRODUCT_ADD',
|
||||||
],
|
],
|
||||||
[RoleType.ADMIN]: [
|
[RoleType.ADMIN]: [
|
||||||
|
'COMMISSION_DEVICE',
|
||||||
'DEVICE_SINGLE_CONTROL',
|
'DEVICE_SINGLE_CONTROL',
|
||||||
'DEVICE_VIEW',
|
'DEVICE_VIEW',
|
||||||
'DEVICE_DELETE',
|
'DEVICE_DELETE',
|
||||||
@ -127,6 +129,7 @@ export const RolePermissions = {
|
|||||||
'SCENES_CONTROL',
|
'SCENES_CONTROL',
|
||||||
],
|
],
|
||||||
[RoleType.SPACE_OWNER]: [
|
[RoleType.SPACE_OWNER]: [
|
||||||
|
'COMMISSION_DEVICE',
|
||||||
'DEVICE_SINGLE_CONTROL',
|
'DEVICE_SINGLE_CONTROL',
|
||||||
'DEVICE_VIEW',
|
'DEVICE_VIEW',
|
||||||
'DEVICE_DELETE',
|
'DEVICE_DELETE',
|
||||||
|
@ -75,7 +75,7 @@ export class DeviceEntity extends AbstractEntity<DeviceDto> {
|
|||||||
|
|
||||||
@OneToMany(() => NewTagEntity, (tag) => tag.devices)
|
@OneToMany(() => NewTagEntity, (tag) => tag.devices)
|
||||||
// @JoinTable({ name: 'device_tags' })
|
// @JoinTable({ name: 'device_tags' })
|
||||||
public tag: NewTagEntity[];
|
public tag: NewTagEntity;
|
||||||
|
|
||||||
constructor(partial: Partial<DeviceEntity>) {
|
constructor(partial: Partial<DeviceEntity>) {
|
||||||
super();
|
super();
|
||||||
|
@ -3,7 +3,6 @@ import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
|||||||
import { ProductEntity } from '../../product/entities';
|
import { ProductEntity } from '../../product/entities';
|
||||||
import { TagDto } from '../dtos';
|
import { TagDto } from '../dtos';
|
||||||
import { TagModel } from '../../space-model/entities/tag-model.entity';
|
import { TagModel } from '../../space-model/entities/tag-model.entity';
|
||||||
import { SpaceEntity } from './space.entity';
|
|
||||||
import { DeviceEntity } from '../../device/entities';
|
import { DeviceEntity } from '../../device/entities';
|
||||||
import { SubspaceEntity } from './subspace/subspace.entity';
|
import { SubspaceEntity } from './subspace/subspace.entity';
|
||||||
|
|
||||||
@ -22,9 +21,6 @@ export class TagEntity extends AbstractEntity<TagDto> {
|
|||||||
})
|
})
|
||||||
product: ProductEntity;
|
product: ProductEntity;
|
||||||
|
|
||||||
@ManyToOne(() => SpaceEntity, (space) => space.tags, { nullable: true })
|
|
||||||
space: SpaceEntity;
|
|
||||||
|
|
||||||
@ManyToOne(() => SubspaceEntity, (subspace) => subspace.tags, {
|
@ManyToOne(() => SubspaceEntity, (subspace) => subspace.tags, {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
|
@ -19,6 +19,8 @@ import {
|
|||||||
SceneRepository,
|
SceneRepository,
|
||||||
} from '@app/common/modules/scene/repositories';
|
} from '@app/common/modules/scene/repositories';
|
||||||
import { AutomationRepository } from '@app/common/modules/automation/repositories';
|
import { AutomationRepository } from '@app/common/modules/automation/repositories';
|
||||||
|
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
||||||
|
import { SubspaceRepository } from '@app/common/modules/space/repositories/subspace.repository';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ConfigModule, SpaceRepositoryModule],
|
imports: [ConfigModule, SpaceRepositoryModule],
|
||||||
@ -39,6 +41,8 @@ import { AutomationRepository } from '@app/common/modules/automation/repositorie
|
|||||||
SceneIconRepository,
|
SceneIconRepository,
|
||||||
SceneRepository,
|
SceneRepository,
|
||||||
AutomationRepository,
|
AutomationRepository,
|
||||||
|
CommunityRepository,
|
||||||
|
SubspaceRepository,
|
||||||
],
|
],
|
||||||
exports: [],
|
exports: [],
|
||||||
})
|
})
|
||||||
|
@ -22,9 +22,10 @@ import { ControllerRoute } from '@app/common/constants/controller-route';
|
|||||||
import { EnableDisableStatusEnum } from '@app/common/constants/days.enum';
|
import { EnableDisableStatusEnum } from '@app/common/constants/days.enum';
|
||||||
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||||
import { CommissionDeviceCsvDto } from '../dto';
|
import { CommissionDeviceCsvDto } from '../dto';
|
||||||
import { CommunityParam } from '@app/common/dto/community-space.param';
|
|
||||||
import { DeviceCommissionService } from '../services';
|
import { DeviceCommissionService } from '../services';
|
||||||
import { ProjectParam } from '@app/common/dto/project-param.dto';
|
import { ProjectParam } from '@app/common/dto/project-param.dto';
|
||||||
|
import { Permissions } from 'src/decorators/permissions.decorator';
|
||||||
|
import { PermissionsGuard } from 'src/guards/permissions.guard';
|
||||||
|
|
||||||
@ApiTags('Commission Devices Module')
|
@ApiTags('Commission Devices Module')
|
||||||
@Controller({
|
@Controller({
|
||||||
@ -34,6 +35,8 @@ import { ProjectParam } from '@app/common/dto/project-param.dto';
|
|||||||
export class DeviceCommissionController {
|
export class DeviceCommissionController {
|
||||||
constructor(private readonly commissionService: DeviceCommissionService) {}
|
constructor(private readonly commissionService: DeviceCommissionService) {}
|
||||||
|
|
||||||
|
@UseGuards(PermissionsGuard)
|
||||||
|
@Permissions('COMMISSION_DEVICE')
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Post()
|
@Post()
|
||||||
@ApiConsumes('multipart/form-data')
|
@ApiConsumes('multipart/form-data')
|
||||||
@ -65,7 +68,7 @@ export class DeviceCommissionController {
|
|||||||
@Param() param: ProjectParam,
|
@Param() param: ProjectParam,
|
||||||
@Req() req: any,
|
@Req() req: any,
|
||||||
): Promise<BaseResponseDto> {
|
): Promise<BaseResponseDto> {
|
||||||
await this.commissionService.processCsv(file.path);
|
await this.commissionService.processCsv(param, file.path);
|
||||||
return {
|
return {
|
||||||
message: 'CSV file received and processing started',
|
message: 'CSV file received and processing started',
|
||||||
success: true,
|
success: true,
|
||||||
|
@ -2,44 +2,185 @@ import * as fs from 'fs';
|
|||||||
import * as csv from 'csv-parser';
|
import * as csv from 'csv-parser';
|
||||||
|
|
||||||
import { TuyaService } from '@app/common/integrations/tuya/services/tuya.service';
|
import { TuyaService } from '@app/common/integrations/tuya/services/tuya.service';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import { DeviceService } from 'src/device/services';
|
import { DeviceService } from 'src/device/services';
|
||||||
|
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
||||||
|
import { SpaceRepository } from '@app/common/modules/space';
|
||||||
|
import { SubspaceRepository } from '@app/common/modules/space/repositories/subspace.repository';
|
||||||
|
import { SubspaceEntity } from '@app/common/modules/space/entities/subspace/subspace.entity';
|
||||||
|
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||||
|
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
||||||
|
import { ProjectParam } from '@app/common/dto/project-param.dto';
|
||||||
|
import { ProjectRepository } from '@app/common/modules/project/repositiories';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeviceCommissionService {
|
export class DeviceCommissionService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly tuyaService: TuyaService,
|
private readonly tuyaService: TuyaService,
|
||||||
private readonly deviceService: DeviceService,
|
private readonly deviceService: DeviceService,
|
||||||
|
private readonly communityRepository: CommunityRepository,
|
||||||
|
private readonly spaceRepository: SpaceRepository,
|
||||||
|
private readonly subspaceRepository: SubspaceRepository,
|
||||||
|
private readonly deviceRepository: DeviceRepository,
|
||||||
|
private readonly projectRepository: ProjectRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async processCsv(filePath: string): Promise<void> {
|
async processCsv(param: ProjectParam, filePath: string) {
|
||||||
return new Promise((resolve, reject) => {
|
const successCount = { value: 0 };
|
||||||
const results = [];
|
const failureCount = { value: 0 };
|
||||||
|
|
||||||
fs.createReadStream(filePath)
|
const projectId = param.projectUuid;
|
||||||
.pipe(csv())
|
|
||||||
.on('data', async (row) => {
|
|
||||||
console.log(`Device: ${JSON.stringify(row)}`);
|
|
||||||
const deviceId = row.deviceId?.trim();
|
|
||||||
|
|
||||||
if (!deviceId) {
|
const project = await this.projectRepository.findOne({
|
||||||
console.error('Missing deviceId or deviceName in row:', row);
|
where: { uuid: projectId },
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const device = await this.tuyaService.getDeviceDetails(
|
|
||||||
row.deviceId,
|
|
||||||
);
|
|
||||||
console.log(device);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on('end', () => {
|
|
||||||
console.log(`Finished processing ${results.length} devices.`);
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.on('error', (error) => {
|
|
||||||
console.error('Error reading CSV', error);
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!project) {
|
||||||
|
throw new HttpException('Project not found', HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows: any[] = [];
|
||||||
|
try {
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
fs.createReadStream(filePath)
|
||||||
|
.pipe(csv())
|
||||||
|
.on('data', (row) => rows.push(row))
|
||||||
|
.on('end', () => resolve())
|
||||||
|
.on('error', (error) => reject(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const row of rows) {
|
||||||
|
await this.processCsvRow(param, row, successCount, failureCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SuccessResponseDto({
|
||||||
|
message: `Successfully processed CSV file`,
|
||||||
|
data: {
|
||||||
|
successCount: successCount.value,
|
||||||
|
failureCount: failureCount.value,
|
||||||
|
},
|
||||||
|
statusCode: HttpStatus.ACCEPTED,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
'Failed to process CSV file',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async processCsvRow(
|
||||||
|
param: ProjectParam,
|
||||||
|
row: any,
|
||||||
|
successCount: { value: number },
|
||||||
|
failureCount: { value: number },
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const rawDeviceId = row['Device ID']?.trim();
|
||||||
|
const communityId = row['Community UUID']?.trim();
|
||||||
|
const spaceId = row['Space UUID']?.trim();
|
||||||
|
const subspaceId = row['Subspace UUID']?.trim();
|
||||||
|
const tagName = row['Tag']?.trim();
|
||||||
|
const productName = row['Product Name']?.trim();
|
||||||
|
const projectId = param.projectUuid;
|
||||||
|
|
||||||
|
if (!rawDeviceId) {
|
||||||
|
console.error('Missing Device ID in row:', row);
|
||||||
|
failureCount.value++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const device = await this.tuyaService.getDeviceDetails(rawDeviceId);
|
||||||
|
if (!device) {
|
||||||
|
console.error(`Device not found for Device ID: ${rawDeviceId}`);
|
||||||
|
failureCount.value++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const community = await this.communityRepository.findOne({
|
||||||
|
where: { uuid: communityId, project: { uuid: projectId } },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!community) {
|
||||||
|
console.error(`Community not found: ${communityId}`);
|
||||||
|
failureCount.value++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tuyaSpaceId = community.externalId;
|
||||||
|
|
||||||
|
const space = await this.spaceRepository.findOne({
|
||||||
|
where: { uuid: spaceId },
|
||||||
|
relations: [
|
||||||
|
'productAllocations',
|
||||||
|
'productAllocations.tags',
|
||||||
|
'productAllocations.product',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!space) {
|
||||||
|
console.error(`Space not found: ${spaceId}`);
|
||||||
|
failureCount.value++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let subspace: SubspaceEntity | null = null;
|
||||||
|
if (subspaceId?.trim()) {
|
||||||
|
subspace = await this.subspaceRepository.findOne({
|
||||||
|
where: { uuid: subspaceId },
|
||||||
|
relations: [
|
||||||
|
'productAllocations',
|
||||||
|
'productAllocations.tags',
|
||||||
|
'productAllocations.product',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!subspace) {
|
||||||
|
console.error(`Subspace not found: ${subspaceId}`);
|
||||||
|
failureCount.value++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const allocations =
|
||||||
|
subspace?.productAllocations || space.productAllocations;
|
||||||
|
|
||||||
|
const match = allocations
|
||||||
|
.flatMap((pa) =>
|
||||||
|
(pa.tags || []).map((tag) => ({ product: pa.product, tag })),
|
||||||
|
)
|
||||||
|
.find(({ tag }) => tag.name === tagName);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
console.error(`No matching tag found for Device ID: ${rawDeviceId}`);
|
||||||
|
failureCount.value++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match.product.name !== productName) {
|
||||||
|
console.error(`Product name mismatch for Device ID: ${rawDeviceId}`);
|
||||||
|
failureCount.value++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const middlewareDevice = this.deviceRepository.create({
|
||||||
|
deviceTuyaUuid: rawDeviceId,
|
||||||
|
isActive: true,
|
||||||
|
spaceDevice: space,
|
||||||
|
subspace: subspace || null,
|
||||||
|
productDevice: match.product,
|
||||||
|
tag: match.tag,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.deviceRepository.save(middlewareDevice);
|
||||||
|
|
||||||
|
await this.deviceService.transferDeviceInSpacesTuya(
|
||||||
|
rawDeviceId,
|
||||||
|
tuyaSpaceId,
|
||||||
|
);
|
||||||
|
successCount.value++;
|
||||||
|
} catch (err) {
|
||||||
|
failureCount.value++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
Delete,
|
Delete,
|
||||||
Get,
|
Get,
|
||||||
Header,
|
Header,
|
||||||
|
HttpStatus,
|
||||||
Param,
|
Param,
|
||||||
Post,
|
Post,
|
||||||
Put,
|
Put,
|
||||||
@ -12,6 +13,7 @@ import {
|
|||||||
Res,
|
Res,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { Response } from 'express';
|
||||||
import {
|
import {
|
||||||
ApiBearerAuth,
|
ApiBearerAuth,
|
||||||
ApiOperation,
|
ApiOperation,
|
||||||
@ -115,7 +117,13 @@ export class ProjectController {
|
|||||||
@Param() params: GetProjectParam,
|
@Param() params: GetProjectParam,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const csvStream = await this.projectService.exportToCsv(params);
|
try {
|
||||||
csvStream.pipe(res as unknown as NodeJS.WritableStream);
|
const csvStream = await this.projectService.exportToCsv(params);
|
||||||
|
csvStream.pipe(res as unknown as NodeJS.WritableStream);
|
||||||
|
} catch (error) {
|
||||||
|
res
|
||||||
|
.status(error.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
.json({ message: error.message || 'Failed to generate CSV file.' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,17 +254,16 @@ export class ProjectService {
|
|||||||
const stream = new PassThrough();
|
const stream = new PassThrough();
|
||||||
const csvStream = format({
|
const csvStream = format({
|
||||||
headers: [
|
headers: [
|
||||||
'Project Name',
|
'Device ID',
|
||||||
'Project UUID',
|
|
||||||
'Community Name',
|
'Community Name',
|
||||||
'Community UUID',
|
|
||||||
'Space Location',
|
|
||||||
'Space Name',
|
'Space Name',
|
||||||
'Space UUID',
|
'Space Location',
|
||||||
'Subspace Name',
|
'Subspace Name',
|
||||||
'Subspace UUID',
|
|
||||||
'Tag',
|
'Tag',
|
||||||
'Tag Product Name',
|
'Product Name',
|
||||||
|
'Community UUID',
|
||||||
|
'Space UUID',
|
||||||
|
'Subspace UUID',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -306,17 +305,16 @@ export class ProjectService {
|
|||||||
for (const productAllocation of subspace.productAllocations || []) {
|
for (const productAllocation of subspace.productAllocations || []) {
|
||||||
for (const tag of productAllocation.tags || []) {
|
for (const tag of productAllocation.tags || []) {
|
||||||
csvStream.write({
|
csvStream.write({
|
||||||
'Project Name': project.name,
|
'Device ID': '',
|
||||||
'Project UUID': project.uuid,
|
|
||||||
'Community Name': space.community?.name || '',
|
'Community Name': space.community?.name || '',
|
||||||
'Community UUID': space.community?.uuid || '',
|
|
||||||
'Space Location': spaceLocation,
|
|
||||||
'Space Name': space.spaceName,
|
'Space Name': space.spaceName,
|
||||||
'Space UUID': space.uuid,
|
'Space Location': spaceLocation,
|
||||||
'Subspace Name': subspace.subspaceName || '',
|
'Subspace Name': subspace.subspaceName || '',
|
||||||
'Subspace UUID': subspace.uuid,
|
|
||||||
Tag: tag.name,
|
Tag: tag.name,
|
||||||
'Tag Product Name': productAllocation.product.name || '',
|
'Product Name': productAllocation.product.name || '',
|
||||||
|
'Community UUID': space.community?.uuid || '',
|
||||||
|
'Space UUID': space.uuid,
|
||||||
|
'Subspace UUID': subspace.uuid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,17 +323,16 @@ export class ProjectService {
|
|||||||
for (const productAllocation of space.productAllocations || []) {
|
for (const productAllocation of space.productAllocations || []) {
|
||||||
for (const tag of productAllocation.tags || []) {
|
for (const tag of productAllocation.tags || []) {
|
||||||
csvStream.write({
|
csvStream.write({
|
||||||
'Project Name': project.name,
|
'Device ID': '',
|
||||||
'Project UUID': project.uuid,
|
|
||||||
'Community Name': space.community?.name || '',
|
'Community Name': space.community?.name || '',
|
||||||
'Community UUID': space.community?.uuid || '',
|
|
||||||
'Space Location': spaceLocation,
|
|
||||||
'Space Name': space.spaceName,
|
'Space Name': space.spaceName,
|
||||||
'Space UUID': space.uuid,
|
'Space Location': spaceLocation,
|
||||||
'Subspace Name': '',
|
'Subspace Name': '',
|
||||||
'Subspace UUID': '',
|
|
||||||
Tag: tag.name,
|
Tag: tag.name,
|
||||||
'Tag Product Name': productAllocation.product.name || '',
|
'Product Name': productAllocation.product.name || '',
|
||||||
|
'Community UUID': space.community?.uuid || '',
|
||||||
|
'Space UUID': space.uuid,
|
||||||
|
'Subspace UUID': '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ export class DisableSpaceHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tagUuids = space.tags?.map((tag) => tag.uuid) || [];
|
const tagUuids = space.productAllocations?.map((tag) => tag.uuid) || [];
|
||||||
/* const subspaceDtos =
|
/* const subspaceDtos =
|
||||||
space.subspaces?.map((subspace) => ({
|
space.subspaces?.map((subspace) => ({
|
||||||
subspaceUuid: subspace.uuid,
|
subspaceUuid: subspace.uuid,
|
||||||
|
@ -582,8 +582,8 @@ export class SpaceService {
|
|||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
if (space.subspaces || space.tags) {
|
if (space.subspaces || space.productAllocations) {
|
||||||
if (space.tags) {
|
if (space.productAllocations) {
|
||||||
await this.spaceProductAllocationService.unlinkModels(
|
await this.spaceProductAllocationService.unlinkModels(
|
||||||
space,
|
space,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
|
@ -118,7 +118,7 @@ export class TagService {
|
|||||||
await queryRunner.manager.update(
|
await queryRunner.manager.update(
|
||||||
this.tagRepository.target,
|
this.tagRepository.target,
|
||||||
{ uuid: tag.uuid },
|
{ uuid: tag.uuid },
|
||||||
{ subspace, space: null },
|
{ subspace },
|
||||||
);
|
);
|
||||||
tag.subspace = subspace;
|
tag.subspace = subspace;
|
||||||
}
|
}
|
||||||
@ -127,10 +127,9 @@ export class TagService {
|
|||||||
await queryRunner.manager.update(
|
await queryRunner.manager.update(
|
||||||
this.tagRepository.target,
|
this.tagRepository.target,
|
||||||
{ uuid: tag.uuid },
|
{ uuid: tag.uuid },
|
||||||
{ subspace: null, space: space },
|
{ subspace: null },
|
||||||
);
|
);
|
||||||
tag.subspace = null;
|
tag.subspace = null;
|
||||||
tag.space = space;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
@ -367,7 +366,6 @@ export class TagService {
|
|||||||
where: [
|
where: [
|
||||||
{
|
{
|
||||||
tag,
|
tag,
|
||||||
space: { uuid: spaceUuid },
|
|
||||||
product: { uuid: productUuid },
|
product: { uuid: productUuid },
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user