import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Patch, Post, Query, } from '@nestjs/common'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; import moment from 'moment'; import { type PageDto } from '../../common/dto/page.dto'; import { RoleType } from '../../constants'; import { ApiPageOkResponse, Auth, AuthUser, UUIDParam, Whitelist, } from '../../decorators'; import { AccountHasClosedException, ActivityRecordDateExceedTodayException, ActivityRecordNotFoundException, // RecordDateIsHolodayException, // RecordDateIsWeekendException, RecordMoreThan3DaysException, } from '../../exceptions'; import { ApiConfigService } from '../../shared/services/api-config.service'; // import { PublicHolidayService } from '../public-holiday/public-holiday.service'; import { UserEntity } from '../user/user.entity'; import { ActivityRecordService } from './activity-record.service'; import { ActivityRecordDto } from './dtos/activity-record.dto'; import { CreateActivityRecordDto } from './dtos/create-activity-record.dto'; import { ActivityRecordPageOptionsDto } from './dtos/get-activity-record-page.dto'; import { UpdateActivityRecordDto } from './dtos/update-activity-record.dto'; @Controller('activity-records') @ApiTags('activity-records') export class ActivityRecordController { constructor( private activityRecordService: ActivityRecordService, // @Inject(forwardRef(() => PublicHolidayService)) // private publicHolidayService: PublicHolidayService, private configService: ApiConfigService, ) {} @Get() @Whitelist() @Auth([RoleType.ADMIN, RoleType.USER]) @HttpCode(HttpStatus.OK) @ApiPageOkResponse({ type: ActivityRecordDto, description: 'Get activity records list', }) async getActivityRecords( @Query() query: ActivityRecordPageOptionsDto, ): Promise> { return this.activityRecordService.findMany(query); } @Post() @Whitelist() @Auth([RoleType.ADMIN, RoleType.USER]) @HttpCode(HttpStatus.OK) @ApiOkResponse() async createActivityRecord( @AuthUser() user: UserEntity, @Body() body: CreateActivityRecordDto, ): Promise { const { date } = body; const recordDate = moment.utc(date); const currentDate = moment.utc(); const recordDateMonth = moment.utc(date).month(); const currentMonth = moment.utc().month(); const daysDifference = currentDate.diff(recordDate, 'days'); // const publicHolidayEntity = await this.publicHolidayService.findOne({ // date: recordDate.toDate(), // }); // NOTE: Temporary remove this restriction // if (publicHolidayEntity) { // throw new RecordDateIsHolodayException(); // } // NOTE: Temporary remove this restriction // if (recordDate.isoWeekday() >= 6) { // throw new RecordDateIsWeekendException(); // } if (this.configService.isProduction) { if (recordDate > currentDate) { throw new ActivityRecordDateExceedTodayException(); } if (user.role === RoleType.USER && daysDifference > 3) { throw new RecordMoreThan3DaysException(); } if (currentMonth - recordDateMonth >= 1 && currentDate.date() > 7) { throw new AccountHasClosedException(); } } const otRecordEntity = await this.activityRecordService.createActivityRecord(body, user); return otRecordEntity.toDto(); } @Patch(':id') @Whitelist() @Auth([RoleType.ADMIN, RoleType.USER]) @HttpCode(HttpStatus.OK) @ApiOkResponse() async updateActivityRecord( @AuthUser() user: UserEntity, @UUIDParam('id') id: Uuid, @Body() body: UpdateActivityRecordDto, ): Promise { const toPatchEntity = await this.activityRecordService.findOne( { id, }, true, ); if (!toPatchEntity) { throw new ActivityRecordNotFoundException(); } const recordDate = moment.utc(toPatchEntity.date); const currentDate = moment.utc(); const recordDateMonth = moment.utc(toPatchEntity.date).month(); const currentMonth = moment.utc().month(); const daysDifference = currentDate.diff(recordDate, 'days'); // const publicHolidayEntity = await this.publicHolidayService.findOne({ // date: recordDate.toDate(), // }); // NOTE: Temporary remove this restriction // if (publicHolidayEntity) { // throw new RecordDateIsHolodayException(); // } // NOTE: Temporary remove this restriction // if (recordDate.isoWeekday() >= 6) { // throw new RecordDateIsWeekendException(); // } if (this.configService.isProduction) { if (recordDate > currentDate) { throw new ActivityRecordDateExceedTodayException(); } if (user.role === RoleType.USER && daysDifference > 3) { throw new RecordMoreThan3DaysException(); } if (currentMonth - recordDateMonth >= 1 && currentDate.date() > 7) { throw new AccountHasClosedException(); } } const activityRecordEntity = await this.activityRecordService.updateActivityRecord( toPatchEntity, body, user, ); return activityRecordEntity.toDto(); } @Delete(':id') @Whitelist() @Auth([RoleType.ADMIN, RoleType.USER]) @HttpCode(HttpStatus.OK) @ApiOkResponse() async deleteActivityRecord( @AuthUser() user: UserEntity, @UUIDParam('id') id: Uuid, ) { const toDeleteEntity = await this.activityRecordService.findOne( { id, }, true, ); if (!toDeleteEntity) { throw new ActivityRecordNotFoundException(); } const recordDate = moment.utc(toDeleteEntity.date); const currentDate = moment.utc(); const recordDateMonth = moment.utc(toDeleteEntity.date).month(); const currentMonth = moment.utc().month(); const daysDifference = currentDate.diff(recordDate, 'days'); if (this.configService.isProduction) { if (user.role === RoleType.USER && daysDifference > 3) { throw new RecordMoreThan3DaysException(); } if (currentMonth - recordDateMonth >= 1 && currentDate.date() > 7) { throw new AccountHasClosedException(); } } await this.activityRecordService.deleteActivityRecord(toDeleteEntity, user); return { status: 'success' }; } }