/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */ /* eslint-disable no-await-in-loop */ import { Controller, Get, HttpCode, HttpStatus, Query, Req, UnauthorizedException, } from '@nestjs/common'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; import { Request } from 'express'; import moment from 'moment'; import { PartialIncentiveName } from '../../constants'; import { Auth, AuthUser, Whitelist } from '../../decorators'; import { ValidatorService } from '../../shared/services/validator.service'; import { ActivityGroupService } from '../activity-record/activity-group.service'; import { ActivityRecordService } from '../activity-record/activity-record.service'; import { ActivityRecordSettingService } from '../activity-record/activity-record-setting.service'; import { AdminConfigService } from '../admin-config/admin-config.service'; import { AuditLogService } from '../audit-log/audit-log.service'; import { BlockService } from '../block/block.service'; import { EmployeeService } from '../employee/employee.service'; import { IncentiveRecordService } from '../incentive/incentive-record.service'; import { IncentiveSettingService } from '../incentive/incentive-settings.service'; import { MonthlyRecordService } from '../monthly-record/monthly-record.service'; import { OtRecordService } from '../ot/ot-record.service'; import { PublicHolidayService } from '../public-holiday/public-holiday.service'; import { RainfallRecordService } from '../rainfall/rainfall.service'; import { SectorService } from '../sector/sector.service'; import { UserEntity } from '../user/user.entity'; import { UserService } from '../user/user.service'; import { VehicleNameService } from '../vehicle/vehicle-name.service'; import { VehicleRecordService } from '../vehicle/vehicle-record.service'; import { GetDropdownDto } from './dtos/get-dropdown.dto'; import { GetActivityDto } from './dtos/get-report-activity.dto'; import { GetAuditLogDto } from './dtos/get-report-audit-log.dto'; import { GetByEmployeeDto } from './dtos/get-report-by-employee.dto'; import { GetIncentiveDto } from './dtos/get-report-incentive.dto'; import { GetOtDto } from './dtos/get-report-ot.dto'; import { GetRainfallDto } from './dtos/get-report-rainfall.dto'; import { GetVehicleDto } from './dtos/get-report-vehicle.dto'; import { GetUnfinisedReportDto } from './dtos/get-unfinised-report.dto'; @Controller('report') @ApiTags('report') export class ReportController { constructor( private employeeService: EmployeeService, private activityRecordSettingService: ActivityRecordSettingService, private activityRecordService: ActivityRecordService, private activityGroupService: ActivityGroupService, private otRecordService: OtRecordService, private monthlyRecordService: MonthlyRecordService, private incentiveRecordService: IncentiveRecordService, private incentiveSettingService: IncentiveSettingService, private validatorService: ValidatorService, private rainfallService: RainfallRecordService, private vehicleService: VehicleRecordService, private vehicleNameService: VehicleNameService, private blockService: BlockService, private sectorService: SectorService, private publicHolidayService: PublicHolidayService, private adminConfigService: AdminConfigService, private auditLogService: AuditLogService, private userService: UserService, ) {} @Get('employee-info') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getEmployees(@Req() req: Request, @Query() query: GetByEmployeeDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.employeeService.findManyByReportFunction(query); } @Get('employee-sector') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getSectorSum(@Req() req: Request, @Query() query: GetByEmployeeDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } const employees = await this.employeeService.findManyByReportFunction(query); const returnData: unknown[] = []; for (const employee of employees) { returnData.push( this.activityRecordService.getSummaryActivityByEmployee( query, employee, ), ); } return Promise.all(returnData); } @Get('employee-ot') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getOtSum(@Req() req: Request, @Query() query: GetByEmployeeDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } const employees = await this.employeeService.findManyByReportFunction(query); const returnData: unknown[] = []; for (const employee of employees) { returnData.push( this.otRecordService.getSummaryOTByEmployee(query, employee), ); } return Promise.all(returnData); } @Get('employee-incentive') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getIncentiveSum(@Req() req: Request, @Query() query: GetByEmployeeDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } const employees = await this.employeeService.findManyByReportFunction(query); const returnData: unknown[] = []; for (const employee of employees) { returnData.push( this.incentiveRecordService.getSummaryIncentiveByEmployee( query, employee, ), ); } return Promise.all(returnData); } @Get('employee-monthly') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getMonthlyRecord( @Req() req: Request, @Query() query: GetByEmployeeDto, ) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } const employees = await this.employeeService.findManyByReportFunction(query); const returnData: unknown[] = []; for (const employee of employees) { returnData.push( this.monthlyRecordService.getSummarMonthlyByEmployee(query, employee), ); } return Promise.all(returnData); } @Get('activity') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getActivityRecords( @Req() req: Request, @Query() query: GetActivityDto, ) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.activityRecordService.findReportMany(query); } @Get('activity-sum') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getActivitySumRecords( @Req() req: Request, @Query() query: GetActivityDto, ) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.activityRecordService.findByActivitySum(query); } @Get('ot') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getOtRecords(@Req() req: Request, @Query() query: GetOtDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.otRecordService.findReportMany(query); } @Get('incentive') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getIncentiveRecords( @Req() req: Request, @Query() query: GetIncentiveDto, ) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.incentiveRecordService.findReportMany(query); } @Get('rainfall') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getRainfallRecords( @Req() req: Request, @Query() query: GetRainfallDto, ) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.rainfallService.findReportMany(query); } @Get('vehicle') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getVehicleRecords(@Req() req: Request, @Query() query: GetVehicleDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.vehicleService.findReportMany(query); } @Get('dropdown') @Whitelist() @HttpCode(HttpStatus.OK) @ApiOkResponse() @Auth([], { public: true }) async getDropdown( @Req() req: Request, @Query() query: GetDropdownDto, @AuthUser() user?: UserEntity, ) { if (!user) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } } const employeeName = await this.employeeService.findManyDropdown({ date: query.date, shouldFilter: query.shouldFilter, showInactive: query.showInactive, }); const blockName = await this.blockService.findManyDropdown( query.showInactive, ); const activityName = await this.activityRecordSettingService.findManyDropdown({ date: query.date, shouldShowInOtfilter: query.shouldShowInOtfilter, showInactive: query.showInactive, }); const incentiveName = await this.incentiveSettingService.findManyDropdown( query.showInactive, ); const partialIncentiveName = incentiveName.filter( (el) => el.name === PartialIncentiveName.FRUIT_HARVEST || el.name === PartialIncentiveName.SUCKER_HARVEST || el.name === PartialIncentiveName.SUCKER_PLANTING || el.name === 'None', ); const sectorName = await this.sectorService.findManyDropdown(); const activityGroupName = await this.activityGroupService.findManyDropdown(); const vehicleName = await this.vehicleNameService.findManyDropdown(); const fullSelectionEmployee = [...employeeName]; const activitySettingEntityArr = await this.activityRecordSettingService.findManyWithoutPagination(); const incentiveSettingEntityArr = await this.incentiveSettingService.findManyWithoutPagination(); const userEntityArr = await this.userService.findMany(); const userArr = userEntityArr.map((el: UserEntity) => el.toDto()); fullSelectionEmployee.push({ name: 'None', value: null, }); return { employeeName, blockName, activityName, incentiveName, sectorName, activityGroupName, partialIncentiveName, vehicleName, fullSelectionEmployee, activitySettingEntityArr, incentiveSettingEntityArr, userArr, }; } @Get('unfinished-activity-record') @Whitelist() @HttpCode(HttpStatus.OK) @ApiOkResponse() @Auth([], { public: true }) // eslint-disable-next-line sonarjs/cognitive-complexity async getUnfinishedActivityRecords( @Req() req: Request, @Query() query: GetUnfinisedReportDto, @AuthUser() user?: UserEntity, ) { if (!user) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } } const employees = await this.employeeService.findManyWithoutPagination({ isActive: true, }); if (employees.length === 0) { return []; } const toReturnArr: Array<{ date: Date; employee: string; currentHour: number; expectedHour: number; }> = []; let toDeductDay = 0; for (let i = 0; i < query.days; i++) { const toCheckDate = moment.utc().startOf('date').add(-toDeductDay, 'day'); let shouldCheckHolidayAndWeekend = true; while (shouldCheckHolidayAndWeekend) { const publicHolidayEntity = await this.publicHolidayService.findOne({ date: toCheckDate.toDate(), }); //NOTE: Temporary disable weekend check // if (publicHolidayEntity || toCheckDate.isoWeekday() >= 6) { if (publicHolidayEntity) { toDeductDay++; toCheckDate.add(-1, 'day'); } else { shouldCheckHolidayAndWeekend = false; } } for (const employee of employees) { const currentDateSumHour = await this.activityRecordService.getEmployeeDayHour( toCheckDate.toDate(), employee, ); if (currentDateSumHour < 8) { toReturnArr.push({ date: toCheckDate.toDate(), employee: employee.name, currentHour: currentDateSumHour, expectedHour: 8, }); } } toDeductDay++; } return toReturnArr; } @Get('employee-advance-info') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getAdvanceInfo(@Req() req: Request, @Query() query: GetByEmployeeDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } const employees = await this.employeeService.findManyByReportFunction(query); const adminConfig = await this.adminConfigService.findOne(); const returnData: unknown[] = []; for (const employee of employees) { returnData.push( this.activityRecordService.getAdvanceInfoByEmployee( query, employee, adminConfig, ), ); } return Promise.all(returnData); } @Get('employee-rest-day-wages-info') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getRestDayWagesInfo( @Req() req: Request, @Query() query: GetByEmployeeDto, ) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } const employees = await this.employeeService.findManyByReportFunction(query); const adminConfig = await this.adminConfigService.findOne(); const returnData: unknown[] = []; for (const employee of employees) { returnData.push( this.activityRecordService.getRestDayWagesInfoByEmployee( query, employee, adminConfig, ), ); } return Promise.all(returnData); } @Get('audit-log') @HttpCode(HttpStatus.OK) @ApiOkResponse() async getAuditLog(@Req() req: Request, @Query() query: GetAuditLogDto) { const { hostname, url, protocol, headers } = req; const isValidate = this.validatorService.validateSignature({ hostname, url, protocol, timestamp: Number(headers['x-report-timestamp']), signature: headers['x-report-signature'] && !Array.isArray(headers['x-report-signature']) ? headers['x-report-signature'] : '', }); if (!isValidate) { throw new UnauthorizedException('invalid signature'); } return this.auditLogService.findReportMany(query); } }