import { Injectable } from '@nestjs/common'; import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager'; import { SelectQueryBuilder } from 'typeorm'; import { Param, RelationParam, } from 'src/core/modules/domain/entities/base-filter.entity'; import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity'; import { DAY, STATUS } from 'src/core/strings/constants/base.constants'; @Injectable() export class IndexItemRateManager extends BaseIndexManager { async prepareData(): Promise { return; } async beforeProcess(): Promise { return; } async afterProcess(): Promise { this.result.data?.map((item) => { const prices = []; for ( let d = new Date(this.filterParam.start_date); d <= new Date(this.filterParam.end_date); d.setDate(d.getDate() + 1) ) { const day: string = DAY[d.getDay()]; const rates = item['item_rates'] ?.filter((rate) => { const days: string[] = rate.season_period.days ?? []; if (rate.season_period.priority == 2) { return ( rate.season_period?.status == STATUS.ACTIVE && d >= new Date(rate.season_period.start_date) && d <= new Date(rate.season_period.end_date) && days.includes(day) ); } else { return ( rate.season_period?.status == STATUS.ACTIVE && d >= new Date(rate.season_period.start_date) && d <= new Date(rate.season_period.end_date) ); } }) .sort((a, b) => a.season_period.priority - b.season_period.priority); prices.push({ date: new Date(d), price: rates[0]?.price ?? item.base_price, season_type: rates[0]?.season_period?.season_type ?? null, holiday_name: rates[0]?.season_period?.holiday_name ?? null, }); } delete item['item_rates']; Object.assign(item, { dates: prices, }); }); return; } get relations(): RelationParam { return { // relation only join (for query purpose) joinRelations: [], // relation join and select (relasi yang ingin ditampilkan), selectRelations: [ 'bundling_items', 'tenant', 'item_rates', 'item_rates.season_period', 'season_period.season_type', ], // relation yang hanya ingin dihitung (akan return number) countRelations: [], }; } get selects(): string[] { return [ `${this.tableName}.id`, `${this.tableName}.item_type`, `${this.tableName}.status`, `${this.tableName}.created_at`, `${this.tableName}.name`, `${this.tableName}.base_price`, `${this.tableName}.breakdown_bundling`, `${this.tableName}.share_profit`, 'tenant.id', 'tenant.name', 'bundling_items.id', 'bundling_items.name', 'item_rates.id', 'item_rates.price', 'season_period.id', 'season_period.status', 'season_period.holiday_name', 'season_period.start_date', 'season_period.end_date', 'season_period.priority', 'season_period.days', 'season_type.id', 'season_type.name', ]; } get specificFilter(): Param[] { return [ { cols: `${this.tableName}.name`, data: this.filterParam.names, }, { cols: `${this.tableName}.item_type::text`, data: this.filterParam.item_types, }, { cols: `${this.tableName}.limit_type::text`, data: this.filterParam.limit_types, }, { cols: `item_category.name`, data: this.filterParam.item_categories, }, ]; } setQueryFilter( queryBuilder: SelectQueryBuilder, ): SelectQueryBuilder { if (this.filterParam.tenant_ids?.length) { queryBuilder.andWhere(`${this.tableName}.tenant_id In (:...tenantIds)`, { tenantIds: this.filterParam.tenant_ids, }); } queryBuilder.andWhere(`${this.tableName}.status In (:...statuses)`, { statuses: [STATUS.ACTIVE], }); return queryBuilder; } }