From efa245048a727f3a005d485d6561fe139cc33e59 Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 22 Oct 2024 11:47:55 +0700 Subject: [PATCH] feat: item queue module --- src/app.module.ts | 17 +++ .../data/models/item-queue.model.ts | 28 ++++ .../data/services/item-queue-data.service.ts | 17 +++ .../data/services/item-queue-read.service.ts | 17 +++ .../entities/filter-item-queue.entity.ts | 5 + .../domain/entities/item-queue.entity.ts | 9 ++ .../usecases/item-queue-data.orchestrator.ts | 122 ++++++++++++++++++ .../usecases/item-queue-read.orchestrator.ts | 33 +++++ .../managers/active-item-queue.manager.ts | 39 ++++++ .../batch-active-item-queue.manager.ts | 40 ++++++ .../batch-confirm-item-queue.manager.ts | 40 ++++++ .../batch-delete-item-queue.manager.ts | 46 +++++++ .../batch-inactive-item-queue.manager.ts | 46 +++++++ .../managers/confirm-item-queue.manager.ts | 39 ++++++ .../managers/create-item-queue.manager.ts | 43 ++++++ .../managers/delete-item-queue.manager.ts | 45 +++++++ .../managers/detail-item-queue.manager.ts | 58 +++++++++ .../managers/inactive-item-queue.manager.ts | 45 +++++++ .../managers/index-item-queue.manager.ts | 75 +++++++++++ .../managers/update-item-queue.manager.ts | 53 ++++++++ src/modules/item-related/item-queue/index.ts | 0 .../dto/filter-item-queue.dto.ts | 15 +++ .../infrastructure/dto/item-queue.dto.ts | 32 +++++ .../item-queue-data.controller.ts | 78 +++++++++++ .../item-queue-read.controller.ts | 30 +++++ .../item-queue/item-queue.module.ts | 54 ++++++++ .../item/data/models/item.model.ts | 12 +- .../item/domain/entities/item.entity.ts | 2 +- .../item/infrastructure/dto/item.dto.ts | 12 +- 29 files changed, 1045 insertions(+), 7 deletions(-) create mode 100644 src/modules/item-related/item-queue/data/models/item-queue.model.ts create mode 100644 src/modules/item-related/item-queue/data/services/item-queue-data.service.ts create mode 100644 src/modules/item-related/item-queue/data/services/item-queue-read.service.ts create mode 100644 src/modules/item-related/item-queue/domain/entities/filter-item-queue.entity.ts create mode 100644 src/modules/item-related/item-queue/domain/entities/item-queue.entity.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/item-queue-data.orchestrator.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/item-queue-read.orchestrator.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/active-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/batch-active-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/batch-confirm-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/batch-delete-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/batch-inactive-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/confirm-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/create-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/delete-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/detail-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/inactive-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/index-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/domain/usecases/managers/update-item-queue.manager.ts create mode 100644 src/modules/item-related/item-queue/index.ts create mode 100644 src/modules/item-related/item-queue/infrastructure/dto/filter-item-queue.dto.ts create mode 100644 src/modules/item-related/item-queue/infrastructure/dto/item-queue.dto.ts create mode 100644 src/modules/item-related/item-queue/infrastructure/item-queue-data.controller.ts create mode 100644 src/modules/item-related/item-queue/infrastructure/item-queue-read.controller.ts create mode 100644 src/modules/item-related/item-queue/item-queue.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index b8001b4..36efd42 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -83,6 +83,14 @@ import { UserLoginModel } from './modules/user-related/user/data/models/user-log import { LogUserLoginModel } from './modules/configuration/log/data/models/log-user-login.model'; import { AuthService } from './core/guards/domain/services/auth.service'; import { ReportSummaryModule } from './modules/reports/report-summary/report-summary.module'; +import { QueueModule } from './modules/queue/queue.module'; +import { + QueueOrderModel, + QueueTicketModel, + QueueItemModel, +} from './modules/queue/data/models/queue.model'; +import { ItemQueueModule } from './modules/item-related/item-queue/item-queue.module'; +import { ItemQueueModel } from './modules/item-related/item-queue/data/models/item-queue.model'; @Module({ imports: [ @@ -107,6 +115,7 @@ import { ReportSummaryModule } from './modules/reports/report-summary/report-sum ItemModel, ItemCategoryModel, ItemRateModel, + ItemQueueModel, LogModel, LogUserLoginModel, NewsModel, @@ -135,6 +144,11 @@ import { ReportSummaryModule } from './modules/reports/report-summary/report-sum // report ReportBookmarkModel, ExportReportHistoryModel, + + // Queue + QueueOrderModel, + QueueTicketModel, + QueueItemModel, ], synchronize: false, }), @@ -160,6 +174,7 @@ import { ReportSummaryModule } from './modules/reports/report-summary/report-sum ItemCategoryModule, ItemModule, ItemRateModule, + ItemQueueModule, // transaction PaymentMethodModule, @@ -193,6 +208,8 @@ import { ReportSummaryModule } from './modules/reports/report-summary/report-sum SupersetModule, GateScanModule, + + QueueModule, ], controllers: [], providers: [ diff --git a/src/modules/item-related/item-queue/data/models/item-queue.model.ts b/src/modules/item-related/item-queue/data/models/item-queue.model.ts new file mode 100644 index 0000000..293a849 --- /dev/null +++ b/src/modules/item-related/item-queue/data/models/item-queue.model.ts @@ -0,0 +1,28 @@ +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; +import { ItemQueueEntity } from '../../domain/entities/item-queue.entity'; +import { Column, Entity, OneToMany } from 'typeorm'; +import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model'; +import { ItemType } from '../../constants'; +import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; + +@Entity(TABLE_NAME.ITEM_QUEUE) +export class ItemQueueModel + extends BaseStatusModel + implements ItemQueueEntity +{ + @Column('varchar', { name: 'name' }) + name: string; + + @Column('enum', { + name: 'item_type', + enum: ItemType, + default: ItemType.TIKET_MASUK, + }) + item_type: ItemType; + + @OneToMany(() => ItemModel, (model) => model.item_queue, { + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + }) + items: ItemModel[]; +} diff --git a/src/modules/item-related/item-queue/data/services/item-queue-data.service.ts b/src/modules/item-related/item-queue/data/services/item-queue-data.service.ts new file mode 100644 index 0000000..7b67210 --- /dev/null +++ b/src/modules/item-related/item-queue/data/services/item-queue-data.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; +import { ItemQueueEntity } from '../../domain/entities/item-queue.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ItemQueueModel } from '../models/item-queue.model'; +import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; +import { Repository } from 'typeorm'; + +@Injectable() +export class ItemQueueDataService extends BaseDataService { + constructor( + @InjectRepository(ItemQueueModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/item-related/item-queue/data/services/item-queue-read.service.ts b/src/modules/item-related/item-queue/data/services/item-queue-read.service.ts new file mode 100644 index 0000000..64414f6 --- /dev/null +++ b/src/modules/item-related/item-queue/data/services/item-queue-read.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { ItemQueueEntity } from '../../domain/entities/item-queue.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ItemQueueModel } from '../models/item-queue.model'; +import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; +import { Repository } from 'typeorm'; +import { BaseReadService } from 'src/core/modules/data/service/base-read.service'; + +@Injectable() +export class ItemQueueReadService extends BaseReadService { + constructor( + @InjectRepository(ItemQueueModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/item-related/item-queue/domain/entities/filter-item-queue.entity.ts b/src/modules/item-related/item-queue/domain/entities/filter-item-queue.entity.ts new file mode 100644 index 0000000..e01cdcc --- /dev/null +++ b/src/modules/item-related/item-queue/domain/entities/filter-item-queue.entity.ts @@ -0,0 +1,5 @@ +import { BaseFilterEntity } from 'src/core/modules/domain/entities/base-filter.entity'; + +export interface FilterItemQueueEntity extends BaseFilterEntity { + item_types: string[]; +} diff --git a/src/modules/item-related/item-queue/domain/entities/item-queue.entity.ts b/src/modules/item-related/item-queue/domain/entities/item-queue.entity.ts new file mode 100644 index 0000000..e3b7708 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/entities/item-queue.entity.ts @@ -0,0 +1,9 @@ +import { BaseStatusEntity } from 'src/core/modules/domain/entities/base-status.entity'; +import { ItemType } from '../../constants'; +import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity'; + +export interface ItemQueueEntity extends BaseStatusEntity { + name: string; + item_type: ItemType; + items: ItemEntity[]; +} diff --git a/src/modules/item-related/item-queue/domain/usecases/item-queue-data.orchestrator.ts b/src/modules/item-related/item-queue/domain/usecases/item-queue-data.orchestrator.ts new file mode 100644 index 0000000..91dcd16 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/item-queue-data.orchestrator.ts @@ -0,0 +1,122 @@ +import { Injectable } from '@nestjs/common'; +import { CreateItemQueueManager } from './managers/create-item-queue.manager'; +import { ItemQueueDataService } from '../../data/services/item-queue-data.service'; +import { ItemQueueEntity } from '../entities/item-queue.entity'; +import { DeleteItemQueueManager } from './managers/delete-item-queue.manager'; +import { UpdateItemQueueManager } from './managers/update-item-queue.manager'; +import { BaseDataTransactionOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-data-transaction.orchestrator'; +import { ActiveItemQueueManager } from './managers/active-item-queue.manager'; +import { InactiveItemQueueManager } from './managers/inactive-item-queue.manager'; +import { ConfirmItemQueueManager } from './managers/confirm-item-queue.manager'; +import { STATUS } from 'src/core/strings/constants/base.constants'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { BatchConfirmItemQueueManager } from './managers/batch-confirm-item-queue.manager'; +import { BatchInactiveItemQueueManager } from './managers/batch-inactive-item-queue.manager'; +import { BatchActiveItemQueueManager } from './managers/batch-active-item-queue.manager'; +import { BatchDeleteItemQueueManager } from './managers/batch-delete-item-queue.manager'; +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; + +@Injectable() +export class ItemQueueDataOrchestrator extends BaseDataTransactionOrchestrator { + constructor( + private createManager: CreateItemQueueManager, + private updateManager: UpdateItemQueueManager, + private deleteManager: DeleteItemQueueManager, + private activeManager: ActiveItemQueueManager, + private confirmManager: ConfirmItemQueueManager, + private inactiveManager: InactiveItemQueueManager, + private batchDeleteManager: BatchDeleteItemQueueManager, + private batchActiveManager: BatchActiveItemQueueManager, + private batchConfirmManager: BatchConfirmItemQueueManager, + private batchInactiveManager: BatchInactiveItemQueueManager, + private serviceData: ItemQueueDataService, + ) { + super(); + } + + async create(data): Promise { + data.items = data.item_ids.map((id) => { + return { id }; + }); + this.createManager.setData(data); + this.createManager.setService(this.serviceData, TABLE_NAME.ITEM_CATEGORY); + await this.createManager.execute(); + await this.createManager.generateConfig(); + return this.createManager.getResult(); + } + + async update(dataId, data): Promise { + this.updateManager.setData(dataId, data); + this.updateManager.setService(this.serviceData, TABLE_NAME.ITEM_CATEGORY); + await this.updateManager.execute(); + return this.updateManager.getResult(); + } + + async delete(dataId): Promise { + this.deleteManager.setData(dataId); + this.deleteManager.setService(this.serviceData, TABLE_NAME.ITEM_CATEGORY); + await this.deleteManager.execute(); + return this.deleteManager.getResult(); + } + + async batchDelete(dataIds: string[]): Promise { + this.batchDeleteManager.setData(dataIds); + this.batchDeleteManager.setService( + this.serviceData, + TABLE_NAME.ITEM_CATEGORY, + ); + await this.batchDeleteManager.execute(); + return this.batchDeleteManager.getResult(); + } + + async active(dataId): Promise { + this.activeManager.setData(dataId, STATUS.ACTIVE); + this.activeManager.setService(this.serviceData, TABLE_NAME.ITEM_CATEGORY); + await this.activeManager.execute(); + return this.activeManager.getResult(); + } + + async batchActive(dataIds: string[]): Promise { + this.batchActiveManager.setData(dataIds, STATUS.ACTIVE); + this.batchActiveManager.setService( + this.serviceData, + TABLE_NAME.ITEM_CATEGORY, + ); + await this.batchActiveManager.execute(); + return this.batchActiveManager.getResult(); + } + + async confirm(dataId): Promise { + this.confirmManager.setData(dataId, STATUS.ACTIVE); + this.confirmManager.setService(this.serviceData, TABLE_NAME.ITEM_CATEGORY); + await this.confirmManager.execute(); + return this.confirmManager.getResult(); + } + + async batchConfirm(dataIds: string[]): Promise { + this.batchConfirmManager.setData(dataIds, STATUS.ACTIVE); + this.batchConfirmManager.setService( + this.serviceData, + TABLE_NAME.ITEM_CATEGORY, + ); + await this.batchConfirmManager.execute(); + return this.batchConfirmManager.getResult(); + } + + async inactive(dataId): Promise { + this.inactiveManager.setData(dataId, STATUS.INACTIVE); + this.inactiveManager.setService(this.serviceData, TABLE_NAME.ITEM_CATEGORY); + await this.inactiveManager.execute(); + return this.inactiveManager.getResult(); + } + + async batchInactive(dataIds: string[]): Promise { + this.batchInactiveManager.setData(dataIds, STATUS.INACTIVE); + this.batchInactiveManager.setService( + this.serviceData, + TABLE_NAME.ITEM_CATEGORY, + ); + await this.batchInactiveManager.execute(); + return this.batchInactiveManager.getResult(); + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/item-queue-read.orchestrator.ts b/src/modules/item-related/item-queue/domain/usecases/item-queue-read.orchestrator.ts new file mode 100644 index 0000000..281d389 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/item-queue-read.orchestrator.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; +import { IndexItemQueueManager } from './managers/index-item-queue.manager'; +import { ItemQueueReadService } from '../../data/services/item-queue-read.service'; +import { ItemQueueEntity } from '../entities/item-queue.entity'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { BaseReadOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-read.orchestrator'; +import { DetailItemQueueManager } from './managers/detail-item-queue.manager'; +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; + +@Injectable() +export class ItemQueueReadOrchestrator extends BaseReadOrchestrator { + constructor( + private indexManager: IndexItemQueueManager, + private detailManager: DetailItemQueueManager, + private serviceData: ItemQueueReadService, + ) { + super(); + } + + async index(params): Promise> { + this.indexManager.setFilterParam(params); + this.indexManager.setService(this.serviceData, TABLE_NAME.ITEM_QUEUE); + await this.indexManager.execute(); + return this.indexManager.getResult(); + } + + async detail(dataId: string): Promise { + this.detailManager.setData(dataId); + this.detailManager.setService(this.serviceData, TABLE_NAME.ITEM_QUEUE); + await this.detailManager.execute(); + return this.detailManager.getResult(); + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/active-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/active-item-queue.manager.ts new file mode 100644 index 0000000..ae3baba --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/active-item-queue.manager.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-update-status.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; + +@Injectable() +export class ActiveItemQueueManager extends BaseUpdateStatusManager { + getResult(): string { + return `Success active data ${this.result.name}`; + } + + async validateProcess(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/batch-active-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/batch-active-item-queue.manager.ts new file mode 100644 index 0000000..e70d534 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/batch-active-item-queue.manager.ts @@ -0,0 +1,40 @@ +import { BaseBatchUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-batch-update-status.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchActiveItemQueueManager extends BaseBatchUpdateStatusManager { + validateData(data: ItemQueueEntity): Promise { + return; + } + + beforeProcess(): Promise { + return; + } + + afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/batch-confirm-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/batch-confirm-item-queue.manager.ts new file mode 100644 index 0000000..02ec3d9 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/batch-confirm-item-queue.manager.ts @@ -0,0 +1,40 @@ +import { BaseBatchUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-batch-update-status.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchConfirmItemQueueManager extends BaseBatchUpdateStatusManager { + validateData(data: ItemQueueEntity): Promise { + return; + } + + beforeProcess(): Promise { + return; + } + + afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/batch-delete-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/batch-delete-item-queue.manager.ts new file mode 100644 index 0000000..a226ce6 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/batch-delete-item-queue.manager.ts @@ -0,0 +1,46 @@ +import { BaseBatchDeleteManager } from 'src/core/modules/domain/usecase/managers/base-batch-delete.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchDeleteItemQueueManager extends BaseBatchDeleteManager { + async beforeProcess(): Promise { + return; + } + + async validateData(data: ItemQueueEntity): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return [ + { + relation: 'items', + message: + 'Gagal! tidak dapat mengubah tipe item karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/batch-inactive-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/batch-inactive-item-queue.manager.ts new file mode 100644 index 0000000..2d3c725 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/batch-inactive-item-queue.manager.ts @@ -0,0 +1,46 @@ +import { BaseBatchUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-batch-update-status.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchInactiveItemQueueManager extends BaseBatchUpdateStatusManager { + validateData(data: ItemQueueEntity): Promise { + return; + } + + beforeProcess(): Promise { + return; + } + + afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return [ + { + relation: 'items', + message: + 'Gagal! tidak dapat mengubah tipe item karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/confirm-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/confirm-item-queue.manager.ts new file mode 100644 index 0000000..d0ad2b8 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/confirm-item-queue.manager.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-update-status.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; + +@Injectable() +export class ConfirmItemQueueManager extends BaseUpdateStatusManager { + getResult(): string { + return `Success active data ${this.result.name}`; + } + + async validateProcess(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/create-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/create-item-queue.manager.ts new file mode 100644 index 0000000..09c3c21 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/create-item-queue.manager.ts @@ -0,0 +1,43 @@ +import { Injectable } from '@nestjs/common'; +import { + EventTopics, + columnUniques, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; +import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager'; + +@Injectable() +export class CreateItemQueueManager extends BaseCreateManager { + async beforeProcess(): Promise { + Object.assign(this.data, { + item_type: this.data.item_type.toLowerCase(), + }); + return; + } + + async afterProcess(): Promise { + return; + } + + async generateConfig(): Promise { + // TODO: Implement logic here + } + + get validateRelations(): validateRelations[] { + return []; + } + + get uniqueColumns(): columnUniques[] { + return [{ column: 'name' }]; + } + + get eventTopics(): EventTopics[] { + return []; + } + + get entityTarget(): any { + return ItemQueueModel; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/delete-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/delete-item-queue.manager.ts new file mode 100644 index 0000000..db63c0c --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/delete-item-queue.manager.ts @@ -0,0 +1,45 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDeleteManager } from 'src/core/modules/domain/usecase/managers/base-delete.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; + +@Injectable() +export class DeleteItemQueueManager extends BaseDeleteManager { + getResult(): string { + return `Success`; + } + + async validateProcess(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return [ + { + relation: 'items', + message: + 'Gagal! tidak dapat mengubah tipe item karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/detail-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/detail-item-queue.manager.ts new file mode 100644 index 0000000..007c5b9 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/detail-item-queue.manager.ts @@ -0,0 +1,58 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDetailManager } from 'src/core/modules/domain/usecase/managers/base-detail.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity'; + +@Injectable() +export class DetailItemQueueManager extends BaseDetailManager { + async prepareData(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get relations(): RelationParam { + return { + joinRelations: [], + selectRelations: ['items'], + countRelations: [], + }; + } + + get selects(): string[] { + return [ + `${this.tableName}.id`, + `${this.tableName}.status`, + `${this.tableName}.name`, + `${this.tableName}.item_type`, + `${this.tableName}.created_at`, + `${this.tableName}.creator_name`, + `${this.tableName}.updated_at`, + `${this.tableName}.editor_name`, + + `items.id`, + `items.created_at`, + `items.status`, + `items.item_type`, + `items.name`, + `items.hpp`, + `items.limit_type`, + `items.limit_value`, + `items.base_price`, + `items.share_profit`, + `items.play_estimation`, + ]; + } + + get setFindProperties(): any { + return { + id: this.dataId, + }; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/inactive-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/inactive-item-queue.manager.ts new file mode 100644 index 0000000..106ab98 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/inactive-item-queue.manager.ts @@ -0,0 +1,45 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-update-status.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; + +@Injectable() +export class InactiveItemQueueManager extends BaseUpdateStatusManager { + getResult(): string { + return `Success inactive data ${this.result.name}`; + } + + async validateProcess(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return [ + { + relation: 'items', + message: + 'Gagal! tidak dapat mengubah tipe item karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/index-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/index-item-queue.manager.ts new file mode 100644 index 0000000..b1256d3 --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/index-item-queue.manager.ts @@ -0,0 +1,75 @@ +import { Injectable } from '@nestjs/common'; +import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { SelectQueryBuilder } from 'typeorm'; +import { + Param, + RelationParam, +} from 'src/core/modules/domain/entities/base-filter.entity'; + +@Injectable() +export class IndexItemQueueManager extends BaseIndexManager { + async prepareData(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get relations(): RelationParam { + return { + joinRelations: [], + selectRelations: ['items'], + countRelations: [], + }; + } + + get selects(): string[] { + return [ + `${this.tableName}.id`, + `${this.tableName}.status`, + `${this.tableName}.name`, + `${this.tableName}.item_type`, + `${this.tableName}.created_at`, + `${this.tableName}.creator_name`, + `${this.tableName}.updated_at`, + `${this.tableName}.editor_name`, + + `items.id`, + `items.created_at`, + `items.status`, + `items.item_type`, + `items.name`, + `items.hpp`, + `items.limit_type`, + `items.limit_value`, + `items.base_price`, + `items.share_profit`, + `items.play_estimation`, + ]; + } + + get specificFilter(): Param[] { + return [ + { + cols: `${this.tableName}.name`, + data: this.filterParam.names, + }, + { + cols: `${this.tableName}.item_type::text`, + data: this.filterParam.item_types, + }, + ]; + } + + setQueryFilter( + queryBuilder: SelectQueryBuilder, + ): SelectQueryBuilder { + return queryBuilder; + } +} diff --git a/src/modules/item-related/item-queue/domain/usecases/managers/update-item-queue.manager.ts b/src/modules/item-related/item-queue/domain/usecases/managers/update-item-queue.manager.ts new file mode 100644 index 0000000..2801c3b --- /dev/null +++ b/src/modules/item-related/item-queue/domain/usecases/managers/update-item-queue.manager.ts @@ -0,0 +1,53 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateManager } from 'src/core/modules/domain/usecase/managers/base-update.manager'; +import { ItemQueueEntity } from '../../entities/item-queue.entity'; +import { ItemQueueModel } from '../../../data/models/item-queue.model'; +import { + EventTopics, + columnUniques, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; + +@Injectable() +export class UpdateItemQueueManager extends BaseUpdateManager { + async validateProcess(): Promise { + Object.assign(this.data, { + item_type: this.data.item_type.toLowerCase(), + }); + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + if (this.data.item_type != this.oldData.item_type) { + return [ + { + relation: 'items', + message: + 'Gagal! tidak dapat mengubah tipe item karena sudah berelasi dengan item', + }, + ]; + } else { + return []; + } + } + + get uniqueColumns(): columnUniques[] { + return [{ column: 'name' }]; + } + + get entityTarget(): any { + return ItemQueueModel; + } + + get eventTopics(): EventTopics[] { + return []; + } +} diff --git a/src/modules/item-related/item-queue/index.ts b/src/modules/item-related/item-queue/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/modules/item-related/item-queue/infrastructure/dto/filter-item-queue.dto.ts b/src/modules/item-related/item-queue/infrastructure/dto/filter-item-queue.dto.ts new file mode 100644 index 0000000..ab43721 --- /dev/null +++ b/src/modules/item-related/item-queue/infrastructure/dto/filter-item-queue.dto.ts @@ -0,0 +1,15 @@ +import { BaseFilterDto } from 'src/core/modules/infrastructure/dto/base-filter.dto'; +import { FilterItemQueueEntity } from '../../domain/entities/filter-item-queue.entity'; +import { ApiProperty } from '@nestjs/swagger'; +import { Transform } from 'class-transformer'; + +export class FilterItemQueueDto + extends BaseFilterDto + implements FilterItemQueueEntity +{ + @ApiProperty({ type: ['string'], required: false }) + @Transform((body) => { + return Array.isArray(body.value) ? body.value : [body.value]; + }) + item_types: string[]; +} diff --git a/src/modules/item-related/item-queue/infrastructure/dto/item-queue.dto.ts b/src/modules/item-related/item-queue/infrastructure/dto/item-queue.dto.ts new file mode 100644 index 0000000..cb1406c --- /dev/null +++ b/src/modules/item-related/item-queue/infrastructure/dto/item-queue.dto.ts @@ -0,0 +1,32 @@ +import { BaseStatusDto } from 'src/core/modules/infrastructure/dto/base-status.dto'; +import { ItemQueueEntity } from '../../domain/entities/item-queue.entity'; +import { IsArray, IsString } from 'class-validator'; +import { ItemType } from '../../constants'; +import { ApiProperty } from '@nestjs/swagger'; +import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity'; +import { Exclude, Transform } from 'class-transformer'; + +export class ItemQueueDto extends BaseStatusDto implements ItemQueueEntity { + @Exclude() + items: ItemEntity[]; + + @ApiProperty({ name: 'name', required: true, example: 'Bundling w Entrance' }) + @IsString() + name: string; + + @ApiProperty({ + type: 'string', + required: true, + description: `Select (${JSON.stringify(Object.values(ItemType))})`, + example: ItemType.BUNDLING, + }) + item_type: ItemType; + + @ApiProperty({ type: [String], required: true }) + @Transform((body) => { + return Array.isArray(body.value) ? body.value : [body.value]; + }) + @IsArray() + @IsString({ each: true }) + item_ids: string[]; +} diff --git a/src/modules/item-related/item-queue/infrastructure/item-queue-data.controller.ts b/src/modules/item-related/item-queue/infrastructure/item-queue-data.controller.ts new file mode 100644 index 0000000..2639a8f --- /dev/null +++ b/src/modules/item-related/item-queue/infrastructure/item-queue-data.controller.ts @@ -0,0 +1,78 @@ +import { + Body, + Controller, + Delete, + Param, + Patch, + Post, + Put, +} from '@nestjs/common'; +import { ItemQueueDataOrchestrator } from '../domain/usecases/item-queue-data.orchestrator'; +import { ItemQueueDto } from './dto/item-queue.dto'; +import { MODULE_NAME } from 'src/core/strings/constants/module.constants'; +import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; +import { ItemQueueEntity } from '../domain/entities/item-queue.entity'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { BatchIdsDto } from 'src/core/modules/infrastructure/dto/base-batch.dto'; +import { Public } from 'src/core/guards'; + +@ApiTags(`${MODULE_NAME.ITEM_QUEUE.split('-').join(' ')} - data`) +@Controller(`v1/${MODULE_NAME.ITEM_QUEUE}`) +@Public(false) +@ApiBearerAuth('JWT') +export class ItemQueueDataController { + constructor(private orchestrator: ItemQueueDataOrchestrator) {} + + @Post() + async create(@Body() data: ItemQueueDto): Promise { + return await this.orchestrator.create(data); + } + + @Put('/batch-delete') + async batchDeleted(@Body() body: BatchIdsDto): Promise { + return await this.orchestrator.batchDelete(body.ids); + } + + @Patch(':id/active') + async active(@Param('id') dataId: string): Promise { + return await this.orchestrator.active(dataId); + } + + @Put('/batch-active') + async batchActive(@Body() body: BatchIdsDto): Promise { + return await this.orchestrator.batchActive(body.ids); + } + + @Patch(':id/confirm') + async confirm(@Param('id') dataId: string): Promise { + return await this.orchestrator.confirm(dataId); + } + + @Put('/batch-confirm') + async batchConfirm(@Body() body: BatchIdsDto): Promise { + return await this.orchestrator.batchConfirm(body.ids); + } + + @Patch(':id/inactive') + async inactive(@Param('id') dataId: string): Promise { + return await this.orchestrator.inactive(dataId); + } + + @Put('/batch-inactive') + async batchInactive(@Body() body: BatchIdsDto): Promise { + return await this.orchestrator.batchInactive(body.ids); + } + + @Put(':id') + async update( + @Param('id') dataId: string, + @Body() data: ItemQueueDto, + ): Promise { + return await this.orchestrator.update(dataId, data); + } + + @Delete(':id') + async delete(@Param('id') dataId: string): Promise { + return await this.orchestrator.delete(dataId); + } +} diff --git a/src/modules/item-related/item-queue/infrastructure/item-queue-read.controller.ts b/src/modules/item-related/item-queue/infrastructure/item-queue-read.controller.ts new file mode 100644 index 0000000..54490f7 --- /dev/null +++ b/src/modules/item-related/item-queue/infrastructure/item-queue-read.controller.ts @@ -0,0 +1,30 @@ +import { Controller, Get, Param, Query } from '@nestjs/common'; +import { FilterItemQueueDto } from './dto/filter-item-queue.dto'; +import { Pagination } from 'src/core/response'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { ItemQueueEntity } from '../domain/entities/item-queue.entity'; +import { ItemQueueReadOrchestrator } from '../domain/usecases/item-queue-read.orchestrator'; +import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; +import { MODULE_NAME } from 'src/core/strings/constants/module.constants'; +import { Public } from 'src/core/guards'; + +@ApiTags(`${MODULE_NAME.ITEM_QUEUE.split('-').join(' ')} - read`) +@Controller(`v1/${MODULE_NAME.ITEM_QUEUE}`) +@Public(false) +@ApiBearerAuth('JWT') +export class ItemQueueReadController { + constructor(private orchestrator: ItemQueueReadOrchestrator) {} + + @Get() + @Pagination() + async index( + @Query() params: FilterItemQueueDto, + ): Promise> { + return await this.orchestrator.index(params); + } + + @Get(':id') + async detail(@Param('id') id: string): Promise { + return await this.orchestrator.detail(id); + } +} diff --git a/src/modules/item-related/item-queue/item-queue.module.ts b/src/modules/item-related/item-queue/item-queue.module.ts new file mode 100644 index 0000000..c009f9f --- /dev/null +++ b/src/modules/item-related/item-queue/item-queue.module.ts @@ -0,0 +1,54 @@ +import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; +import { ItemQueueDataService } from './data/services/item-queue-data.service'; +import { ItemQueueReadService } from './data/services/item-queue-read.service'; +import { ItemQueueReadController } from './infrastructure/item-queue-read.controller'; +import { ItemQueueReadOrchestrator } from './domain/usecases/item-queue-read.orchestrator'; +import { ItemQueueDataController } from './infrastructure/item-queue-data.controller'; +import { ItemQueueDataOrchestrator } from './domain/usecases/item-queue-data.orchestrator'; +import { CreateItemQueueManager } from './domain/usecases/managers/create-item-queue.manager'; +import { CqrsModule } from '@nestjs/cqrs'; +import { IndexItemQueueManager } from './domain/usecases/managers/index-item-queue.manager'; +import { DeleteItemQueueManager } from './domain/usecases/managers/delete-item-queue.manager'; +import { UpdateItemQueueManager } from './domain/usecases/managers/update-item-queue.manager'; +import { ActiveItemQueueManager } from './domain/usecases/managers/active-item-queue.manager'; +import { ConfirmItemQueueManager } from './domain/usecases/managers/confirm-item-queue.manager'; +import { InactiveItemQueueManager } from './domain/usecases/managers/inactive-item-queue.manager'; +import { DetailItemQueueManager } from './domain/usecases/managers/detail-item-queue.manager'; +import { BatchDeleteItemQueueManager } from './domain/usecases/managers/batch-delete-item-queue.manager'; +import { BatchActiveItemQueueManager } from './domain/usecases/managers/batch-active-item-queue.manager'; +import { BatchConfirmItemQueueManager } from './domain/usecases/managers/batch-confirm-item-queue.manager'; +import { BatchInactiveItemQueueManager } from './domain/usecases/managers/batch-inactive-item-queue.manager'; +import { ItemQueueModel } from './data/models/item-queue.model'; + +@Module({ + imports: [ + ConfigModule.forRoot(), + TypeOrmModule.forFeature([ItemQueueModel], CONNECTION_NAME.DEFAULT), + CqrsModule, + ], + controllers: [ItemQueueDataController, ItemQueueReadController], + providers: [ + IndexItemQueueManager, + DetailItemQueueManager, + CreateItemQueueManager, + DeleteItemQueueManager, + UpdateItemQueueManager, + ActiveItemQueueManager, + ConfirmItemQueueManager, + InactiveItemQueueManager, + BatchDeleteItemQueueManager, + BatchActiveItemQueueManager, + BatchConfirmItemQueueManager, + BatchInactiveItemQueueManager, + + ItemQueueDataService, + ItemQueueReadService, + + ItemQueueDataOrchestrator, + ItemQueueReadOrchestrator, + ], +}) +export class ItemQueueModule {} diff --git a/src/modules/item-related/item/data/models/item.model.ts b/src/modules/item-related/item/data/models/item.model.ts index 7506733..14df792 100644 --- a/src/modules/item-related/item/data/models/item.model.ts +++ b/src/modules/item-related/item/data/models/item.model.ts @@ -16,6 +16,7 @@ import { ItemCategoryModel } from 'src/modules/item-related/item-category/data/m import { UserModel } from 'src/modules/user-related/user/data/models/user.model'; import { ItemRateModel } from 'src/modules/item-related/item-rate/data/models/item-rate.model'; import { GateModel } from 'src/modules/web-information/gate/data/models/gate.model'; +import { ItemQueueModel } from 'src/modules/item-related/item-queue/data/models/item-queue.model'; @Entity(TABLE_NAME.ITEM) export class ItemModel @@ -28,8 +29,8 @@ export class ItemModel @Column('varchar', { name: 'image_url', nullable: true }) image_url: string; - @Column('varchar', { nullable: true }) - video_url: string; + @Column('json', { nullable: true }) + video_url: string[]; @Column('enum', { name: 'item_type', @@ -85,6 +86,13 @@ export class ItemModel @JoinColumn({ name: 'item_category_id' }) item_category: ItemCategoryModel; + @ManyToOne(() => ItemQueueModel, (model) => model.items, { + onUpdate: 'CASCADE', + onDelete: 'CASCADE', + }) + @JoinColumn({ name: 'item_queue_id' }) + item_queue: ItemQueueModel; + // relation ke tenant // ? karena item bisajadi merupakan item dari tenant @Column('varchar', { name: 'tenant_id', nullable: true }) diff --git a/src/modules/item-related/item/domain/entities/item.entity.ts b/src/modules/item-related/item/domain/entities/item.entity.ts index 7ade51e..995b113 100644 --- a/src/modules/item-related/item/domain/entities/item.entity.ts +++ b/src/modules/item-related/item/domain/entities/item.entity.ts @@ -6,7 +6,7 @@ export interface ItemEntity extends BaseStatusEntity { name: string; item_type: ItemType; image_url: string; - video_url?: string; + video_url?: string[]; hpp: number; sales_margin: number; diff --git a/src/modules/item-related/item/infrastructure/dto/item.dto.ts b/src/modules/item-related/item/infrastructure/dto/item.dto.ts index c6f739e..c1add0f 100644 --- a/src/modules/item-related/item/infrastructure/dto/item.dto.ts +++ b/src/modules/item-related/item/infrastructure/dto/item.dto.ts @@ -12,6 +12,7 @@ import { ValidateIf, } from 'class-validator'; import { ItemCategoryEntity } from 'src/modules/item-related/item-category/domain/entities/item-category.entity'; +import { Transform } from 'class-transformer'; export class ItemDto extends BaseStatusDto implements ItemEntity { @ApiProperty({ @@ -32,13 +33,16 @@ export class ItemDto extends BaseStatusDto implements ItemEntity { image_url: string; @ApiProperty({ - type: String, + isArray: true, required: false, - example: '...', }) - @IsString() + // @IsString() @ValidateIf((body) => body.video_url) - video_url: string; + @Transform(({ value }) => { + if (!value) return []; + return Array.isArray(value) ? value : [value]; + }) + video_url: string[]; @ApiProperty({ type: 'string',