added base service

This commit is contained in:
hannathkadher
2024-12-17 19:21:00 +04:00
parent d1050babd1
commit e35cefb03b
4 changed files with 94 additions and 116 deletions

View File

@ -0,0 +1,69 @@
import { HttpException, HttpStatus } from '@nestjs/common';
import { QueryRunner } from 'typeorm';
export abstract class BaseProductItemService {
protected async validateTags(
incomingTags: string[],
queryRunner: QueryRunner,
spaceUuid: string,
): Promise<void> {
const duplicateTags = incomingTags.filter(
(tag, index) => incomingTags.indexOf(tag) !== index,
);
if (duplicateTags.length > 0) {
throw new HttpException(
`Duplicate tags found in the request: ${[...new Set(duplicateTags)].join(', ')}`,
HttpStatus.BAD_REQUEST,
);
}
const existingTagsQuery = `
SELECT tag FROM (
SELECT spi.tag
FROM "space-product-item" spi
INNER JOIN "space-product" spm ON spi.space_product_uuid = spm.uuid
WHERE spm.space_uuid = $1
UNION
SELECT spi.tag
FROM "subspace-product-item" spi
INNER JOIN "subspace-product" spm ON spi.subspace_product_uuid = spm.uuid
INNER JOIN "subspace" sm ON spm.subspace_uuid = sm.uuid
WHERE sm.space_uuid = $1
) AS combined_tags;
`;
const existingTags = await queryRunner.manager.query(existingTagsQuery, [
spaceUuid,
]);
const existingTagSet = new Set(
existingTags.map((row: { tag: string }) => row.tag),
);
const conflictingTags = incomingTags.filter((tag) =>
existingTagSet.has(tag),
);
if (conflictingTags.length > 0) {
throw new HttpException(
`Tags already exist in the model: ${conflictingTags.join(', ')}`,
HttpStatus.CONFLICT,
);
}
}
protected async saveProductItems<T>(
productItems: T[],
targetRepository: any,
queryRunner: QueryRunner,
): Promise<void> {
try {
await queryRunner.manager.save(targetRepository, productItems);
} catch (error) {
throw new HttpException(
error.message || 'An error occurred while creating product items.',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
}

View File

@ -0,0 +1 @@
export * from './base-product-item.service';

View File

@ -7,12 +7,15 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateSpaceProductItemDto } from '../../dtos';
import { QueryRunner } from 'typeorm';
import { SpaceProductModelEntity } from '@app/common/modules/space-model';
import { BaseProductItemService } from '../../common';
@Injectable()
export class SpaceProductItemService {
export class SpaceProductItemService extends BaseProductItemService {
constructor(
private readonly spaceProductItemRepository: SpaceProductItemRepository,
) {}
) {
super();
}
async createProductItem(
itemModelDtos: CreateSpaceProductItemDto[],
@ -20,7 +23,11 @@ export class SpaceProductItemService {
space: SpaceEntity,
queryRunner: QueryRunner,
) {
await this.validateTags(itemModelDtos, queryRunner, space);
if (!itemModelDtos?.length) return;
const incomingTags = itemModelDtos.map((item) => item.tag);
await this.validateTags(incomingTags, queryRunner, space.uuid);
try {
const productItems = itemModelDtos.map((dto) =>
@ -30,7 +37,11 @@ export class SpaceProductItemService {
}),
);
await queryRunner.manager.save(productItems);
await this.saveProductItems(
productItems,
this.spaceProductItemRepository.target,
queryRunner,
);
} catch (error) {
if (error instanceof HttpException) {
throw error;
@ -50,6 +61,7 @@ export class SpaceProductItemService {
queryRunner: QueryRunner,
) {
const spaceProductItemModels = spaceProductModel.items;
if (!spaceProductItemModels?.length) return;
try {
const productItems = spaceProductItemModels.map((model) =>
@ -72,56 +84,4 @@ export class SpaceProductItemService {
);
}
}
private async validateTags(
itemModelDtos: CreateSpaceProductItemDto[],
queryRunner: QueryRunner,
space: SpaceEntity,
) {
const query = `
SELECT spi.tag
FROM "space-product-item" spi
INNER JOIN "space-product" spm
ON spi.space_product_uuid = spm.uuid
WHERE spm.space_uuid = $1
UNION
SELECT spi.tag
FROM "subspace-product-item" spi
INNER JOIN "subspace-product" spm
ON spi.subspace_product_uuid = spm.uuid
INNER JOIN "subspace" sm
ON spm.subspace_uuid = sm.uuid
WHERE sm.space_uuid = $1;
`;
const result = await queryRunner.manager.query(query, [space.uuid]);
console.log(result);
const incomingTags = itemModelDtos.map((item) => item.tag);
const duplicateTags = incomingTags.filter(
(tag, index) => incomingTags.indexOf(tag) !== index,
);
if (duplicateTags.length > 0) {
throw new HttpException(
`Duplicate tags found in the request: ${[...new Set(duplicateTags)].join(', ')}`,
HttpStatus.BAD_REQUEST,
);
}
const existingTags = await queryRunner.manager.query(query, [space.uuid]);
const existingTagSet = new Set(existingTags.map((item) => item.tag));
const conflictingTags = incomingTags.filter((tag) =>
existingTagSet.has(tag),
);
if (conflictingTags.length > 0) {
throw new HttpException(
`Tags already exist in the model: ${conflictingTags.join(', ')}`,
HttpStatus.CONFLICT,
);
}
}
}

View File

@ -11,13 +11,16 @@ import {
SubspaceProductModelEntity,
} from '@app/common/modules/space-model';
import { SubspaceProductItemRepository } from '@app/common/modules/space/repositories/subspace.repository';
import { CreateSpaceProductItemDto } from 'src/space/dtos';
import { CreateSpaceProductItemDto } from '../../dtos';
import { BaseProductItemService } from '../../common';
@Injectable()
export class SubspaceProductItemService {
export class SubspaceProductItemService extends BaseProductItemService {
constructor(
private readonly productItemRepository: SubspaceProductItemRepository,
) {}
) {
super();
}
async createItemFromModel(
product: SubspaceProductEntity,
@ -64,10 +67,10 @@ export class SubspaceProductItemService {
space: SpaceEntity,
) {
if (!itemDto?.length) return;
const incomingTags = itemDto.map((item) => item.tag);
await this.validateTags(incomingTags, queryRunner, space.uuid);
try {
await this.validateTags(itemDto, queryRunner, space);
const productItems = itemDto.map((dto) =>
queryRunner.manager.create(SubspaceProductItemEntity, {
tag: dto.tag,
@ -86,59 +89,4 @@ export class SubspaceProductItemService {
);
}
}
private async validateTags(
subspaceItemModelDtos: CreateSpaceProductItemDto[],
queryRunner: QueryRunner,
space: SpaceEntity,
) {
const incomingTags = subspaceItemModelDtos.map((item) => item.tag);
const duplicateTags = incomingTags.filter(
(tag, index) => incomingTags.indexOf(tag) !== index,
);
if (duplicateTags.length > 0) {
throw new HttpException(
`Duplicate tags found in the request: ${[...new Set(duplicateTags)].join(', ')}`,
HttpStatus.BAD_REQUEST,
);
}
const existingTagsQuery = `
SELECT spi.tag
FROM "space-product-item" spi
INNER JOIN "space-product" spm
ON spi.space_product_uuid = spm.uuid
WHERE spm.space_uuid = $1
UNION
SELECT spi.tag
FROM "subspace-product-item" spi
INNER JOIN "subspace-product" spm
ON spi.subspace_product_uuid = spm.uuid
INNER JOIN "subspace" sm
ON spm.subspace_uuid = sm.uuid
WHERE sm.space_uuid = $1;
`;
const existingTags = await queryRunner.manager.query(existingTagsQuery, [
space.uuid,
]);
console.log(existingTags);
const existingTagsSet = new Set(
existingTags.map((row: { tag: string }) => row.tag),
);
const conflictingTags = [...incomingTags].filter((tag) =>
existingTagsSet.has(tag),
);
if (conflictingTags.length > 0) {
throw new HttpException(
`Tags already exist in the model: ${conflictingTags.join(', ')}`,
HttpStatus.CONFLICT,
);
}
}
}