From 86f81f30278df3a3695d66709cd4786e7bdea5de Mon Sep 17 00:00:00 2001 From: ashar Date: Thu, 20 Jun 2024 01:47:56 +0700 Subject: [PATCH] feat(SPG-367) REST API CUD Item Rate --- .../migrations/1718792479432-item-rate.ts | 27 +++++++++ .../item-related/item-rate/constants.ts | 0 .../item-rate/data/models/item-rate.model.ts | 35 ++++++++++++ .../data/services/item-rate-data.service.ts | 17 ++++++ .../data/services/item-rate-read.service.ts | 17 ++++++ .../entities/event/item-rate-created.event.ts | 5 ++ .../entities/event/item-rate-deleted.event.ts | 5 ++ .../entities/event/item-rate-updated.event.ts | 5 ++ .../entities/filter-item-rate.entity.ts | 3 + .../domain/entities/item-rate.entity.ts | 7 +++ .../usecases/item-rate-data.orchestrator.ts | 52 ++++++++++++++++++ .../usecases/item-rate-read.orchestrator.ts | 33 +++++++++++ .../batch-delete-item-rate.manager.ts | 45 +++++++++++++++ .../managers/create-item-rate.manager.ts | 42 ++++++++++++++ .../managers/delete-item-rate.manager.ts | 45 +++++++++++++++ .../managers/detail-item-rate.manager.ts | 42 ++++++++++++++ .../managers/index-item-rate.manager.ts | 55 +++++++++++++++++++ .../managers/update-item-rate.manager.ts | 46 ++++++++++++++++ src/modules/item-related/item-rate/index.ts | 0 .../dto/filter-item-rate.dto.ts | 6 ++ .../infrastructure/dto/item-rate.dto.ts | 32 +++++++++++ .../item-rate-data.controller.ts | 40 ++++++++++++++ .../item-rate-read.controller.ts | 30 ++++++++++ .../item-rate/item-rate.module.ts | 42 ++++++++++++++ .../item/data/models/item.model.ts | 9 +++ .../domain/entities/filter-item.entity.ts | 1 + .../usecases/managers/index-item.manager.ts | 2 +- .../infrastructure/dto/filter-item.dto.ts | 7 +++ .../item/infrastructure/dto/item.dto.ts | 6 +- 29 files changed, 654 insertions(+), 2 deletions(-) create mode 100644 src/database/migrations/1718792479432-item-rate.ts create mode 100644 src/modules/item-related/item-rate/constants.ts create mode 100644 src/modules/item-related/item-rate/data/models/item-rate.model.ts create mode 100644 src/modules/item-related/item-rate/data/services/item-rate-data.service.ts create mode 100644 src/modules/item-related/item-rate/data/services/item-rate-read.service.ts create mode 100644 src/modules/item-related/item-rate/domain/entities/event/item-rate-created.event.ts create mode 100644 src/modules/item-related/item-rate/domain/entities/event/item-rate-deleted.event.ts create mode 100644 src/modules/item-related/item-rate/domain/entities/event/item-rate-updated.event.ts create mode 100644 src/modules/item-related/item-rate/domain/entities/filter-item-rate.entity.ts create mode 100644 src/modules/item-related/item-rate/domain/entities/item-rate.entity.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/item-rate-read.orchestrator.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/managers/batch-delete-item-rate.manager.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/managers/create-item-rate.manager.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/managers/delete-item-rate.manager.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/managers/detail-item-rate.manager.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/managers/index-item-rate.manager.ts create mode 100644 src/modules/item-related/item-rate/domain/usecases/managers/update-item-rate.manager.ts create mode 100644 src/modules/item-related/item-rate/index.ts create mode 100644 src/modules/item-related/item-rate/infrastructure/dto/filter-item-rate.dto.ts create mode 100644 src/modules/item-related/item-rate/infrastructure/dto/item-rate.dto.ts create mode 100644 src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts create mode 100644 src/modules/item-related/item-rate/infrastructure/item-rate-read.controller.ts create mode 100644 src/modules/item-related/item-rate/item-rate.module.ts diff --git a/src/database/migrations/1718792479432-item-rate.ts b/src/database/migrations/1718792479432-item-rate.ts new file mode 100644 index 0000000..5c97cb2 --- /dev/null +++ b/src/database/migrations/1718792479432-item-rate.ts @@ -0,0 +1,27 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class ItemRate1718792479432 implements MigrationInterface { + name = 'ItemRate1718792479432'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "item_rates" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "item_id" uuid, "season_period_id" uuid, "price" bigint, CONSTRAINT "PK_e3e0cf3b098409533dc20bf1992" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "item_rates" ADD CONSTRAINT "FK_2bff76c50f678bdf0c4f93990fc" FOREIGN KEY ("item_id") REFERENCES "items"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query( + `ALTER TABLE "item_rates" ADD CONSTRAINT "FK_d309461c7e5a7f83ca596203afa" FOREIGN KEY ("season_period_id") REFERENCES "season_periods"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "item_rates" DROP CONSTRAINT "FK_d309461c7e5a7f83ca596203afa"`, + ); + await queryRunner.query( + `ALTER TABLE "item_rates" DROP CONSTRAINT "FK_2bff76c50f678bdf0c4f93990fc"`, + ); + await queryRunner.query(`DROP TABLE "item_rates"`); + } +} diff --git a/src/modules/item-related/item-rate/constants.ts b/src/modules/item-related/item-rate/constants.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/modules/item-related/item-rate/data/models/item-rate.model.ts b/src/modules/item-related/item-rate/data/models/item-rate.model.ts new file mode 100644 index 0000000..cf1bf78 --- /dev/null +++ b/src/modules/item-related/item-rate/data/models/item-rate.model.ts @@ -0,0 +1,35 @@ +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; +import { ItemRateEntity } from '../../domain/entities/item-rate.entity'; +import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm'; +import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model'; +import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; +import { SeasonPeriodModel } from 'src/modules/season-related/season-period/data/models/season-period.model'; + +@Entity(TABLE_NAME.ITEM_RATE) +export class ItemRateModel + extends BaseCoreModel + implements ItemRateEntity +{ + @Column('varchar', { name: 'item_id', nullable: true }) + item_id: string; + + @ManyToOne(() => ItemModel, (model) => model.item_rates, { + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + }) + @JoinColumn({ name: 'item_id' }) + item: ItemModel; + + @Column('varchar', { name: 'season_period_id', nullable: true }) + season_period_id: string; + + @ManyToOne(() => SeasonPeriodModel, (model) => model.item_rates, { + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + }) + @JoinColumn({ name: 'season_period_id' }) + season_period: SeasonPeriodModel; + + @Column('bigint', { name: 'price', nullable: true }) + price: number; +} diff --git a/src/modules/item-related/item-rate/data/services/item-rate-data.service.ts b/src/modules/item-related/item-rate/data/services/item-rate-data.service.ts new file mode 100644 index 0000000..1c8862f --- /dev/null +++ b/src/modules/item-related/item-rate/data/services/item-rate-data.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; +import { ItemRateEntity } from '../../domain/entities/item-rate.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ItemRateModel } from '../models/item-rate.model'; +import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; +import { Repository } from 'typeorm'; + +@Injectable() +export class ItemRateDataService extends BaseDataService { + constructor( + @InjectRepository(ItemRateModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/item-related/item-rate/data/services/item-rate-read.service.ts b/src/modules/item-related/item-rate/data/services/item-rate-read.service.ts new file mode 100644 index 0000000..3273f11 --- /dev/null +++ b/src/modules/item-related/item-rate/data/services/item-rate-read.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { ItemRateEntity } from '../../domain/entities/item-rate.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ItemRateModel } from '../models/item-rate.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 ItemRateReadService extends BaseReadService { + constructor( + @InjectRepository(ItemRateModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/item-related/item-rate/domain/entities/event/item-rate-created.event.ts b/src/modules/item-related/item-rate/domain/entities/event/item-rate-created.event.ts new file mode 100644 index 0000000..72232fc --- /dev/null +++ b/src/modules/item-related/item-rate/domain/entities/event/item-rate-created.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class ItemRateCreatedEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/item-related/item-rate/domain/entities/event/item-rate-deleted.event.ts b/src/modules/item-related/item-rate/domain/entities/event/item-rate-deleted.event.ts new file mode 100644 index 0000000..948d976 --- /dev/null +++ b/src/modules/item-related/item-rate/domain/entities/event/item-rate-deleted.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class ItemRateDeletedEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/item-related/item-rate/domain/entities/event/item-rate-updated.event.ts b/src/modules/item-related/item-rate/domain/entities/event/item-rate-updated.event.ts new file mode 100644 index 0000000..270967e --- /dev/null +++ b/src/modules/item-related/item-rate/domain/entities/event/item-rate-updated.event.ts @@ -0,0 +1,5 @@ +import { IEvent } from 'src/core/strings/constants/interface.constants'; + +export class ItemRateUpdatedEvent { + constructor(public readonly data: IEvent) {} +} diff --git a/src/modules/item-related/item-rate/domain/entities/filter-item-rate.entity.ts b/src/modules/item-related/item-rate/domain/entities/filter-item-rate.entity.ts new file mode 100644 index 0000000..87df4e3 --- /dev/null +++ b/src/modules/item-related/item-rate/domain/entities/filter-item-rate.entity.ts @@ -0,0 +1,3 @@ +import { BaseFilterEntity } from 'src/core/modules/domain/entities/base-filter.entity'; + +export interface FilterItemRateEntity extends BaseFilterEntity {} diff --git a/src/modules/item-related/item-rate/domain/entities/item-rate.entity.ts b/src/modules/item-related/item-rate/domain/entities/item-rate.entity.ts new file mode 100644 index 0000000..b290f0d --- /dev/null +++ b/src/modules/item-related/item-rate/domain/entities/item-rate.entity.ts @@ -0,0 +1,7 @@ +import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entity'; + +export interface ItemRateEntity extends BaseCoreEntity { + item_id: string; + season_period_id: string; + price: number; +} diff --git a/src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts b/src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts new file mode 100644 index 0000000..0745326 --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/item-rate-data.orchestrator.ts @@ -0,0 +1,52 @@ +import { Injectable } from '@nestjs/common'; +import { CreateItemRateManager } from './managers/create-item-rate.manager'; +import { ItemRateDataService } from '../../data/services/item-rate-data.service'; +import { ItemRateEntity } from '../entities/item-rate.entity'; +import { DeleteItemRateManager } from './managers/delete-item-rate.manager'; +import { UpdateItemRateManager } from './managers/update-item-rate.manager'; +import { BaseDataOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-data.orchestrator'; +import { STATUS } from 'src/core/strings/constants/base.constants'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { BatchDeleteItemRateManager } from './managers/batch-delete-item-rate.manager'; +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; + +@Injectable() +export class ItemRateDataOrchestrator extends BaseDataOrchestrator { + constructor( + private createManager: CreateItemRateManager, + private updateManager: UpdateItemRateManager, + private deleteManager: DeleteItemRateManager, + private batchDeleteManager: BatchDeleteItemRateManager, + private serviceData: ItemRateDataService, + ) { + super(); + } + + async create(data): Promise { + this.createManager.setData(data); + this.createManager.setService(this.serviceData, TABLE_NAME.ITEM_RATE); + await this.createManager.execute(); + return this.createManager.getResult(); + } + + async update(dataId, data): Promise { + this.updateManager.setData(dataId, data); + this.updateManager.setService(this.serviceData, TABLE_NAME.ITEM_RATE); + await this.updateManager.execute(); + return this.updateManager.getResult(); + } + + async delete(dataId): Promise { + this.deleteManager.setData(dataId); + this.deleteManager.setService(this.serviceData, TABLE_NAME.ITEM_RATE); + 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_RATE); + await this.batchDeleteManager.execute(); + return this.batchDeleteManager.getResult(); + } +} diff --git a/src/modules/item-related/item-rate/domain/usecases/item-rate-read.orchestrator.ts b/src/modules/item-related/item-rate/domain/usecases/item-rate-read.orchestrator.ts new file mode 100644 index 0000000..b0a135b --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/item-rate-read.orchestrator.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; +import { IndexItemRateManager } from './managers/index-item-rate.manager'; +import { ItemRateReadService } from '../../data/services/item-rate-read.service'; +import { ItemRateEntity } from '../entities/item-rate.entity'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { BaseReadOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-read.orchestrator'; +import { DetailItemRateManager } from './managers/detail-item-rate.manager'; +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; + +@Injectable() +export class ItemRateReadOrchestrator extends BaseReadOrchestrator { + constructor( + private indexManager: IndexItemRateManager, + private detailManager: DetailItemRateManager, + private serviceData: ItemRateReadService, + ) { + super(); + } + + async index(params): Promise> { + this.indexManager.setFilterParam(params); + this.indexManager.setService(this.serviceData, TABLE_NAME.ITEM_RATE); + 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_RATE); + await this.detailManager.execute(); + return this.detailManager.getResult(); + } +} diff --git a/src/modules/item-related/item-rate/domain/usecases/managers/batch-delete-item-rate.manager.ts b/src/modules/item-related/item-rate/domain/usecases/managers/batch-delete-item-rate.manager.ts new file mode 100644 index 0000000..f8f1e2f --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/managers/batch-delete-item-rate.manager.ts @@ -0,0 +1,45 @@ +import { BaseBatchDeleteManager } from 'src/core/modules/domain/usecase/managers/base-batch-delete.manager'; +import { ItemRateEntity } from '../../entities/item-rate.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemRateModel } from '../../../data/models/item-rate.model'; +import { ItemRateDeletedEvent } from '../../entities/event/item-rate-deleted.event'; +import { BatchResult } from 'src/core/response/domain/ok-response.interface'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class BatchDeleteItemRateManager extends BaseBatchDeleteManager { + async beforeProcess(): Promise { + return; + } + + async validateData(data: ItemRateEntity): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return ItemRateModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: ItemRateDeletedEvent, + }, + ]; + } + + getResult(): BatchResult { + return this.result; + } +} diff --git a/src/modules/item-related/item-rate/domain/usecases/managers/create-item-rate.manager.ts b/src/modules/item-related/item-rate/domain/usecases/managers/create-item-rate.manager.ts new file mode 100644 index 0000000..31d1453 --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/managers/create-item-rate.manager.ts @@ -0,0 +1,42 @@ +import { Injectable } from '@nestjs/common'; +import { + EventTopics, + columnUniques, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemRateEntity } from '../../entities/item-rate.entity'; +import { ItemRateModel } from '../../../data/models/item-rate.model'; +import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager'; +import { ItemRateCreatedEvent } from '../../entities/event/item-rate-created.event'; + +@Injectable() +export class CreateItemRateManager extends BaseCreateManager { + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get uniqueColumns(): columnUniques[] { + return []; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: ItemRateCreatedEvent, + data: this.data, + }, + ]; + } + + get entityTarget(): any { + return ItemRateModel; + } +} diff --git a/src/modules/item-related/item-rate/domain/usecases/managers/delete-item-rate.manager.ts b/src/modules/item-related/item-rate/domain/usecases/managers/delete-item-rate.manager.ts new file mode 100644 index 0000000..2e0b3dc --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/managers/delete-item-rate.manager.ts @@ -0,0 +1,45 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDeleteManager } from 'src/core/modules/domain/usecase/managers/base-delete.manager'; +import { ItemRateEntity } from '../../entities/item-rate.entity'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; +import { ItemRateModel } from '../../../data/models/item-rate.model'; +import { ItemRateDeletedEvent } from '../../entities/event/item-rate-deleted.event'; + +@Injectable() +export class DeleteItemRateManager extends BaseDeleteManager { + getResult(): string { + return `Success`; + } + + async validateProcess(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get entityTarget(): any { + return ItemRateModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: ItemRateDeletedEvent, + data: this.data, + }, + ]; + } +} diff --git a/src/modules/item-related/item-rate/domain/usecases/managers/detail-item-rate.manager.ts b/src/modules/item-related/item-rate/domain/usecases/managers/detail-item-rate.manager.ts new file mode 100644 index 0000000..1d20cb1 --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/managers/detail-item-rate.manager.ts @@ -0,0 +1,42 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDetailManager } from 'src/core/modules/domain/usecase/managers/base-detail.manager'; +import { ItemRateEntity } from '../../entities/item-rate.entity'; +import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity'; + +@Injectable() +export class DetailItemRateManager extends BaseDetailManager { + async prepareData(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get relations(): RelationParam { + return { + // relation only join (for query purpose) + joinRelations: [], + + // relation join and select (relasi yang ingin ditampilkan), + selectRelations: [], + + // relation yang hanya ingin dihitung (akan return number) + countRelations: [], + }; + } + + get selects(): string[] { + return []; + } + + get setFindProperties(): any { + return { + id: this.dataId, + }; + } +} diff --git a/src/modules/item-related/item-rate/domain/usecases/managers/index-item-rate.manager.ts b/src/modules/item-related/item-rate/domain/usecases/managers/index-item-rate.manager.ts new file mode 100644 index 0000000..82f19cc --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/managers/index-item-rate.manager.ts @@ -0,0 +1,55 @@ +import { Injectable } from '@nestjs/common'; +import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager'; +import { ItemRateEntity } from '../../entities/item-rate.entity'; +import { SelectQueryBuilder } from 'typeorm'; +import { + Param, + RelationParam, +} from 'src/core/modules/domain/entities/base-filter.entity'; + +@Injectable() +export class IndexItemRateManager extends BaseIndexManager { + async prepareData(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get relations(): RelationParam { + return { + // relation only join (for query purpose) + joinRelations: [], + + // relation join and select (relasi yang ingin ditampilkan), + selectRelations: [], + + // relation yang hanya ingin dihitung (akan return number) + countRelations: [], + }; + } + + get selects(): string[] { + return []; + } + + 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/item-rate/domain/usecases/managers/update-item-rate.manager.ts b/src/modules/item-related/item-rate/domain/usecases/managers/update-item-rate.manager.ts new file mode 100644 index 0000000..963ea85 --- /dev/null +++ b/src/modules/item-related/item-rate/domain/usecases/managers/update-item-rate.manager.ts @@ -0,0 +1,46 @@ +import { Injectable } from '@nestjs/common'; +import { BaseUpdateManager } from 'src/core/modules/domain/usecase/managers/base-update.manager'; +import { ItemRateEntity } from '../../entities/item-rate.entity'; +import { ItemRateModel } from '../../../data/models/item-rate.model'; +import { ItemRateUpdatedEvent } from '../../entities/event/item-rate-updated.event'; +import { + EventTopics, + columnUniques, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; + +@Injectable() +export class UpdateItemRateManager extends BaseUpdateManager { + async validateProcess(): Promise { + return; + } + + async beforeProcess(): Promise { + return; + } + + async afterProcess(): Promise { + return; + } + + get validateRelations(): validateRelations[] { + return []; + } + + get uniqueColumns(): columnUniques[] { + return []; + } + + get entityTarget(): any { + return ItemRateModel; + } + + get eventTopics(): EventTopics[] { + return [ + { + topic: ItemRateUpdatedEvent, + data: this.data, + }, + ]; + } +} diff --git a/src/modules/item-related/item-rate/index.ts b/src/modules/item-related/item-rate/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/modules/item-related/item-rate/infrastructure/dto/filter-item-rate.dto.ts b/src/modules/item-related/item-rate/infrastructure/dto/filter-item-rate.dto.ts new file mode 100644 index 0000000..de94d21 --- /dev/null +++ b/src/modules/item-related/item-rate/infrastructure/dto/filter-item-rate.dto.ts @@ -0,0 +1,6 @@ +import { BaseFilterDto } from 'src/core/modules/infrastructure/dto/base-filter.dto'; +import { FilterItemRateEntity } from '../../domain/entities/filter-item-rate.entity'; + +export class FilterItemRateDto + extends BaseFilterDto + implements FilterItemRateEntity {} diff --git a/src/modules/item-related/item-rate/infrastructure/dto/item-rate.dto.ts b/src/modules/item-related/item-rate/infrastructure/dto/item-rate.dto.ts new file mode 100644 index 0000000..5ae1270 --- /dev/null +++ b/src/modules/item-related/item-rate/infrastructure/dto/item-rate.dto.ts @@ -0,0 +1,32 @@ +import { BaseCoreDto } from 'src/core/modules/infrastructure/dto/base-core.dto'; +import { ItemRateEntity } from '../../domain/entities/item-rate.entity'; +import { ApiProperty } from '@nestjs/swagger'; +import { Exclude } from 'class-transformer'; +import { ItemModel } from 'src/modules/item-related/item/data/models/item.model'; +import { IsObject } from 'class-validator'; +import { ItemDto } from 'src/modules/item-related/item/infrastructure/dto/item.dto'; + +export class ItemRateDto extends BaseCoreDto implements ItemRateEntity { + @Exclude() + item_id: string; + + @ApiProperty({ + type: [Object], + required: true, + example: { + id: 'uuid', + name: 'Entrace Ticket', + }, + }) + @IsObject() + item: ItemModel; + + @Exclude() + season_period_id: string; + + @ApiProperty({ + type: Number, + required: true, + }) + price: number; +} diff --git a/src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts b/src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts new file mode 100644 index 0000000..d8a3648 --- /dev/null +++ b/src/modules/item-related/item-rate/infrastructure/item-rate-data.controller.ts @@ -0,0 +1,40 @@ +import { Body, Controller, Delete, Param, Post, Put } from '@nestjs/common'; +import { ItemRateDataOrchestrator } from '../domain/usecases/item-rate-data.orchestrator'; +import { ItemRateDto } from './dto/item-rate.dto'; +import { MODULE_NAME } from 'src/core/strings/constants/module.constants'; +import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; +import { ItemRateEntity } from '../domain/entities/item-rate.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_RATE.split('-').join(' ')} - data`) +@Controller(MODULE_NAME.ITEM_RATE) +@Public(false) +@ApiBearerAuth('JWT') +export class ItemRateDataController { + constructor(private orchestrator: ItemRateDataOrchestrator) {} + + @Post() + async create(@Body() data: ItemRateDto): Promise { + return await this.orchestrator.create(data); + } + + @Put('/batch-delete') + async batchDeleted(@Body() body: BatchIdsDto): Promise { + return await this.orchestrator.batchDelete(body.ids); + } + + @Put(':id') + async update( + @Param('id') dataId: string, + @Body() data: ItemRateDto, + ): 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-rate/infrastructure/item-rate-read.controller.ts b/src/modules/item-related/item-rate/infrastructure/item-rate-read.controller.ts new file mode 100644 index 0000000..4861962 --- /dev/null +++ b/src/modules/item-related/item-rate/infrastructure/item-rate-read.controller.ts @@ -0,0 +1,30 @@ +import { Controller, Get, Param, Query } from '@nestjs/common'; +import { FilterItemRateDto } from './dto/filter-item-rate.dto'; +import { Pagination } from 'src/core/response'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { ItemRateEntity } from '../domain/entities/item-rate.entity'; +import { ItemRateReadOrchestrator } from '../domain/usecases/item-rate-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_RATE.split('-').join(' ')} - read`) +@Controller(MODULE_NAME.ITEM_RATE) +@Public(false) +@ApiBearerAuth('JWT') +export class ItemRateReadController { + constructor(private orchestrator: ItemRateReadOrchestrator) {} + + @Get() + @Pagination() + async index( + @Query() params: FilterItemRateDto, + ): 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-rate/item-rate.module.ts b/src/modules/item-related/item-rate/item-rate.module.ts new file mode 100644 index 0000000..17e224f --- /dev/null +++ b/src/modules/item-related/item-rate/item-rate.module.ts @@ -0,0 +1,42 @@ +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 { ItemRateDataService } from './data/services/item-rate-data.service'; +import { ItemRateReadService } from './data/services/item-rate-read.service'; +import { ItemRateReadController } from './infrastructure/item-rate-read.controller'; +import { ItemRateReadOrchestrator } from './domain/usecases/item-rate-read.orchestrator'; +import { ItemRateDataController } from './infrastructure/item-rate-data.controller'; +import { ItemRateDataOrchestrator } from './domain/usecases/item-rate-data.orchestrator'; +import { CreateItemRateManager } from './domain/usecases/managers/create-item-rate.manager'; +import { CqrsModule } from '@nestjs/cqrs'; +import { IndexItemRateManager } from './domain/usecases/managers/index-item-rate.manager'; +import { DeleteItemRateManager } from './domain/usecases/managers/delete-item-rate.manager'; +import { UpdateItemRateManager } from './domain/usecases/managers/update-item-rate.manager'; +import { DetailItemRateManager } from './domain/usecases/managers/detail-item-rate.manager'; +import { BatchDeleteItemRateManager } from './domain/usecases/managers/batch-delete-item-rate.manager'; +import { ItemRateModel } from './data/models/item-rate.model'; + +@Module({ + imports: [ + ConfigModule.forRoot(), + TypeOrmModule.forFeature([ItemRateModel], CONNECTION_NAME.DEFAULT), + CqrsModule, + ], + controllers: [ItemRateDataController, ItemRateReadController], + providers: [ + IndexItemRateManager, + DetailItemRateManager, + CreateItemRateManager, + DeleteItemRateManager, + UpdateItemRateManager, + BatchDeleteItemRateManager, + + ItemRateDataService, + ItemRateReadService, + + ItemRateDataOrchestrator, + ItemRateReadOrchestrator, + ], +}) +export class ItemRateModule {} 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 e1cd7ec..0b9bf82 100644 --- a/src/modules/item-related/item/data/models/item.model.ts +++ b/src/modules/item-related/item/data/models/item.model.ts @@ -7,12 +7,14 @@ import { JoinTable, ManyToMany, ManyToOne, + OneToMany, } from 'typeorm'; import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model'; import { ItemType } from 'src/modules/item-related/item-category/constants'; import { LimitType } from '../../constants'; import { ItemCategoryModel } from 'src/modules/item-related/item-category/data/models/item-category.model'; 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'; @Entity(TABLE_NAME.ITEM) export class ItemModel @@ -99,4 +101,11 @@ export class ItemModel }, }) bundling_items: ItemModel[]; + + // relasi ke item rates + @OneToMany(() => ItemRateModel, (model) => model.item, { + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + }) + item_rates: ItemRateModel[]; } diff --git a/src/modules/item-related/item/domain/entities/filter-item.entity.ts b/src/modules/item-related/item/domain/entities/filter-item.entity.ts index 7d10d72..1bde43f 100644 --- a/src/modules/item-related/item/domain/entities/filter-item.entity.ts +++ b/src/modules/item-related/item/domain/entities/filter-item.entity.ts @@ -5,4 +5,5 @@ export interface FilterItemEntity extends BaseFilterEntity { item_types: string[]; limit_types: string[]; tenant_ids: string[]; + all_item: boolean; } diff --git a/src/modules/item-related/item/domain/usecases/managers/index-item.manager.ts b/src/modules/item-related/item/domain/usecases/managers/index-item.manager.ts index ffa0adb..281ab07 100644 --- a/src/modules/item-related/item/domain/usecases/managers/index-item.manager.ts +++ b/src/modules/item-related/item/domain/usecases/managers/index-item.manager.ts @@ -82,7 +82,7 @@ export class IndexItemManager extends BaseIndexManager { queryBuilder.andWhere(`${this.tableName}.tenant_id In (:...tenantIds)`, { tenantIds: this.filterParam.tenant_ids, }); - } else { + } else if (!this.filterParam.all_item) { queryBuilder.andWhere(`${this.tableName}.tenant_id Is Null`); } diff --git a/src/modules/item-related/item/infrastructure/dto/filter-item.dto.ts b/src/modules/item-related/item/infrastructure/dto/filter-item.dto.ts index 5270b63..5a0d70f 100644 --- a/src/modules/item-related/item/infrastructure/dto/filter-item.dto.ts +++ b/src/modules/item-related/item/infrastructure/dto/filter-item.dto.ts @@ -27,4 +27,11 @@ export class FilterItemDto extends BaseFilterDto implements FilterItemEntity { return Array.isArray(body.value) ? body.value : [body.value]; }) tenant_ids: string[]; + + @ApiProperty({ + type: Boolean, + required: false, + }) + @Transform((body) => body.value == 'true') + all_item: boolean; } 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 65a6b88..cc2067e 100644 --- a/src/modules/item-related/item/infrastructure/dto/item.dto.ts +++ b/src/modules/item-related/item/infrastructure/dto/item.dto.ts @@ -108,7 +108,11 @@ export class ItemDto extends BaseStatusDto implements ItemEntity { example: 60, }) @IsNumber() - @ValidateIf((body) => body.item_type.toLowerCase() == ItemType.WAHANA && body.limit_type.toLowerCase() != LimitType.NO_LIMIT) + @ValidateIf( + (body) => + body.item_type.toLowerCase() == ItemType.WAHANA && + body.limit_type.toLowerCase() != LimitType.NO_LIMIT, + ) limit_value: number; @ApiProperty({ type: Boolean, required: false })