Skip to content
This repository has been archived by the owner on Dec 16, 2024. It is now read-only.

Commit

Permalink
feat: implements attendance statistic page
Browse files Browse the repository at this point in the history
  • Loading branch information
jspark2000 committed Mar 14, 2024
1 parent 50e1650 commit ceff3db
Show file tree
Hide file tree
Showing 20 changed files with 803 additions and 85 deletions.
28 changes: 27 additions & 1 deletion backend/app/src/attendance/attendance.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
import { Controller } from '@nestjs/common'
import { Controller, Get, ParseIntPipe, Query } from '@nestjs/common'
import { Roles } from '@libs/decorator'
import { BusinessExceptionHandler } from '@libs/exception'
import { Role } from '@prisma/client'
import { AttendanceService } from './attendance.service'
import type { AttendanceWithRoster } from './dto/attendance.dto'

@Controller('attendances')
export class AttendanceController {
constructor(private readonly attendanceService: AttendanceService) {}

@Get('')
@Roles(Role.Manager)
async getAttendances(
@Query('scheduleId', ParseIntPipe) scheduleId: number,
@Query('page', ParseIntPipe) page: number,
@Query('searchTerm') searchTerm: string,
@Query('limit', new ParseIntPipe({ optional: true })) limit?: number,
@Query('rosterType') rosterType?: string
): Promise<{ attendances: AttendanceWithRoster[]; total: number }> {
try {
return await this.attendanceService.getAttendances(
scheduleId,
searchTerm,
page,
rosterType,
limit
)
} catch (error) {
BusinessExceptionHandler(error)
}
}
}
101 changes: 75 additions & 26 deletions backend/app/src/attendance/attendance.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,53 +50,94 @@ export class AttendanceService {

async getAttendances(
scheduleId: number,
searchTerm: string,
searchTerm = '',
page: number,
rosterType?: string,
limit = 10
): Promise<{ attendances: AttendanceWithRoster[] }> {
): Promise<{ attendances: AttendanceWithRoster[]; total: number }> {
try {
const attendances = await this.prisma.attendance.findMany({
where: {
scheduleId,
Roster: {
OR: [
AND: [
{
offPosition: {
contains: searchTerm
},
defPosition: {
contains: searchTerm
},
splPosition: {
contains: searchTerm
}
type: this.transformRosterType(rosterType)
},
{
OR: [
{
offPosition: {
contains: searchTerm
}
},
{
defPosition: {
contains: searchTerm
}
},
{
splPosition: {
contains: searchTerm
}
}
]
}
]
}
},
include: {
Roster: {
select: {
id: true,
name: true,
type: true,
registerYear: true,
offPosition: true,
defPosition: true,
splPosition: true
}
}
Roster: true
},
take: limit,
skip: calculatePaginationOffset(page, limit),
orderBy: {
orderBy: [
{
Roster: {
admissionYear: 'asc'
}
},
{
Roster: {
name: 'asc'
}
}
]
})

const total = await this.prisma.attendance.count({
where: {
scheduleId,
Roster: {
name: 'asc'
AND: [
{
type: this.transformRosterType(rosterType)
},
{
OR: [
{
offPosition: {
contains: searchTerm
}
},
{
defPosition: {
contains: searchTerm
}
},
{
splPosition: {
contains: searchTerm
}
}
]
}
]
}
}
})

return { attendances }
return { attendances, total }
} catch (error) {
throw new UnexpectedException(error)
}
Expand Down Expand Up @@ -244,4 +285,12 @@ export class AttendanceService {

return positionCounts
}

private transformRosterType(rosterType: string): RosterType {
try {
return RosterType[rosterType]
} catch (error) {
return RosterType.Athlete
}
}
}
12 changes: 2 additions & 10 deletions backend/app/src/attendance/dto/attendance.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
AttendanceLocation,
AttendanceResponse,
type Attendance,
type RosterType
type Roster
} from '@prisma/client'
import {
IsEnum,
Expand Down Expand Up @@ -50,13 +50,5 @@ export class UpdateAttendanceDTO {

export interface AttendanceWithRoster extends Attendance {
// eslint-disable-next-line @typescript-eslint/naming-convention
Roster: {
id: number
name: string
type: RosterType
registerYear: number
offPosition?: string
defPosition?: string
splPosition?: string
}
Roster: Roster
}
9 changes: 6 additions & 3 deletions backend/app/src/roster/roster.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@ export class RosterService {
},
take: limit,
skip: calculatePaginationOffset(page, limit),
orderBy: {
name: 'asc'
}
orderBy: [
{
admissionYear: 'asc',
name: 'asc'
}
]
})

const total = await this.prisma.roster.count({
Expand Down
25 changes: 25 additions & 0 deletions backend/app/src/survey/survey.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,31 @@ export class SurveyController {
}
}

@Public()
@Get('/schedules')
async getSchedules(
@Query('page', ParseIntPipe) page: number,
@Query('limit', new ParseIntPipe({ optional: true })) limit?: number
): Promise<{ schedules: Schedule[]; total: number }> {
try {
return await this.surveyService.getSchedules(page, limit)
} catch (error) {
BusinessExceptionHandler(error)
}
}

@Public()
@Get('/schedules/:scheduleId')
async getSchedule(
@Param('scheduleId', ParseIntPipe) scheduleId: number
): Promise<Schedule> {
try {
return await this.surveyService.getSchedule(scheduleId)
} catch (error) {
BusinessExceptionHandler(error)
}
}

@Public()
@Get('/groups')
async getSurveyGroups(
Expand Down
39 changes: 39 additions & 0 deletions backend/app/src/survey/survey.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,45 @@ export class SurveyService {
}
}

async getSchedules(
page: number,
limit = 10
): Promise<{ schedules: Schedule[]; total: number }> {
try {
const schedules = await this.prisma.schedule.findMany({
take: limit,
skip: calculatePaginationOffset(page, limit),
orderBy: {
startedAt: 'desc'
}
})

const total = await this.prisma.schedule.count()

return { schedules, total }
} catch (error) {
throw new UnexpectedException(error)
}
}

async getSchedule(scheduleId: number): Promise<Schedule> {
try {
return await this.prisma.schedule.findUniqueOrThrow({
where: {
id: scheduleId
}
})
} catch (error) {
if (
error instanceof Prisma.PrismaClientKnownRequestError &&
error.code === 'P2025'
) {
throw new EntityNotExistException('일정이 존재하지 않습니다')
}
throw new UnexpectedException(error)
}
}

async createSurveyGroup(
surveyGroupDTO: CreateSurveyGroupDTO
): Promise<SurveyGroup> {
Expand Down
Loading

0 comments on commit ceff3db

Please sign in to comment.