diff --git a/src/core/helpers/query/check-duplicate.helpers.ts b/src/core/helpers/query/check-duplicate.helpers.ts new file mode 100644 index 0000000..2960c08 --- /dev/null +++ b/src/core/helpers/query/check-duplicate.helpers.ts @@ -0,0 +1,41 @@ +import { HttpStatus, UnprocessableEntityException } from '@nestjs/common'; +import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; + +export class CheckDuplicateHelper { + constructor( + private dataService: BaseDataService, + private duplicateColumn: string[], + private entity: any, + private entityId?: string, + ) {} + + async execute() { + for (const column of this.duplicateColumn) { + const queryBuilder = this.dataService + .getRepository() + .createQueryBuilder(); + queryBuilder.orWhere( + `replace(trim(lower(${column})), ' ',' ') = :query`, + { + query: this.entity[column] + ?.toLowerCase() + .trim() + .replace(/ +(?= )/g, ''), + }, + ); + + if (this.entityId) { + queryBuilder.andWhere(`id Not In ('${this.entityId}')`); + } + + const data_exists = await queryBuilder.getCount(); + if (data_exists > 0) { + throw new UnprocessableEntityException({ + statusCode: HttpStatus.UNPROCESSABLE_ENTITY, + message: `Entity with ${column} : ${this.entity[column]} already exist`, + error: 'Unprocessable Entity', + }); + } + } + } +} diff --git a/src/core/modules/domain/usecase/base.manager.ts b/src/core/modules/domain/usecase/base.manager.ts index de0d828..b06fb96 100644 --- a/src/core/modules/domain/usecase/base.manager.ts +++ b/src/core/modules/domain/usecase/base.manager.ts @@ -1,8 +1,4 @@ -import { - Inject, - Injectable, - Logger, -} from '@nestjs/common'; +import { Inject, Injectable, Logger } from '@nestjs/common'; import { EventBus } from '@nestjs/cqrs'; import { UserProvider, UsersSession } from 'src/core/sessions'; import { BLANK_USER } from 'src/core/strings/constants/base.constants'; diff --git a/src/core/modules/domain/usecase/managers/base-create.manager.ts b/src/core/modules/domain/usecase/managers/base-create.manager.ts index 13ff9a9..d3a7991 100644 --- a/src/core/modules/domain/usecase/managers/base-create.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-create.manager.ts @@ -1,10 +1,11 @@ +import { CheckDuplicateHelper } from 'src/core/helpers/query/check-duplicate.helpers'; import { BaseManager } from '../base.manager'; -import { Injectable } from '@nestjs/common'; export abstract class BaseCreateManager extends BaseManager { protected result: Entity; protected duplicateColumn: string[]; abstract get entityTarget(): any; + abstract get uniqueColumns(): string[]; setData(entity: Entity): void { this.data = entity; @@ -19,6 +20,17 @@ export abstract class BaseCreateManager extends BaseManager { }); } + async validateProcess(): Promise { + if (this.uniqueColumns.length) { + await new CheckDuplicateHelper( + this.dataService, + this.uniqueColumns, + this.data, + ).execute(); + } + return; + } + async process(): Promise { this.result = await this.dataService.create( this.queryRunner, diff --git a/src/core/modules/domain/usecase/managers/base-custom.manager.ts b/src/core/modules/domain/usecase/managers/base-custom.manager.ts new file mode 100644 index 0000000..f066360 --- /dev/null +++ b/src/core/modules/domain/usecase/managers/base-custom.manager.ts @@ -0,0 +1,21 @@ +import { BaseManager } from '../base.manager'; + +export abstract class BaseCustomManager extends BaseManager { + protected result: Entity; + abstract get entityTarget(): any; + + setData(entity: Entity): void { + this.data = entity; + } + + async prepareData(): Promise { + if (this.data) + Object.assign(this.data, { + editor_id: this.user.id, + editor_name: this.user.name, + updated_at: new Date().getTime(), + }); + } + + abstract getResult(): any; +} diff --git a/src/core/modules/domain/usecase/managers/base-delete.manager.ts b/src/core/modules/domain/usecase/managers/base-delete.manager.ts index f5c187a..2841d6e 100644 --- a/src/core/modules/domain/usecase/managers/base-delete.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-delete.manager.ts @@ -1,8 +1,4 @@ -import { - HttpStatus, - Injectable, - UnprocessableEntityException, -} from '@nestjs/common'; +import { HttpStatus, UnprocessableEntityException } from '@nestjs/common'; import { BaseManager } from '../base.manager'; export abstract class BaseDeleteManager extends BaseManager { diff --git a/src/core/modules/domain/usecase/managers/base-detail.manager.ts b/src/core/modules/domain/usecase/managers/base-detail.manager.ts index 3f9b374..87c8916 100644 --- a/src/core/modules/domain/usecase/managers/base-detail.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-detail.manager.ts @@ -1,24 +1,23 @@ -import { BaseReadManager } from "../base-read.manager"; +import { BaseReadManager } from '../base-read.manager'; export abstract class BaseDetailManager extends BaseReadManager { + protected dataId: string; + protected result: Entity; - protected dataId: string; - protected result: Entity; + abstract get selectData(): string[]; + abstract get relationData(): string[]; + abstract get setFindProperties(): any; - abstract get selectData(): string[]; - abstract get relationData(): string[]; - abstract get setFindProperties(): any; + setData(dataId: string): void { + this.dataId = dataId; + } - setData(dataId: string): void { - this.dataId = dataId; - } + async process(): Promise { + this.queryBuilder.select(this.selectData).where(this.setFindProperties); + this.result = await this.queryBuilder.getOne(); + } - async process(): Promise { - this.queryBuilder.select(this.selectData).where(this.setFindProperties); - this.result = await this.queryBuilder.getOne(); - } - - getResult(): Entity { - return this.result; - } -} \ No newline at end of file + getResult(): Entity { + return this.result; + } +} diff --git a/src/core/modules/domain/usecase/managers/base-index.manager.ts b/src/core/modules/domain/usecase/managers/base-index.manager.ts index 41f9a4b..db6eff5 100644 --- a/src/core/modules/domain/usecase/managers/base-index.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-index.manager.ts @@ -1,54 +1,57 @@ -import { PaginationResponse } from "src/core/response/domain/ok-response.interface"; -import { BaseReadManager } from "../base-read.manager"; -import { SelectQueryBuilder } from "typeorm"; -import { BaseFilterEntity } from "../../entities/base-filter.entity"; -import { Param, SpecificSearchFilter } from "src/core/helpers/query/specific-search.helper"; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { BaseReadManager } from '../base-read.manager'; +import { SelectQueryBuilder } from 'typeorm'; +import { + Param, + SpecificSearchFilter, +} from 'src/core/helpers/query/specific-search.helper'; export abstract class BaseIndexManager extends BaseReadManager { - - protected result: PaginationResponse; - public filterParam: BaseFilterEntity; - abstract get specificFilter(): Param[]; + protected result: PaginationResponse; + public filterParam: any; + abstract get specificFilter(): Param[]; - setFilterParam(param: BaseFilterEntity): void { - this.filterParam = param; - } + setFilterParam(param: any): void { + this.filterParam = param; + } - async process(): Promise { - // const filterSearch: string[] = this.setFilterSearch(); + async process(): Promise { + // const filterSearch: string[] = this.setFilterSearch(); - // this.queryBuilder.andWhere( - // new Brackets((qb) => { - // filterSearch.map((fSearch) => { - // qb.orWhere(`${fSearch} ILIKE :query`, { - // query: `%${ - // this.filterParam.q.trim().replace(/\s+/g, ' ') ?? '' - // }%`, - // }); - // }); - // }), - // ); + // this.queryBuilder.andWhere( + // new Brackets((qb) => { + // filterSearch.map((fSearch) => { + // qb.orWhere(`${fSearch} ILIKE :query`, { + // query: `%${ + // this.filterParam.q.trim().replace(/\s+/g, ' ') ?? '' + // }%`, + // }); + // }); + // }), + // ); - new SpecificSearchFilter(this.queryBuilder, this.tableName, this.specificFilter).getFilter(); - this.setQueryFilter(this.queryBuilder); + // new SpecificSearchFilter( + // this.queryBuilder, + // this.tableName, + // this.specificFilter, + // ).getFilter(); + this.setQueryFilter(this.queryBuilder); - this.result = await this.dataService.getIndex( - this.queryBuilder, - this.filterParam, - ); - } - + this.result = await this.dataService.getIndex( + this.queryBuilder, + this.filterParam, + ); + } - setFilterSearch(): string[] { - return []; - } - - abstract setQueryFilter( - queryBuilder: SelectQueryBuilder, - ): SelectQueryBuilder; - - - getResult(): PaginationResponse { - return this.result; - } -} \ No newline at end of file + setFilterSearch(): string[] { + return []; + } + + abstract setQueryFilter( + queryBuilder: SelectQueryBuilder, + ): SelectQueryBuilder; + + getResult(): PaginationResponse { + return this.result; + } +} diff --git a/src/core/modules/domain/usecase/managers/base-update-status.manager.ts b/src/core/modules/domain/usecase/managers/base-update-status.manager.ts index fa6290c..ac27977 100644 --- a/src/core/modules/domain/usecase/managers/base-update-status.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-update-status.manager.ts @@ -1,6 +1,6 @@ import { BaseManager } from '../base.manager'; import { STATUS } from 'src/core/strings/constants/base.constants'; -import { UserPrivilegeModel } from 'src/modules/user-related/user-privilege/data/model/user-privilege.model'; +import { UserPrivilegeModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege.model'; export abstract class BaseUpdateStatusManager extends BaseManager { protected dataId: string; diff --git a/src/core/modules/domain/usecase/managers/base-update.manager.ts b/src/core/modules/domain/usecase/managers/base-update.manager.ts index 1eb356b..2c15838 100644 --- a/src/core/modules/domain/usecase/managers/base-update.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-update.manager.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { CheckDuplicateHelper } from 'src/core/helpers/query/check-duplicate.helpers'; import { BaseManager } from '../base.manager'; export abstract class BaseUpdateManager extends BaseManager { @@ -6,6 +6,7 @@ export abstract class BaseUpdateManager extends BaseManager { protected result: Entity; protected duplicateColumn: string[]; abstract get entityTarget(): any; + abstract get uniqueColumns(): string[]; setData(id: string, entity: Entity): void { this.dataId = id; @@ -18,6 +19,15 @@ export abstract class BaseUpdateManager extends BaseManager { editor_name: this.user.name, updated_at: new Date().getTime(), }); + + if (this.uniqueColumns.length) { + await new CheckDuplicateHelper( + this.dataService, + this.uniqueColumns, + this.data, + this.dataId, + ).execute(); + } } async process(): Promise {