From d8fa72ba20851447a563618ca9cafa283d58f465 Mon Sep 17 00:00:00 2001 From: shancheas Date: Wed, 11 Jun 2025 15:41:07 +0700 Subject: [PATCH] feat: implement BookingItemManager for enhanced item booking functionality --- .../usecases/managers/booking-item.manager.ts | 66 +++++++++++++++++++ .../order/infrastructure/item.controller.ts | 4 +- .../booking-online/order/order.module.ts | 2 + .../item/domain/entities/item.entity.ts | 3 + .../usecases/managers/index-item.manager.ts | 2 +- 5 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 src/modules/booking-online/order/domain/usecases/managers/booking-item.manager.ts diff --git a/src/modules/booking-online/order/domain/usecases/managers/booking-item.manager.ts b/src/modules/booking-online/order/domain/usecases/managers/booking-item.manager.ts new file mode 100644 index 0000000..b392b78 --- /dev/null +++ b/src/modules/booking-online/order/domain/usecases/managers/booking-item.manager.ts @@ -0,0 +1,66 @@ +import { Injectable } from '@nestjs/common'; +import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity'; +import { IndexItemManager } from 'src/modules/item-related/item/domain/usecases/managers/index-item.manager'; +import { SelectQueryBuilder } from 'typeorm'; + +@Injectable() +export class BookingItemManager extends IndexItemManager { + get relations(): RelationParam { + return { + // relation only join (for query purpose) + joinRelations: [], + + // relation join and select (relasi yang ingin ditampilkan), + selectRelations: [ + 'item_category', + 'bundling_items', + 'tenant', + 'time_group', + 'item_rates', + ], + + // relation yang hanya ingin dihitung (akan return number) + countRelations: [], + }; + } + + get selects(): string[] { + const parent = super.selects; + return [ + ...parent, + 'item_rates.id', + 'item_rates.price', + 'item_rates.season_period_id', + ]; + } + + getResult(): PaginationResponse { + const result = super.getResult(); + const { data, total } = result; + const hasRates = (this.filterParam.season_period_ids?.length ?? 0) > 0; + const items = data.map((item) => { + const { item_rates, ...rest } = item; + const rate = item_rates?.[0]?.['price'] ?? rest.base_price; + return { + ...rest, + base_price: hasRates ? rate : rest.base_price, + }; + }); + return { total, data: items }; + } + + setQueryFilter( + queryBuilder: SelectQueryBuilder, + ): SelectQueryBuilder { + const query = super.setQueryFilter(queryBuilder); + + if (this.filterParam.season_period_ids) { + query.andWhere(`item_rates.season_period_id In (:...seasonIds)`, { + seasonIds: this.filterParam.season_period_ids, + }); + } + return query; + } +} diff --git a/src/modules/booking-online/order/infrastructure/item.controller.ts b/src/modules/booking-online/order/infrastructure/item.controller.ts index 166818e..5e15333 100644 --- a/src/modules/booking-online/order/infrastructure/item.controller.ts +++ b/src/modules/booking-online/order/infrastructure/item.controller.ts @@ -5,15 +5,15 @@ import { PaginationResponse } from 'src/core/response/domain/ok-response.interfa import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { ItemReadService } from 'src/modules/item-related/item/data/services/item-read.service'; import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity'; -import { IndexItemManager } from 'src/modules/item-related/item/domain/usecases/managers/index-item.manager'; import { FilterItemDto } from 'src/modules/item-related/item/infrastructure/dto/filter-item.dto'; +import { BookingItemManager } from '../domain/usecases/managers/booking-item.manager'; @ApiTags('Booking Item') @Controller('v1/booking-item') @Public(true) export class ItemController { constructor( - private indexManager: IndexItemManager, + private indexManager: BookingItemManager, private serviceData: ItemReadService, ) {} diff --git a/src/modules/booking-online/order/order.module.ts b/src/modules/booking-online/order/order.module.ts index d337988..b0aea9e 100644 --- a/src/modules/booking-online/order/order.module.ts +++ b/src/modules/booking-online/order/order.module.ts @@ -14,6 +14,7 @@ import { CqrsModule } from '@nestjs/cqrs'; import { RescheduleVerificationModel } from './data/models/reschedule-verification.model'; import { RescheduleVerificationManager } from './domain/usecases/managers/reschedule-verification.manager'; import { RescheduleManager } from './domain/usecases/managers/reschedule.manager'; +import { BookingItemManager } from './domain/usecases/managers/booking-item.manager'; @Module({ imports: [ ConfigModule.forRoot(), @@ -31,6 +32,7 @@ import { RescheduleManager } from './domain/usecases/managers/reschedule.manager CreateBookingManager, RescheduleVerificationManager, RescheduleManager, + BookingItemManager, ], }) export class BookingOrderModule {} 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 8d4a0a7..e8a158c 100644 --- a/src/modules/item-related/item/domain/entities/item.entity.ts +++ b/src/modules/item-related/item/domain/entities/item.entity.ts @@ -1,6 +1,7 @@ import { BaseStatusEntity } from 'src/core/modules/domain/entities/base-status.entity'; import { ItemType } from 'src/modules/item-related/item-category/constants'; import { LimitType } from '../../constants'; +import { ItemRateEntity } from 'src/modules/item-related/item-rate/domain/entities/item-rate.entity'; export interface ItemEntity extends BaseStatusEntity { name: string; @@ -19,4 +20,6 @@ export interface ItemEntity extends BaseStatusEntity { show_to_booking: boolean; breakdown_bundling?: boolean; booking_description?: string; + + item_rates?: ItemRateEntity[] | any[]; } 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 f32ac74..6277d2b 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 @@ -110,7 +110,7 @@ export class IndexItemManager extends BaseIndexManager { if (this.filterParam.time_group_ids?.length) { queryBuilder.andWhere( - `${this.tableName}.time_group_id In (:...timeGroupIds) OR ${this.tableName}.time_group_id Is Null`, + `(${this.tableName}.time_group_id In (:...timeGroupIds) OR ${this.tableName}.time_group_id Is Null)`, { timeGroupIds: this.filterParam.time_group_ids, },