From 3b362d2822986ce3f914fe2aae7cab2ecfce04ad Mon Sep 17 00:00:00 2001 From: Firman Ramdhani <33869609+firmanramdhani@users.noreply.github.com> Date: Wed, 28 May 2025 14:52:26 +0700 Subject: [PATCH] feat: crete API CRUD feature time group --- src/app.module.ts | 4 + .../strings/constants/module.constants.ts | 2 + src/core/strings/constants/table.constants.ts | 2 + .../1748409891706-create-time-group-table.ts | 27 ++++ .../item/data/models/item.model.ts | 12 ++ .../data/models/time-group.model.ts | 29 +++++ .../data/services/time-group-data.service.ts | 17 +++ .../data/services/time-group-read.service.ts | 17 +++ .../event/time-group-change-status.event.ts | 5 + .../event/time-group-created.event.ts | 5 + .../event/time-group-deleted.event.ts | 5 + .../event/time-group-updated.event.ts | 5 + .../entities/filter-time-group.entity.ts | 11 ++ .../domain/entities/time-group.entity.ts | 8 ++ .../managers/active-time-group.manager.ts | 45 +++++++ .../batch-active-time-group.manager.ts | 45 +++++++ .../batch-confirm-time-group.manager.ts | 45 +++++++ .../batch-delete-time-group.manager.ts | 51 ++++++++ .../batch-inactive-time-group.manager.ts | 51 ++++++++ .../managers/confirm-time-group.manager.ts | 45 +++++++ .../managers/create-time-group.manager.ts | 75 +++++++++++ .../managers/delete-time-group.manager.ts | 51 ++++++++ .../managers/detail-time-group.manager.ts | 48 +++++++ .../managers/inactive-time-group.manager.ts | 51 ++++++++ .../managers/index-time-group.manager.ts | 64 ++++++++++ .../managers/update-time-group.manager.ts | 75 +++++++++++ .../usecases/time-group-data.orchestrator.ts | 119 ++++++++++++++++++ .../usecases/time-group-read.orchestrator.ts | 33 +++++ .../dto/filter-time-group.dto.ts | 33 +++++ .../infrastructure/dto/time-group.dto.ts | 47 +++++++ .../time-group-data.controller.ts | 78 ++++++++++++ .../time-group-read.controller.ts | 30 +++++ .../time-group/time-group.module.ts | 54 ++++++++ 33 files changed, 1189 insertions(+) create mode 100644 src/database/migrations/1748409891706-create-time-group-table.ts create mode 100644 src/modules/item-related/time-group/data/models/time-group.model.ts create mode 100644 src/modules/item-related/time-group/data/services/time-group-data.service.ts create mode 100644 src/modules/item-related/time-group/data/services/time-group-read.service.ts create mode 100644 src/modules/item-related/time-group/domain/entities/event/time-group-change-status.event.ts create mode 100644 src/modules/item-related/time-group/domain/entities/event/time-group-created.event.ts create mode 100644 src/modules/item-related/time-group/domain/entities/event/time-group-deleted.event.ts create mode 100644 src/modules/item-related/time-group/domain/entities/event/time-group-updated.event.ts create mode 100644 src/modules/item-related/time-group/domain/entities/filter-time-group.entity.ts create mode 100644 src/modules/item-related/time-group/domain/entities/time-group.entity.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/active-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/batch-active-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/batch-confirm-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/batch-delete-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/batch-inactive-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/confirm-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/create-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/delete-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/detail-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/inactive-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/index-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/managers/update-time-group.manager.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/time-group-data.orchestrator.ts create mode 100644 src/modules/item-related/time-group/domain/usecases/time-group-read.orchestrator.ts create mode 100644 src/modules/item-related/time-group/infrastructure/dto/filter-time-group.dto.ts create mode 100644 src/modules/item-related/time-group/infrastructure/dto/time-group.dto.ts create mode 100644 src/modules/item-related/time-group/infrastructure/time-group-data.controller.ts create mode 100644 src/modules/item-related/time-group/infrastructure/time-group-read.controller.ts create mode 100644 src/modules/item-related/time-group/time-group.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index 5266aa2..6bb3641 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -99,6 +99,8 @@ import { QueueBucketModel } from './modules/queue/data/models/queue-bucket.model import { VerificationModel } from './modules/booking-online/authentication/data/models/verification.model'; import { BookingOnlineAuthModule } from './modules/booking-online/authentication/auth.module'; import { BookingOrderModule } from './modules/booking-online/order/order.module'; +import { TimeGroupModule } from './modules/item-related/time-group/time-group.module'; +import { TimeGroupModel } from './modules/item-related/time-group/data/models/time-group.model'; @Module({ imports: [ ApmModule.register(), @@ -123,6 +125,7 @@ import { BookingOrderModule } from './modules/booking-online/order/order.module' ItemCategoryModel, ItemRateModel, ItemQueueModel, + TimeGroupModel, LogModel, LogUserLoginModel, NewsModel, @@ -188,6 +191,7 @@ import { BookingOrderModule } from './modules/booking-online/order/order.module' ItemModule, ItemRateModule, ItemQueueModule, + TimeGroupModule, // transaction PaymentMethodModule, diff --git a/src/core/strings/constants/module.constants.ts b/src/core/strings/constants/module.constants.ts index b05838e..032dace 100644 --- a/src/core/strings/constants/module.constants.ts +++ b/src/core/strings/constants/module.constants.ts @@ -28,4 +28,6 @@ export enum MODULE_NAME { REPORT_SUMMARY = 'report-summary', QUEUE = 'queue', + + TIME_GROUPS = 'time-groups', } diff --git a/src/core/strings/constants/table.constants.ts b/src/core/strings/constants/table.constants.ts index 4725e10..dcdc1a3 100644 --- a/src/core/strings/constants/table.constants.ts +++ b/src/core/strings/constants/table.constants.ts @@ -43,4 +43,6 @@ export enum TABLE_NAME { QUEUE_TICKET = 'queue_tickets', QUEUE_ITEM = 'queue_items', QUEUE_BUCKET = 'queue_bucket', + + TIME_GROUPS = 'time_groups', } diff --git a/src/database/migrations/1748409891706-create-time-group-table.ts b/src/database/migrations/1748409891706-create-time-group-table.ts new file mode 100644 index 0000000..5c83f84 --- /dev/null +++ b/src/database/migrations/1748409891706-create-time-group-table.ts @@ -0,0 +1,27 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class CreateTimeGroupTable1748409891706 implements MigrationInterface { + name = 'CreateTimeGroupTable1748409891706'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."time_groups_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`, + ); + await queryRunner.query( + `CREATE TABLE "time_groups" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."time_groups_status_enum" NOT NULL DEFAULT 'draft', "name" character varying NOT NULL, "start_time" TIME NOT NULL, "end_time" TIME NOT NULL, "max_usage_time" TIME NOT NULL, CONSTRAINT "PK_083d02988db7bedfe3b7c869b50" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "items" ADD "time_group_id" uuid`); + await queryRunner.query( + `ALTER TABLE "items" ADD CONSTRAINT "FK_f44f222e1808448dca1b6cc4557" FOREIGN KEY ("time_group_id") REFERENCES "time_groups"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "items" DROP CONSTRAINT "FK_f44f222e1808448dca1b6cc4557"`, + ); + await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "time_group_id"`); + await queryRunner.query(`DROP TABLE "time_groups"`); + await queryRunner.query(`DROP TYPE "public"."time_groups_status_enum"`); + } +} 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 62e9c83..b565c4d 100644 --- a/src/modules/item-related/item/data/models/item.model.ts +++ b/src/modules/item-related/item/data/models/item.model.ts @@ -17,6 +17,7 @@ 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'; +import { TimeGroupModel } from 'src/modules/item-related/time-group/data/models/time-group.model'; @Entity(TABLE_NAME.ITEM) export class ItemModel @@ -86,6 +87,17 @@ export class ItemModel @JoinColumn({ name: 'item_category_id' }) item_category: ItemCategoryModel; + // start relation to time group + @Column('varchar', { name: 'time_group_id', nullable: true }) + time_group_id: number; + @ManyToOne(() => TimeGroupModel, (model) => model.items, { + onUpdate: 'CASCADE', + onDelete: 'CASCADE', + }) + @JoinColumn({ name: 'time_group_id' }) + time_group: TimeGroupModel; + // end relation to time group + @ManyToOne(() => ItemQueueModel, (model) => model.items, { onUpdate: 'CASCADE', onDelete: 'SET NULL', diff --git a/src/modules/item-related/time-group/data/models/time-group.model.ts b/src/modules/item-related/time-group/data/models/time-group.model.ts new file mode 100644 index 0000000..e4332e0 --- /dev/null +++ b/src/modules/item-related/time-group/data/models/time-group.model.ts @@ -0,0 +1,29 @@ +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; +import { TimeGroupEntity } from '../../domain/entities/time-group.entity'; +import { Column, Entity, OneToMany } from 'typeorm'; +import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model'; +import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; + +@Entity(TABLE_NAME.TIME_GROUPS) +export class TimeGroupModel + extends BaseStatusModel + implements TimeGroupEntity +{ + @Column('varchar', { name: 'name' }) + name: string; + + @Column({ type: 'time' }) + start_time: string; + + @Column({ type: 'time' }) + end_time: string; + + @Column({ type: 'time' }) + max_usage_time: string; + + @OneToMany(() => ItemModel, (model) => model.time_group, { + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + }) + items: ItemModel[]; +} diff --git a/src/modules/item-related/time-group/data/services/time-group-data.service.ts b/src/modules/item-related/time-group/data/services/time-group-data.service.ts new file mode 100644 index 0000000..823d81a --- /dev/null +++ b/src/modules/item-related/time-group/data/services/time-group-data.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; +import { TimeGroupEntity } from '../../domain/entities/time-group.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { TimeGroupModel } from '../models/time-group.model'; +import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; +import { Repository } from 'typeorm'; + +@Injectable() +export class TimeGroupDataService extends BaseDataService { + constructor( + @InjectRepository(TimeGroupModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/item-related/time-group/data/services/time-group-read.service.ts b/src/modules/item-related/time-group/data/services/time-group-read.service.ts new file mode 100644 index 0000000..a528bd3 --- /dev/null +++ b/src/modules/item-related/time-group/data/services/time-group-read.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { TimeGroupEntity } from '../../domain/entities/time-group.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { TimeGroupModel } from '../models/time-group.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 TimeGroupReadService extends BaseReadService { + constructor( + @InjectRepository(TimeGroupModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/item-related/time-group/domain/entities/event/time-group-change-status.event.ts b/src/modules/item-related/time-group/domain/entities/event/time-group-change-status.event.ts new file mode 100644 index 0000000..4aa911f --- /dev/null +++ b/src/modules/item-related/time-group/domain/entities/event/time-group-change-status.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class TimeGroupChangeStatusEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/item-related/time-group/domain/entities/event/time-group-created.event.ts b/src/modules/item-related/time-group/domain/entities/event/time-group-created.event.ts new file mode 100644 index 0000000..27c35a0 --- /dev/null +++ b/src/modules/item-related/time-group/domain/entities/event/time-group-created.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class TimeGroupCreatedEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/item-related/time-group/domain/entities/event/time-group-deleted.event.ts b/src/modules/item-related/time-group/domain/entities/event/time-group-deleted.event.ts new file mode 100644 index 0000000..a1f8030 --- /dev/null +++ b/src/modules/item-related/time-group/domain/entities/event/time-group-deleted.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class TimeGroupDeletedEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/item-related/time-group/domain/entities/event/time-group-updated.event.ts b/src/modules/item-related/time-group/domain/entities/event/time-group-updated.event.ts new file mode 100644 index 0000000..21d9c80 --- /dev/null +++ b/src/modules/item-related/time-group/domain/entities/event/time-group-updated.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class TimeGroupUpdatedEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/item-related/time-group/domain/entities/filter-time-group.entity.ts b/src/modules/item-related/time-group/domain/entities/filter-time-group.entity.ts new file mode 100644 index 0000000..c286d7c --- /dev/null +++ b/src/modules/item-related/time-group/domain/entities/filter-time-group.entity.ts @@ -0,0 +1,11 @@ +import { BaseFilterEntity } from 'src/core/modules/domain/entities/base-filter.entity'; + +export interface FilterITimeGroupEntity extends BaseFilterEntity { + names: string[]; + start_time_from: string; + start_time_to: string; + end_time_from: string; + end_time_to: string; + max_usage_time_from: string; + max_usage_time_to: string; +} diff --git a/src/modules/item-related/time-group/domain/entities/time-group.entity.ts b/src/modules/item-related/time-group/domain/entities/time-group.entity.ts new file mode 100644 index 0000000..7281552 --- /dev/null +++ b/src/modules/item-related/time-group/domain/entities/time-group.entity.ts @@ -0,0 +1,8 @@ +import { BaseStatusEntity } from 'src/core/modules/domain/entities/base-status.entity'; + +export interface TimeGroupEntity extends BaseStatusEntity { + name: string; + start_time: string; + end_time: string; + max_usage_time: string; +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/active-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/active-time-group.manager.ts new file mode 100644 index 0000000..6f3e3e7 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/active-time-group.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 { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupChangeStatusEvent } from '../../entities/event/time-group-change-status.event'; + +@Injectable() +export class ActiveTimeGroupManager 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 TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupChangeStatusEvent, + data: this.data, + }, + ]; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/batch-active-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/batch-active-time-group.manager.ts new file mode 100644 index 0000000..464c346 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/batch-active-time-group.manager.ts @@ -0,0 +1,45 @@ +import { BaseBatchUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-batch-update-status.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupChangeStatusEvent } from '../../entities/event/time-group-change-status.event'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchActiveTimeGroupManager extends BaseBatchUpdateStatusManager { + validateData(data: TimeGroupEntity): Promise { + return; + } + + beforeProcess(): Promise { + return; + } + + afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupChangeStatusEvent, + }, + ]; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/batch-confirm-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/batch-confirm-time-group.manager.ts new file mode 100644 index 0000000..2d2482c --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/batch-confirm-time-group.manager.ts @@ -0,0 +1,45 @@ +import { BaseBatchUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-batch-update-status.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupChangeStatusEvent } from '../../entities/event/time-group-change-status.event'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchConfirmTimeGroupManager extends BaseBatchUpdateStatusManager { + validateData(data: TimeGroupEntity): Promise { + return; + } + + beforeProcess(): Promise { + return; + } + + afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupChangeStatusEvent, + }, + ]; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/batch-delete-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/batch-delete-time-group.manager.ts new file mode 100644 index 0000000..95bb85b --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/batch-delete-time-group.manager.ts @@ -0,0 +1,51 @@ +import { BaseBatchDeleteManager } from 'src/core/modules/domain/usecase/managers/base-batch-delete.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupDeletedEvent } from '../../entities/event/time-group-deleted.event'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchDeleteTimeGroupManager extends BaseBatchDeleteManager { + async beforeProcess(): Promise { + return; + } + + async validateData(data: TimeGroupEntity): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return [ + { + relation: 'items', + message: + 'Gagal! tidak dapat menghapus time group karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupDeletedEvent, + }, + ]; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/batch-inactive-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/batch-inactive-time-group.manager.ts new file mode 100644 index 0000000..ecb437f --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/batch-inactive-time-group.manager.ts @@ -0,0 +1,51 @@ +import { BaseBatchUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-batch-update-status.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupChangeStatusEvent } from '../../entities/event/time-group-change-status.event'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchInactiveTimeGroupManager extends BaseBatchUpdateStatusManager { + validateData(data: TimeGroupEntity): Promise { + return; + } + + beforeProcess(): Promise { + return; + } + + afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return [ + { + relation: 'items', + message: + 'Gagal! tidak dapat mengubah status time group karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupChangeStatusEvent, + }, + ]; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/confirm-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/confirm-time-group.manager.ts new file mode 100644 index 0000000..76e207f --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/confirm-time-group.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 { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupChangeStatusEvent } from '../../entities/event/time-group-change-status.event'; + +@Injectable() +export class ConfirmTimeGroupManager 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 TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupChangeStatusEvent, + data: this.data, + }, + ]; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/create-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/create-time-group.manager.ts new file mode 100644 index 0000000..efa3885 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/create-time-group.manager.ts @@ -0,0 +1,75 @@ +import { Injectable } from '@nestjs/common'; +import { + EventTopics, + columnUniques, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager'; +import { TimeGroupCreatedEvent } from '../../entities/event/time-group-created.event'; +import * as moment from 'moment'; + +@Injectable() +export class CreateTimeGroupManager extends BaseCreateManager { + async beforeProcess(): Promise { + const queryBuilder = this.dataService + .getRepository() + .createQueryBuilder(this.tableName); + + const overlapping = await queryBuilder + .where(`${this.tableName}.start_time <= :end_time`, { + end_time: this.data.end_time, + }) + .andWhere(`${this.tableName}.end_time >= :start_time`, { + start_time: this.data.start_time, + }) + .getOne(); + + if (overlapping) { + throw new Error( + 'Rentang waktu yang dimasukkan beririsan dengan data lain.', + ); + } else if (this.data.max_usage_time) { + const format = 'HH:mm'; + const end_time = moment(this.data.end_time, format); + const max_usage_time = moment(this.data.max_usage_time, format); + + if (max_usage_time.isBefore(end_time)) { + throw new Error( + 'Waktu maksimum penggunaan harus lebih kecil dari waktu selesai.', + ); + } + } + 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 [ + { + topic: TimeGroupCreatedEvent, + data: this.data, + }, + ]; + } + + get entityTarget(): any { + return TimeGroupModel; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/delete-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/delete-time-group.manager.ts new file mode 100644 index 0000000..5195904 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/delete-time-group.manager.ts @@ -0,0 +1,51 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDeleteManager } from 'src/core/modules/domain/usecase/managers/base-delete.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupDeletedEvent } from '../../entities/event/time-group-deleted.event'; + +@Injectable() +export class DeleteTimeGroupManager 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 menghapus time group karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupDeletedEvent, + data: this.data, + }, + ]; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/detail-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/detail-time-group.manager.ts new file mode 100644 index 0000000..c900594 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/detail-time-group.manager.ts @@ -0,0 +1,48 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDetailManager } from 'src/core/modules/domain/usecase/managers/base-detail.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity'; + +@Injectable() +export class DetailTimeGroupManager extends BaseDetailManager { + async prepareData(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get relations(): RelationParam { + return { + joinRelations: [], + selectRelations: [], + countRelations: [], + }; + } + + get selects(): string[] { + return [ + `${this.tableName}.id`, + `${this.tableName}.status`, + `${this.tableName}.name`, + `${this.tableName}.start_time`, + `${this.tableName}.end_time`, + `${this.tableName}.max_usage_time`, + `${this.tableName}.created_at`, + `${this.tableName}.creator_name`, + `${this.tableName}.updated_at`, + `${this.tableName}.editor_name`, + ]; + } + + get setFindProperties(): any { + return { + id: this.dataId, + }; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/inactive-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/inactive-time-group.manager.ts new file mode 100644 index 0000000..d6dca30 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/inactive-time-group.manager.ts @@ -0,0 +1,51 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateStatusManager } from 'src/core/modules/domain/usecase/managers/base-update-status.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupChangeStatusEvent } from '../../entities/event/time-group-change-status.event'; + +@Injectable() +export class InactiveTimeGroupManager 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 status time group karena sudah berelasi dengan item', + }, + ]; + } + + get entityTarget(): any { + return TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupChangeStatusEvent, + data: this.data, + }, + ]; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/index-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/index-time-group.manager.ts new file mode 100644 index 0000000..3ffdd56 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/index-time-group.manager.ts @@ -0,0 +1,64 @@ +import { Injectable } from '@nestjs/common'; +import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { SelectQueryBuilder } from 'typeorm'; +import { + Param, + RelationParam, +} from 'src/core/modules/domain/entities/base-filter.entity'; + +// TODO: +// Implementasikan filter by start_time, end_timen, dan max_usage_time + +@Injectable() +export class IndexTimeGroupManager extends BaseIndexManager { + async prepareData(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get relations(): RelationParam { + return { + joinRelations: [], + selectRelations: [], + countRelations: [], + }; + } + + get selects(): string[] { + return [ + `${this.tableName}.id`, + `${this.tableName}.status`, + `${this.tableName}.name`, + `${this.tableName}.start_time`, + `${this.tableName}.end_time`, + `${this.tableName}.max_usage_time`, + `${this.tableName}.created_at`, + `${this.tableName}.creator_name`, + `${this.tableName}.updated_at`, + `${this.tableName}.editor_name`, + ]; + } + + get specificFilter(): Param[] { + return [ + { + cols: `${this.tableName}.name`, + data: this.filterParam.names, + }, + ]; + } + + setQueryFilter( + queryBuilder: SelectQueryBuilder, + ): SelectQueryBuilder { + return queryBuilder; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/managers/update-time-group.manager.ts b/src/modules/item-related/time-group/domain/usecases/managers/update-time-group.manager.ts new file mode 100644 index 0000000..399130a --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/managers/update-time-group.manager.ts @@ -0,0 +1,75 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateManager } from 'src/core/modules/domain/usecase/managers/base-update.manager'; +import { TimeGroupEntity } from '../../entities/time-group.entity'; +import { TimeGroupModel } from '../../../data/models/time-group.model'; +import { TimeGroupUpdatedEvent } from '../../entities/event/time-group-updated.event'; +import { + EventTopics, + columnUniques, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import * as moment from 'moment'; + +@Injectable() +export class UpdateTimeGroupManager extends BaseUpdateManager { + async validateProcess(): Promise { + const queryBuilder = this.dataService + .getRepository() + .createQueryBuilder(this.tableName); + + const overlapping = await queryBuilder + .where(`${this.tableName}.start_time <= :end_time`, { + end_time: this.data.end_time, + }) + .andWhere(`${this.tableName}.end_time >= :start_time`, { + start_time: this.data.start_time, + }) + .andWhere(`${this.tableName}.id != :id`, { id: this.dataId ?? null }) + .getOne(); + + if (overlapping) { + throw new Error( + 'Rentang waktu yang dimasukkan beririsan dengan data lain.', + ); + } else if (this.data.max_usage_time) { + const format = 'HH:mm'; + const end_time = moment(this.data.end_time, format); + const max_usage_time = moment(this.data.max_usage_time, format); + + if (max_usage_time.isBefore(end_time)) { + throw new Error( + 'Waktu maksimum penggunaan harus lebih kecil dari waktu selesai.', + ); + } + } + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get uniqueColumns(): columnUniques[] { + return [{ column: 'name' }]; + } + + get entityTarget(): any { + return TimeGroupModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: TimeGroupUpdatedEvent, + }, + ]; + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/time-group-data.orchestrator.ts b/src/modules/item-related/time-group/domain/usecases/time-group-data.orchestrator.ts new file mode 100644 index 0000000..d474676 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/time-group-data.orchestrator.ts @@ -0,0 +1,119 @@ +import { Injectable } from '@nestjs/common'; +import { CreateTimeGroupManager } from './managers/create-time-group.manager'; +import { TimeGroupDataService } from '../../data/services/time-group-data.service'; +import { TimeGroupEntity } from '../entities/time-group.entity'; +import { DeleteTimeGroupManager } from './managers/delete-time-group.manager'; +import { UpdateTimeGroupManager } from './managers/update-time-group.manager'; +import { BaseDataTransactionOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-data-transaction.orchestrator'; +import { ActiveTimeGroupManager } from './managers/active-time-group.manager'; +import { InactiveTimeGroupManager } from './managers/inactive-time-group.manager'; +import { ConfirmTimeGroupManager } from './managers/confirm-time-group.manager'; +import { STATUS } from 'src/core/strings/constants/base.constants'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { BatchConfirmTimeGroupManager } from './managers/batch-confirm-time-group.manager'; +import { BatchInactiveTimeGroupManager } from './managers/batch-inactive-time-group.manager'; +import { BatchActiveTimeGroupManager } from './managers/batch-active-time-group.manager'; +import { BatchDeleteTimeGroupManager } from './managers/batch-delete-time-group.manager'; +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; + +@Injectable() +export class TimeGroupDataOrchestrator extends BaseDataTransactionOrchestrator { + constructor( + private createManager: CreateTimeGroupManager, + private updateManager: UpdateTimeGroupManager, + private deleteManager: DeleteTimeGroupManager, + private activeManager: ActiveTimeGroupManager, + private confirmManager: ConfirmTimeGroupManager, + private inactiveManager: InactiveTimeGroupManager, + private batchDeleteManager: BatchDeleteTimeGroupManager, + private batchActiveManager: BatchActiveTimeGroupManager, + private batchConfirmManager: BatchConfirmTimeGroupManager, + private batchInactiveManager: BatchInactiveTimeGroupManager, + private serviceData: TimeGroupDataService, + ) { + super(); + } + + async create(data): Promise { + this.createManager.setData(data); + this.createManager.setService(this.serviceData, TABLE_NAME.TIME_GROUPS); + 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.TIME_GROUPS); + await this.updateManager.execute(); + return this.updateManager.getResult(); + } + + async delete(dataId): Promise { + this.deleteManager.setData(dataId); + this.deleteManager.setService(this.serviceData, TABLE_NAME.TIME_GROUPS); + await this.deleteManager.execute(); + return this.deleteManager.getResult(); + } + + async batchDelete(dataIds: string[]): Promise { + this.batchDeleteManager.setData(dataIds); + this.batchDeleteManager.setService( + this.serviceData, + TABLE_NAME.TIME_GROUPS, + ); + 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.TIME_GROUPS); + 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.TIME_GROUPS, + ); + 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.TIME_GROUPS); + 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.TIME_GROUPS, + ); + 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.TIME_GROUPS); + 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.TIME_GROUPS, + ); + await this.batchInactiveManager.execute(); + return this.batchInactiveManager.getResult(); + } +} diff --git a/src/modules/item-related/time-group/domain/usecases/time-group-read.orchestrator.ts b/src/modules/item-related/time-group/domain/usecases/time-group-read.orchestrator.ts new file mode 100644 index 0000000..aa6b6e3 --- /dev/null +++ b/src/modules/item-related/time-group/domain/usecases/time-group-read.orchestrator.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; +import { IndexTimeGroupManager } from './managers/index-time-group.manager'; +import { TimeGroupReadService } from '../../data/services/time-group-read.service'; +import { TimeGroupEntity } from '../entities/time-group.entity'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { BaseReadOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-read.orchestrator'; +import { DetailTimeGroupManager } from './managers/detail-time-group.manager'; +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; + +@Injectable() +export class TimeGroupReadOrchestrator extends BaseReadOrchestrator { + constructor( + private indexManager: IndexTimeGroupManager, + private detailManager: DetailTimeGroupManager, + private serviceData: TimeGroupReadService, + ) { + super(); + } + + async index(params): Promise> { + this.indexManager.setFilterParam(params); + this.indexManager.setService(this.serviceData, TABLE_NAME.TIME_GROUPS); + await this.indexManager.execute(); + return this.indexManager.getResult(); + } + + async detail(dataId: string): Promise { + this.detailManager.setData(dataId); + this.detailManager.setService(this.serviceData, TABLE_NAME.TIME_GROUPS); + await this.detailManager.execute(); + return this.detailManager.getResult(); + } +} diff --git a/src/modules/item-related/time-group/infrastructure/dto/filter-time-group.dto.ts b/src/modules/item-related/time-group/infrastructure/dto/filter-time-group.dto.ts new file mode 100644 index 0000000..b4b6cd9 --- /dev/null +++ b/src/modules/item-related/time-group/infrastructure/dto/filter-time-group.dto.ts @@ -0,0 +1,33 @@ +import { BaseFilterDto } from 'src/core/modules/infrastructure/dto/base-filter.dto'; +import { FilterITimeGroupEntity } from '../../domain/entities/filter-time-group.entity'; +import { ApiProperty } from '@nestjs/swagger'; +import { ValidateIf } from 'class-validator'; + +export class FilterTimeGroupDto + extends BaseFilterDto + implements FilterITimeGroupEntity +{ + @ApiProperty({ type: 'string', required: false }) + @ValidateIf((body) => body.start_time_from) + start_time_from: string; + + @ApiProperty({ type: 'string', required: false }) + @ValidateIf((body) => body.start_time_to) + start_time_to: string; + + @ApiProperty({ type: 'string', required: false }) + @ValidateIf((body) => body.end_time_from) + end_time_from: string; + + @ApiProperty({ type: 'string', required: false }) + @ValidateIf((body) => body.end_time_to) + end_time_to: string; + + @ApiProperty({ type: 'string', required: false }) + @ValidateIf((body) => body.max_usage_time_from) + max_usage_time_from: string; + + @ApiProperty({ type: 'string', required: false }) + @ValidateIf((body) => body.max_usage_time_to) + max_usage_time_to: string; +} diff --git a/src/modules/item-related/time-group/infrastructure/dto/time-group.dto.ts b/src/modules/item-related/time-group/infrastructure/dto/time-group.dto.ts new file mode 100644 index 0000000..f7a5bd9 --- /dev/null +++ b/src/modules/item-related/time-group/infrastructure/dto/time-group.dto.ts @@ -0,0 +1,47 @@ +import { BaseStatusDto } from 'src/core/modules/infrastructure/dto/base-status.dto'; +import { TimeGroupEntity } from '../../domain/entities/time-group.entity'; +import { IsString, ValidateIf } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateTimeGroupDto + extends BaseStatusDto + implements TimeGroupEntity +{ + @ApiProperty({ name: 'name', required: true, example: 'Morning' }) + @IsString() + name: string; + + @ApiProperty({ name: 'start_time', required: true, example: '09:00' }) + @IsString() + start_time: string; + + @ApiProperty({ name: 'end_time', required: true, example: '10:00' }) + @IsString() + end_time: string; + + @ApiProperty({ name: 'max_usage_time', required: true, example: '10:30' }) + @IsString() + max_usage_time: string; +} + +export class EditTimeGroupDto extends BaseStatusDto implements TimeGroupEntity { + @ApiProperty({ name: 'name', example: 'Morning' }) + @IsString() + @ValidateIf((body) => body.name) + name: string; + + @ApiProperty({ name: 'start_time', example: '09:00' }) + @IsString() + @ValidateIf((body) => body.start_time) + start_time: string; + + @ApiProperty({ name: 'end_time', example: '10:00' }) + @IsString() + @ValidateIf((body) => body.end_time) + end_time: string; + + @ApiProperty({ name: 'max_usage_time', example: '10:30' }) + @IsString() + @ValidateIf((body) => body.max_usage_time) + max_usage_time: string; +} diff --git a/src/modules/item-related/time-group/infrastructure/time-group-data.controller.ts b/src/modules/item-related/time-group/infrastructure/time-group-data.controller.ts new file mode 100644 index 0000000..4de60fa --- /dev/null +++ b/src/modules/item-related/time-group/infrastructure/time-group-data.controller.ts @@ -0,0 +1,78 @@ +import { + Body, + Controller, + Delete, + Param, + Patch, + Post, + Put, +} from '@nestjs/common'; +import { TimeGroupDataOrchestrator } from '../domain/usecases/time-group-data.orchestrator'; +import { CreateTimeGroupDto, EditTimeGroupDto } from './dto/time-group.dto'; +import { MODULE_NAME } from 'src/core/strings/constants/module.constants'; +import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; +import { TimeGroupEntity } from '../domain/entities/time-group.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.TIME_GROUPS.split('-').join(' ')} - data`) +@Controller(`v1/${MODULE_NAME.TIME_GROUPS}`) +@Public(false) +@ApiBearerAuth('JWT') +export class TimeGroupDataController { + constructor(private orchestrator: TimeGroupDataOrchestrator) {} + + @Post() + async create(@Body() data: CreateTimeGroupDto): 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: EditTimeGroupDto, + ): 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/time-group/infrastructure/time-group-read.controller.ts b/src/modules/item-related/time-group/infrastructure/time-group-read.controller.ts new file mode 100644 index 0000000..212558d --- /dev/null +++ b/src/modules/item-related/time-group/infrastructure/time-group-read.controller.ts @@ -0,0 +1,30 @@ +import { Controller, Get, Param, Query } from '@nestjs/common'; +import { FilterTimeGroupDto } from './dto/filter-time-group.dto'; +import { Pagination } from 'src/core/response'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { TimeGroupEntity } from '../domain/entities/time-group.entity'; +import { TimeGroupReadOrchestrator } from '../domain/usecases/time-group-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.TIME_GROUPS.split('-').join(' ')} - read`) +@Controller(`v1/${MODULE_NAME.TIME_GROUPS}`) +@Public(false) +@ApiBearerAuth('JWT') +export class TimeGroupReadController { + constructor(private orchestrator: TimeGroupReadOrchestrator) {} + + @Get() + @Pagination() + async index( + @Query() params: FilterTimeGroupDto, + ): 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/time-group/time-group.module.ts b/src/modules/item-related/time-group/time-group.module.ts new file mode 100644 index 0000000..45455c0 --- /dev/null +++ b/src/modules/item-related/time-group/time-group.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 { TimeGroupDataService } from './data/services/time-group-data.service'; +import { TimeGroupReadService } from './data/services/time-group-read.service'; +import { TimeGroupReadController } from './infrastructure/time-group-read.controller'; +import { TimeGroupReadOrchestrator } from './domain/usecases/time-group-read.orchestrator'; +import { TimeGroupDataController } from './infrastructure/time-group-data.controller'; +import { TimeGroupDataOrchestrator } from './domain/usecases/time-group-data.orchestrator'; +import { CreateTimeGroupManager } from './domain/usecases/managers/create-time-group.manager'; +import { CqrsModule } from '@nestjs/cqrs'; +import { IndexTimeGroupManager } from './domain/usecases/managers/index-time-group.manager'; +import { DeleteTimeGroupManager } from './domain/usecases/managers/delete-time-group.manager'; +import { UpdateTimeGroupManager } from './domain/usecases/managers/update-time-group.manager'; +import { ActiveTimeGroupManager } from './domain/usecases/managers/active-time-group.manager'; +import { ConfirmTimeGroupManager } from './domain/usecases/managers/confirm-time-group.manager'; +import { InactiveTimeGroupManager } from './domain/usecases/managers/inactive-time-group.manager'; +import { DetailTimeGroupManager } from './domain/usecases/managers/detail-time-group.manager'; +import { BatchDeleteTimeGroupManager } from './domain/usecases/managers/batch-delete-time-group.manager'; +import { BatchActiveTimeGroupManager } from './domain/usecases/managers/batch-active-time-group.manager'; +import { BatchConfirmTimeGroupManager } from './domain/usecases/managers/batch-confirm-time-group.manager'; +import { BatchInactiveTimeGroupManager } from './domain/usecases/managers/batch-inactive-time-group.manager'; +import { TimeGroupModel } from './data/models/time-group.model'; + +@Module({ + imports: [ + ConfigModule.forRoot(), + TypeOrmModule.forFeature([TimeGroupModel], CONNECTION_NAME.DEFAULT), + CqrsModule, + ], + controllers: [TimeGroupDataController, TimeGroupReadController], + providers: [ + IndexTimeGroupManager, + DetailTimeGroupManager, + CreateTimeGroupManager, + DeleteTimeGroupManager, + UpdateTimeGroupManager, + ActiveTimeGroupManager, + ConfirmTimeGroupManager, + InactiveTimeGroupManager, + BatchDeleteTimeGroupManager, + BatchActiveTimeGroupManager, + BatchConfirmTimeGroupManager, + BatchInactiveTimeGroupManager, + + TimeGroupDataService, + TimeGroupReadService, + + TimeGroupDataOrchestrator, + TimeGroupReadOrchestrator, + ], +}) +export class TimeGroupModule {}