diff --git a/src/main/kotlin/dsm/pick2024/domain/afterschool/service/SaveAfterSchoolStudentService.kt b/src/main/kotlin/dsm/pick2024/domain/afterschool/service/SaveAfterSchoolStudentService.kt index 71e946be..293d4c3c 100644 --- a/src/main/kotlin/dsm/pick2024/domain/afterschool/service/SaveAfterSchoolStudentService.kt +++ b/src/main/kotlin/dsm/pick2024/domain/afterschool/service/SaveAfterSchoolStudentService.kt @@ -22,11 +22,11 @@ class SaveAfterSchoolStudentService( val user = findByStudentNumPort.findByStudentNum(grade, classNum, num) AfterSchoolStudent( id = null, - userId = user!!.id!!, + userId = user!!.id, grade = grade, classNum = classNum, num = num, - name = user!!.name, + name = user.name, status1 = Status.ATTENDANCE, status2 = Status.ATTENDANCE, status3 = Status.ATTENDANCE diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/domain/Attendance.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/domain/Attendance.kt new file mode 100644 index 00000000..d68cf991 --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/domain/Attendance.kt @@ -0,0 +1,19 @@ +package dsm.pick2024.domain.attendance.domain + +import dsm.pick2024.domain.afterschool.enums.Status +import java.util.* + +data class Attendance( + val id: UUID? = null, + val userId: UUID, + val grade: Int, + val classNum: Int, + val num: Int, + val name: String, + val club: String, + val period6: Status, + val period7: Status, + val period8: Status, + val period9: Status, + val period10: Status +) diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/entity/AttendanceJpaEntity.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/entity/AttendanceJpaEntity.kt new file mode 100644 index 00000000..2eebadd0 --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/entity/AttendanceJpaEntity.kt @@ -0,0 +1,36 @@ +package dsm.pick2024.domain.attendance.entity + +import dsm.pick2024.domain.afterschool.enums.Status +import dsm.pick2024.global.base.BaseUUIDEntity +import java.util.UUID +import javax.persistence.Column +import javax.persistence.Entity +import javax.persistence.EnumType +import javax.persistence.Enumerated + +@Entity(name = "tbl_attendance") +class AttendanceJpaEntity( + id: UUID?, + @Column(columnDefinition = "BINARY(16)") + val userId: UUID, + @Column(nullable = false) + val name: String, + @Column(nullable = false) + val grade: Int, + @Column(name = "class_num", nullable = false) + val classNum: Int, + @Column(nullable = false) + val num: Int, + @Column(name = "club") + val club: String? = null, + @Enumerated(value = EnumType.STRING) + val period6: Status, + @Enumerated(value = EnumType.STRING) + val period7: Status, + @Enumerated(value = EnumType.STRING) + val period8: Status, + @Enumerated(value = EnumType.STRING) + val period9: Status, + @Enumerated(value = EnumType.STRING) + val period10: Status +) : BaseUUIDEntity(id) diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/mapper/AttendanceMapper.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/mapper/AttendanceMapper.kt new file mode 100644 index 00000000..f886a4ad --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/mapper/AttendanceMapper.kt @@ -0,0 +1,45 @@ +package dsm.pick2024.domain.attendance.mapper + +import dsm.pick2024.domain.attendance.domain.Attendance +import dsm.pick2024.domain.attendance.entity.AttendanceJpaEntity +import dsm.pick2024.global.base.GenericMapper +import org.springframework.stereotype.Component + +@Component +class AttendanceMapper : GenericMapper { + override fun toEntity(domain: Attendance) = + domain.run { + AttendanceJpaEntity( + id = id, + userId = userId, + grade = grade, + classNum = classNum, + num = num, + name = name, + club = club, + period6 = period6, + period7 = period7, + period8 = period8, + period9 = period9, + period10 = period10 + ) + } + + override fun toDomain(entity: AttendanceJpaEntity) = + entity.run { + Attendance( + id = id, + userId = userId, + grade = grade, + classNum = classNum, + num = num, + name = name, + club = club!!, + period6 = period6, + period7 = period7, + period8 = period8, + period9 = period9, + period10 = period10 + ) + } +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/persistence/AttendancePersistenceAdapter.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/persistence/AttendancePersistenceAdapter.kt new file mode 100644 index 00000000..cf4df06c --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/persistence/AttendancePersistenceAdapter.kt @@ -0,0 +1,24 @@ +package dsm.pick2024.domain.attendance.persistence + +import com.querydsl.jpa.impl.JPAQueryFactory +import dsm.pick2024.domain.attendance.domain.Attendance +import dsm.pick2024.domain.attendance.mapper.AttendanceMapper +import dsm.pick2024.domain.attendance.persistence.repository.AttendanceRepository +import dsm.pick2024.domain.attendance.port.out.AttendancePort +import org.springframework.stereotype.Component +import java.util.* + +@Component +class AttendancePersistenceAdapter( + private val attendanceJpaRepository: AttendanceRepository, + private val attendanceMapper: AttendanceMapper, + private val jpaQueryFactory: JPAQueryFactory +) : AttendancePort { + override fun saveAll(attendance: MutableList) { + val entities = attendance.map { attendanceMapper.toEntity(it) } + attendanceJpaRepository.saveAll(entities) + } + + override fun findByUserId(userId: UUID) = + attendanceJpaRepository.findByUserId(userId).let { attendanceMapper.toDomain(it) } +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/persistence/repository/AttendanceRepository.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/persistence/repository/AttendanceRepository.kt new file mode 100644 index 00000000..6fe5a0f7 --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/persistence/repository/AttendanceRepository.kt @@ -0,0 +1,11 @@ +package dsm.pick2024.domain.attendance.persistence.repository + +import dsm.pick2024.domain.attendance.entity.AttendanceJpaEntity +import org.springframework.data.repository.Repository +import java.util.UUID + +interface AttendanceRepository : Repository { + fun saveAll(entity: Iterable) + + fun findByUserId(userId: UUID): AttendanceJpaEntity +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/port/in/ChangeAttendanceUseCase.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/port/in/ChangeAttendanceUseCase.kt new file mode 100644 index 00000000..d3c6202c --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/port/in/ChangeAttendanceUseCase.kt @@ -0,0 +1,7 @@ +package dsm.pick2024.domain.attendance.port.`in` + +import dsm.pick2024.domain.attendance.presentation.dto.request.ChangeAttendanceRequest + +interface ChangeAttendanceUseCase { + fun changeAttendance(request: List) +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/port/in/SaveAllAttendanceUseCase.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/port/in/SaveAllAttendanceUseCase.kt new file mode 100644 index 00000000..04ab706f --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/port/in/SaveAllAttendanceUseCase.kt @@ -0,0 +1,5 @@ +package dsm.pick2024.domain.attendance.port.`in` + +interface SaveAllAttendanceUseCase { + fun saveAll(key: String) +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/AttendancePort.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/AttendancePort.kt new file mode 100644 index 00000000..f3d2577a --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/AttendancePort.kt @@ -0,0 +1,5 @@ +package dsm.pick2024.domain.attendance.port.out + +interface AttendancePort : + SaveAll, + FindByUserIdPort diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/FindByUserIdPort.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/FindByUserIdPort.kt new file mode 100644 index 00000000..0ad4af6c --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/FindByUserIdPort.kt @@ -0,0 +1,8 @@ +package dsm.pick2024.domain.attendance.port.out + +import dsm.pick2024.domain.attendance.domain.Attendance +import java.util.UUID + +interface FindByUserIdPort { + fun findByUserId(userId: UUID): Attendance? +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/SaveAll.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/SaveAll.kt new file mode 100644 index 00000000..149106ef --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/port/out/SaveAll.kt @@ -0,0 +1,7 @@ +package dsm.pick2024.domain.attendance.port.out + +import dsm.pick2024.domain.attendance.domain.Attendance + +interface SaveAll { + fun saveAll(attendance: MutableList) +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/presentation/AttendanceController.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/presentation/AttendanceController.kt new file mode 100644 index 00000000..a262507a --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/presentation/AttendanceController.kt @@ -0,0 +1,31 @@ +package dsm.pick2024.domain.attendance.presentation + +import dsm.pick2024.domain.attendance.port.`in`.ChangeAttendanceUseCase +import dsm.pick2024.domain.attendance.port.`in`.SaveAllAttendanceUseCase +import dsm.pick2024.domain.attendance.presentation.dto.request.ChangeAttendanceRequest +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.web.bind.annotation.PatchMapping +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController + +@Tag(name = "attendance API") +@RestController +@RequestMapping("/attendance") +class AttendanceController( + private val saveAllAttendanceUseCase: SaveAllAttendanceUseCase, + private val changeAttendanceUseCase: ChangeAttendanceUseCase +) { + + @Operation(summary = "데이터 저장 api") + @PostMapping("/all") + fun all(@RequestParam(name = "key") key: String) = + saveAllAttendanceUseCase.saveAll(key) + + @Operation(summary = "자습 or 방과후 상태관리") + @PatchMapping("/modify") + fun changeAttendance(changeAttendanceRequest: List) = + changeAttendanceUseCase.changeAttendance(changeAttendanceRequest) +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/presentation/dto/request/ChangeAttendanceRequest.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/presentation/dto/request/ChangeAttendanceRequest.kt new file mode 100644 index 00000000..0bf9cd0c --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/presentation/dto/request/ChangeAttendanceRequest.kt @@ -0,0 +1,9 @@ +package dsm.pick2024.domain.attendance.presentation.dto.request + +import dsm.pick2024.domain.afterschool.enums.Status +import java.util.UUID + +data class ChangeAttendanceRequest( + val userId: UUID, + val statusList: List +) diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/service/ChangeAttendanceService.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/service/ChangeAttendanceService.kt new file mode 100644 index 00000000..ba2453e1 --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/service/ChangeAttendanceService.kt @@ -0,0 +1,38 @@ +package dsm.pick2024.domain.attendance.service + +import dsm.pick2024.domain.attendance.domain.Attendance +import dsm.pick2024.domain.attendance.port.`in`.ChangeAttendanceUseCase +import dsm.pick2024.domain.attendance.port.out.FindByUserIdPort +import dsm.pick2024.domain.attendance.port.out.SaveAll +import dsm.pick2024.domain.attendance.presentation.dto.request.ChangeAttendanceRequest +import dsm.pick2024.domain.user.exception.UserNotFoundException +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class ChangeAttendanceService( + private val saveAll: SaveAll, + private val findByUserIdPort: FindByUserIdPort +) : ChangeAttendanceUseCase { + + @Transactional + override fun changeAttendance(request: List) { + val update = mutableListOf() + + request.map { + it -> + val attendance = findByUserIdPort.findByUserId(it.userId) + ?: throw UserNotFoundException + val list = it.statusList + val add = attendance.copy( + period6 = list.getOrElse(0) { attendance.period6 }, + period7 = list.getOrElse(1) { attendance.period7 }, + period8 = list.getOrElse(2) { attendance.period8 }, + period9 = list.getOrElse(1) { attendance.period9 }, + period10 = list.getOrElse(2) { attendance.period10 } + ) + update.add(add) + } + saveAll.saveAll(update) + } +} diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/service/SaveAllAttendanceSaveAllUserService.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/service/SaveAllAttendanceSaveAllUserService.kt new file mode 100644 index 00000000..603e8977 --- /dev/null +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/service/SaveAllAttendanceSaveAllUserService.kt @@ -0,0 +1,38 @@ +package dsm.pick2024.domain.attendance.service + +import dsm.pick2024.domain.afterschool.enums.Status +import dsm.pick2024.domain.attendance.domain.Attendance +import dsm.pick2024.domain.attendance.port.`in`.SaveAllAttendanceUseCase +import dsm.pick2024.domain.attendance.port.out.SaveAll +import dsm.pick2024.infrastructure.feign.client.XquareFeignClient +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class SaveAllAttendanceSaveAllUserService( + private val saveAll: SaveAll, + private val xquareFeignClient: XquareFeignClient +) : SaveAllAttendanceUseCase { + + @Transactional + override fun saveAll(key: String) { + val xquare = xquareFeignClient.userAll(key) + val entity = xquare.map { + it -> + Attendance( + userId = it.id, + name = it.name, + grade = it.grade, + classNum = it.classNum, + num = it.num, + club = it.club, + period6 = Status.ATTENDANCE, + period7 = Status.ATTENDANCE, + period8 = Status.ATTENDANCE, + period9 = Status.ATTENDANCE, + period10 = Status.ATTENDANCE + ) + }.toMutableList() + saveAll.saveAll(entity) + } +} diff --git a/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareResponse.kt b/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareResponse.kt index 2360f1d2..1728f1e0 100644 --- a/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareResponse.kt +++ b/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareResponse.kt @@ -12,5 +12,6 @@ data class XquareResponse( val classNum: Int, val num: Int, val userRole: String, + val clubName: String, val birthDay: LocalDate ) diff --git a/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareUserAllResponse.kt b/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareUserAllResponse.kt index 69e709e6..cafe6f1a 100644 --- a/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareUserAllResponse.kt +++ b/src/main/kotlin/dsm/pick2024/infrastructure/feign/client/response/XquareUserAllResponse.kt @@ -7,5 +7,6 @@ data class XquareUserAllResponse( val name: String, val grade: Int, val classNum: Int, - val num: Int + val num: Int, + val club: String )