From 5b5c3efcccf4749077d5d3a2e8703487b3369560 Mon Sep 17 00:00:00 2001 From: ashar Date: Thu, 20 Jun 2024 01:46:09 +0700 Subject: [PATCH] feat(SPG-355) REST API Read Season Period --- .../services/season-period-read.service.ts | 17 ++++ .../entities/filter-season-period.entity.ts | 9 +++ .../managers/detail-season-period.manager.ts | 56 +++++++++++++ .../index-holiday-google-calendar.manager.ts | 53 ------------- .../managers/index-season-period.manager.ts | 79 +++++++++++++++++++ .../season-period-read.orchestrator.ts | 33 ++++++++ .../dto/filter-season-period.dto.ts | 28 +++++++ .../season-period-read.controller.ts | 30 +++++++ 8 files changed, 252 insertions(+), 53 deletions(-) create mode 100644 src/modules/season-related/season-period/data/services/season-period-read.service.ts create mode 100644 src/modules/season-related/season-period/domain/entities/filter-season-period.entity.ts create mode 100644 src/modules/season-related/season-period/domain/usecases/managers/detail-season-period.manager.ts delete mode 100644 src/modules/season-related/season-period/domain/usecases/managers/index-holiday-google-calendar.manager.ts create mode 100644 src/modules/season-related/season-period/domain/usecases/managers/index-season-period.manager.ts create mode 100644 src/modules/season-related/season-period/domain/usecases/season-period-read.orchestrator.ts create mode 100644 src/modules/season-related/season-period/infrastructure/dto/filter-season-period.dto.ts create mode 100644 src/modules/season-related/season-period/infrastructure/season-period-read.controller.ts diff --git a/src/modules/season-related/season-period/data/services/season-period-read.service.ts b/src/modules/season-related/season-period/data/services/season-period-read.service.ts new file mode 100644 index 0000000..8384f0a --- /dev/null +++ b/src/modules/season-related/season-period/data/services/season-period-read.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { SeasonPeriodEntity } from '../../domain/entities/season-period.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { SeasonPeriodModel } from '../models/season-period.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 SeasonPeriodReadService extends BaseReadService { + constructor( + @InjectRepository(SeasonPeriodModel, CONNECTION_NAME.DEFAULT) + private repo: Repository, + ) { + super(repo); + } +} diff --git a/src/modules/season-related/season-period/domain/entities/filter-season-period.entity.ts b/src/modules/season-related/season-period/domain/entities/filter-season-period.entity.ts new file mode 100644 index 0000000..0dc158d --- /dev/null +++ b/src/modules/season-related/season-period/domain/entities/filter-season-period.entity.ts @@ -0,0 +1,9 @@ +import { BaseFilterEntity } from 'src/core/modules/domain/entities/base-filter.entity'; +import { EnumDays } from '../../constants'; + +export interface FilterSeasonPeriodEntity extends BaseFilterEntity { + start_date: Date; + end_date: Date; + holiday_names: string[]; + days: EnumDays[]; +} diff --git a/src/modules/season-related/season-period/domain/usecases/managers/detail-season-period.manager.ts b/src/modules/season-related/season-period/domain/usecases/managers/detail-season-period.manager.ts new file mode 100644 index 0000000..c99528c --- /dev/null +++ b/src/modules/season-related/season-period/domain/usecases/managers/detail-season-period.manager.ts @@ -0,0 +1,56 @@ +import { Injectable } from '@nestjs/common'; +import { BaseDetailManager } from 'src/core/modules/domain/usecase/managers/base-detail.manager'; +import { SeasonPeriodEntity } from '../../entities/season-period.entity'; +import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity'; + +@Injectable() +export class DetailSeasonPeriodManager 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: ['season_type'], + + // relation join and select (relasi yang ingin ditampilkan), + selectRelations: [], + + // relation yang hanya ingin dihitung (akan return number) + countRelations: [], + }; + } + + get selects(): string[] { + return [ + `${this.tableName}.id`, + `${this.tableName}.created_at`, + `${this.tableName}.creator_name`, + `${this.tableName}.editor_name`, + `${this.tableName}.updated_at`, + `${this.tableName}.status`, + `${this.tableName}.start_date`, + `${this.tableName}.end_date`, + `${this.tableName}.days`, + `${this.tableName}.holiday_name`, + + 'season_type.id', + 'season_type.name', + ]; + } + + get setFindProperties(): any { + return { + id: this.dataId, + }; + } +} diff --git a/src/modules/season-related/season-period/domain/usecases/managers/index-holiday-google-calendar.manager.ts b/src/modules/season-related/season-period/domain/usecases/managers/index-holiday-google-calendar.manager.ts deleted file mode 100644 index e1c52c3..0000000 --- a/src/modules/season-related/season-period/domain/usecases/managers/index-holiday-google-calendar.manager.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { google } from 'googleapis'; - -@Injectable() -export class IndexHolidayCalendarManager { - async execute() { - const events = []; - const calendar = google.calendar({ - version: 'v3', - auth: 'AIzaSyCsCt6PDd6uYLkahvtdvCoMWf-1_QaLiNM', - }); - const calendarId = 'id.indonesian#holiday@group.v.calendar.google.com'; - - const res = await calendar.events.list({ - calendarId: calendarId, - timeMin: new Date().getFullYear() + '-01-01T00:00:00Z', - timeMax: new Date().getFullYear() + '-12-31T23:59:59Z', - singleEvents: true, - orderBy: 'startTime', - }); - - res.data.items?.forEach((item) => { - // const eventName = item.summary.replace("Joint", "").replace("for", "").replace("after", "").replace("Holiday","").trim(); - let eventName = item.summary.replace('Cuti Bersama', '').trim(); - - // function ini untuk menyamakan dan menggabungkan Hari Libur - if (eventName == 'Hari Idul Fitri') - eventName = eventName.replace('Hari', '').trim(); - else if (eventName == 'Natal (Hari Tinju)' || eventName == 'Malam Natal') - eventName = 'Hari Raya Natal'; - - const exist = events.find((event) => { - return event.name.toLowerCase().includes(eventName.toLowerCase()); - }); - - if (exist) { - Object.assign(exist, { - end_date: item.start.date, - total_day: exist.total_day + 1, - }); - } else { - events.push({ - name: eventName, - start_date: item.start?.date, - end_date: item.start?.date, - total_day: 1, - }); - } - }); - - return events; - } -} diff --git a/src/modules/season-related/season-period/domain/usecases/managers/index-season-period.manager.ts b/src/modules/season-related/season-period/domain/usecases/managers/index-season-period.manager.ts new file mode 100644 index 0000000..62dec43 --- /dev/null +++ b/src/modules/season-related/season-period/domain/usecases/managers/index-season-period.manager.ts @@ -0,0 +1,79 @@ +import { Injectable } from '@nestjs/common'; +import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager'; +import { SeasonPeriodEntity } from '../../entities/season-period.entity'; +import { SelectQueryBuilder } from 'typeorm'; +import { + Param, + RelationParam, +} from 'src/core/modules/domain/entities/base-filter.entity'; + +@Injectable() +export class IndexSeasonPeriodManager 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: ['season_type'], + + // relation join and select (relasi yang ingin ditampilkan), + selectRelations: [], + + // relation yang hanya ingin dihitung (akan return number) + countRelations: [], + }; + } + + get selects(): string[] { + return [ + `${this.tableName}.id`, + `${this.tableName}.created_at`, + `${this.tableName}.creator_name`, + `${this.tableName}.editor_name`, + `${this.tableName}.updated_at`, + `${this.tableName}.status`, + `${this.tableName}.start_date`, + `${this.tableName}.end_date`, + `${this.tableName}.days`, + `${this.tableName}.holiday_name`, + + 'season_type.id', + 'season_type.name', + ]; + } + + get specificFilter(): Param[] { + return [ + { + cols: `${this.tableName}.holiday_name`, + data: this.filterParam.holiday_names, + }, + ]; + } + + setQueryFilter( + queryBuilder: SelectQueryBuilder, + ): SelectQueryBuilder { + if (this.filterParam.start_date && this.filterParam.end_date) { + queryBuilder.andWhere( + `${this.tableName}.start_date BETWEEN :from AND :to`, + { + from: this.filterParam.start_date, + to: this.filterParam.end_date, + }, + ); + } + + return queryBuilder; + } +} diff --git a/src/modules/season-related/season-period/domain/usecases/season-period-read.orchestrator.ts b/src/modules/season-related/season-period/domain/usecases/season-period-read.orchestrator.ts new file mode 100644 index 0000000..36ae641 --- /dev/null +++ b/src/modules/season-related/season-period/domain/usecases/season-period-read.orchestrator.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; +import { IndexSeasonPeriodManager } from './managers/index-season-period.manager'; +import { SeasonPeriodReadService } from '../../data/services/season-period-read.service'; +import { SeasonPeriodEntity } from '../entities/season-period.entity'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { BaseReadOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-read.orchestrator'; +import { DetailSeasonPeriodManager } from './managers/detail-season-period.manager'; +import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; + +@Injectable() +export class SeasonPeriodReadOrchestrator extends BaseReadOrchestrator { + constructor( + private indexManager: IndexSeasonPeriodManager, + private detailManager: DetailSeasonPeriodManager, + private serviceData: SeasonPeriodReadService, + ) { + super(); + } + + async index(params): Promise> { + this.indexManager.setFilterParam(params); + this.indexManager.setService(this.serviceData, TABLE_NAME.SEASON_PERIOD); + await this.indexManager.execute(); + return this.indexManager.getResult(); + } + + async detail(dataId: string): Promise { + this.detailManager.setData(dataId); + this.detailManager.setService(this.serviceData, TABLE_NAME.SEASON_PERIOD); + await this.detailManager.execute(); + return this.detailManager.getResult(); + } +} diff --git a/src/modules/season-related/season-period/infrastructure/dto/filter-season-period.dto.ts b/src/modules/season-related/season-period/infrastructure/dto/filter-season-period.dto.ts new file mode 100644 index 0000000..b2a438a --- /dev/null +++ b/src/modules/season-related/season-period/infrastructure/dto/filter-season-period.dto.ts @@ -0,0 +1,28 @@ +import { BaseFilterDto } from 'src/core/modules/infrastructure/dto/base-filter.dto'; +import { FilterSeasonPeriodEntity } from '../../domain/entities/filter-season-period.entity'; +import { EnumDays } from '../../constants'; +import { ApiProperty } from '@nestjs/swagger'; +import { Transform } from 'class-transformer'; + +export class FilterSeasonPeriodDto + extends BaseFilterDto + implements FilterSeasonPeriodEntity +{ + @ApiProperty({ type: Date, required: false }) + start_date: Date; + + @ApiProperty({ type: Date, required: false }) + end_date: Date; + + @ApiProperty({ type: ['string'], required: false }) + @Transform((body) => { + return Array.isArray(body.value) ? body.value : [body.value]; + }) + holiday_names: string[]; + + @ApiProperty({ type: ['string'], required: false }) + @Transform((body) => { + return Array.isArray(body.value) ? body.value : [body.value]; + }) + days: EnumDays[]; +} diff --git a/src/modules/season-related/season-period/infrastructure/season-period-read.controller.ts b/src/modules/season-related/season-period/infrastructure/season-period-read.controller.ts new file mode 100644 index 0000000..5d64393 --- /dev/null +++ b/src/modules/season-related/season-period/infrastructure/season-period-read.controller.ts @@ -0,0 +1,30 @@ +import { Controller, Get, Param, Query } from '@nestjs/common'; +import { FilterSeasonPeriodDto } from './dto/filter-season-period.dto'; +import { Pagination } from 'src/core/response'; +import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { SeasonPeriodEntity } from '../domain/entities/season-period.entity'; +import { SeasonPeriodReadOrchestrator } from '../domain/usecases/season-period-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.SEASON_PERIOD.split('-').join(' ')} - read`) +@Controller(MODULE_NAME.SEASON_PERIOD) +@Public(false) +@ApiBearerAuth('JWT') +export class SeasonPeriodReadController { + constructor(private orchestrator: SeasonPeriodReadOrchestrator) {} + + @Get() + @Pagination() + async index( + @Query() params: FilterSeasonPeriodDto, + ): Promise> { + return await this.orchestrator.index(params); + } + + @Get(':id') + async detail(@Param('id') id: string): Promise { + return await this.orchestrator.detail(id); + } +}