Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

강의 수강 신청 #78

Merged
merged 28 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f3ee57c
delete :: exception message
ani2689 Oct 25, 2023
8196a23
create :: lecture exception
ani2689 Oct 25, 2023
6c76fdd
add :: findByLectureId method
ani2689 Oct 25, 2023
1e6e309
add :: lecture error code
ani2689 Oct 25, 2023
7c5d1f3
add :: sign up lecture
ani2689 Oct 25, 2023
6f9492f
add :: sign up lecture
ani2689 Oct 25, 2023
206ef8f
add :: sign up lecture
ani2689 Oct 25, 2023
c8377cf
update :: 주석 설명
ani2689 Oct 25, 2023
6dab1a3
add :: security 경로
ani2689 Oct 25, 2023
c64dfbb
fix :: merge
ani2689 Oct 26, 2023
a3c20ba
update :: s 추가
ani2689 Oct 26, 2023
5e5f5bf
update :: date format 수정
ani2689 Oct 27, 2023
4353910
update :: date format 수정
ani2689 Oct 27, 2023
ff4138b
update :: lecture 참조
ani2689 Oct 27, 2023
2ca989d
create :: 이미 신청한 강의에 예외
ani2689 Oct 27, 2023
87ae00d
add :: 이미 신청한 강의에 예외
ani2689 Oct 27, 2023
748b19d
update :: 띄어쓰기
ani2689 Oct 27, 2023
fe6fe9b
update :: Not -> Un
ani2689 Oct 27, 2023
cca4e4b
update :: Not -> Un
ani2689 Oct 27, 2023
3a049aa
update :: Not -> Un
ani2689 Oct 27, 2023
9e73c85
update :: username
ani2689 Oct 27, 2023
9d07083
update :: date 예외 이름 변경
ani2689 Oct 27, 2023
6f4f037
update :: 불편한 띄어쓰기
ani2689 Oct 27, 2023
4d0b7a5
update :: 크거나 같을 때로
ani2689 Oct 27, 2023
5c8db51
add :: Lecture status getter
ani2689 Oct 30, 2023
47c584a
create :: Lecture status
ani2689 Oct 30, 2023
33118a5
update :: Lecture status로 검증
ani2689 Oct 30, 2023
6c41526
Merge remote-tracking branch 'origin/feature-52/sign-up-lecture' into…
ani2689 Oct 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.msg.domain.lecture.exception

import team.msg.domain.lecture.exception.constant.LectureErrorCode
import team.msg.global.error.exception.BitgouelException

class AlreadySignedUpLectureException (
message: String
) : BitgouelException(message, LectureErrorCode.ALREADY_SIGNED_UP_LECTURE.status)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.msg.domain.lecture.exception

import team.msg.domain.lecture.exception.constant.LectureErrorCode
import team.msg.global.error.exception.BitgouelException

class NotAvailableSignUpDateException (
message: String
) : BitgouelException(message, LectureErrorCode.NOT_AVAILABLE_SIGN_UP_DATE.status)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.msg.domain.lecture.exception

import team.msg.domain.lecture.exception.constant.LectureErrorCode
import team.msg.global.error.exception.BitgouelException

class OverMaxRegisteredUserException(
message: String
) : BitgouelException(message, LectureErrorCode.OVER_MAX_REGISTERED_USER.status)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.msg.domain.lecture.exception

import team.msg.domain.lecture.exception.constant.LectureErrorCode
import team.msg.global.error.exception.BitgouelException

class UnApprovedLectureException(
message: String
) : BitgouelException(message, LectureErrorCode.UNAPPROVED_LECTURE.status)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ enum class LectureErrorCode(
val status: Int
){
INVALID_LECTURE_TYPE(400),

LECTURE_NOT_FOUND(404),
ALREADY_APPROVED_LECTURE(409)
}

ALREADY_APPROVED_LECTURE(409),
ALREADY_SIGNED_UP_LECTURE(409),
UNAPPROVED_LECTURE(409),
OVER_MAX_REGISTERED_USER(409),
NOT_AVAILABLE_SIGN_UP_DATE(409)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ class LectureController(
return ResponseEntity.status(HttpStatus.CREATED).build()
}

@PostMapping("/{id}")
fun signUpLecture(@PathVariable id: UUID): ResponseEntity<Void> {
lectureService.signUpLecture(id)
return ResponseEntity.noContent().build()
}

@PatchMapping("/{id}/approve")
fun approveLecture(@PathVariable id: UUID): ResponseEntity<Void> {
lectureService.approveLecture(id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ data class CreateLectureWebRequest(

@field:NotNull
@FutureOrPresent
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:s")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
val startDate: LocalDateTime,

@field:NotNull
@Future
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:s")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
val endDate: LocalDateTime,

@field:NotNull
@Future
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:s")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
val completeDate: LocalDateTime,

@field:NotNull
Expand All @@ -44,4 +44,4 @@ data class CreateLectureWebRequest(
@field:NotNull
@field:Min(1)
val maxRegisteredUser: Int
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import java.util.UUID

interface LectureService {
fun createLecture(request: CreateLectureRequest)
fun signUpLecture(id: UUID)
fun approveLecture(id: UUID)
fun rejectLecture(id: UUID)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,27 @@ import team.msg.common.enum.ApproveStatus
import team.msg.common.util.UserUtil
import team.msg.domain.lecture.enum.LectureType
import team.msg.domain.lecture.exception.AlreadyApprovedLectureException
import team.msg.domain.lecture.exception.AlreadySignedUpLectureException
import team.msg.domain.lecture.exception.InvalidLectureTypeException
import team.msg.domain.lecture.exception.LectureNotFoundException
import team.msg.domain.lecture.exception.NotAvailableSignUpDateException
import team.msg.domain.lecture.exception.OverMaxRegisteredUserException
import team.msg.domain.lecture.exception.UnApprovedLectureException
import team.msg.domain.lecture.model.Lecture
import team.msg.domain.lecture.model.RegisteredLecture
import team.msg.domain.lecture.presentation.data.request.CreateLectureRequest
import team.msg.domain.lecture.repository.LectureRepository
import team.msg.domain.lecture.repository.RegisteredLectureRepository
import team.msg.domain.student.exception.StudentNotFoundException
import team.msg.domain.student.repository.StudentRepository
import java.time.LocalDateTime
import java.util.*

@Service
class LectureServiceImpl(
private val lectureRepository: LectureRepository,
private val registeredLectureRepository: RegisteredLectureRepository,
private val studentRepository: StudentRepository,
private val userUtil: UserUtil
) : LectureService{

Expand Down Expand Up @@ -51,9 +62,50 @@ class LectureServiceImpl(
lectureRepository.save(lecture)
}

/**
* 강의에 대해 수강신청하는 비지니스 로직입니다.
* @param 수강신청을 하기 위한 강의 id
*/
@Transactional(rollbackFor = [Exception::class])
override fun signUpLecture(id: UUID) {
val user = userUtil.queryCurrentUser()

val student = studentRepository.findByIdOrNull(user.id)
?: throw StudentNotFoundException("학생을 찾을 수 없습니다. info : [ userId = ${user.id}, username = ${user.name} ]")

val lecture = queryLecture(id)

if(lecture.approveStatus == ApproveStatus.PENDING)
throw UnApprovedLectureException("아직 승인되지 않은 강의입니다. info : [ lectureId = ${lecture.id} ]")

if(lecture.startDate.isBefore(LocalDateTime.now()))
throw NotAvailableSignUpDateException("이른 강의 신청입니다. info : [ lectureStartDate = ${lecture.startDate}, currentDate = ${LocalDateTime.now()} ]")

if(lecture.endDate.isAfter(LocalDateTime.now()))
throw NotAvailableSignUpDateException("늦은 강의 신청입니다. info : [ lectureEndDate = ${lecture.endDate}, currentDate = ${LocalDateTime.now()} ]")
ani2689 marked this conversation as resolved.
Show resolved Hide resolved

if(registeredLectureRepository.existsByStudentAndLecture(student, lecture))
throw AlreadySignedUpLectureException("이미 신청한 강의입니다. info : [ lectureId = ${lecture.id}, studentId = ${student.id} ]")

val currentSignUpLectureStudent = registeredLectureRepository.findAllByLecture(lecture).size

if(lecture.maxRegisteredUser == currentSignUpLectureStudent)
throw OverMaxRegisteredUserException("수강 인원이 가득 찼습니다. info : [ maxRegisteredUser = ${lecture.maxRegisteredUser}, currentSignUpLectureStudent = $currentSignUpLectureStudent ]")

ani2689 marked this conversation as resolved.
Show resolved Hide resolved
val registeredLecture = RegisteredLecture(
id = UUID.randomUUID(),
student = student,
lecture = lecture,
completeDate = lecture.completeDate
)

registeredLectureRepository.save(registeredLecture)

}

/**
* 강의 개설 신청을 수락하는 비지니스 로직입니다.
* @param 승인할 강의의 id
* @param 개설을 수락할 대기 상태의 강의 id
*/
@Transactional(rollbackFor = [Exception::class])
override fun approveLecture(id: UUID) {
Expand All @@ -72,16 +124,17 @@ class LectureServiceImpl(
content = lecture.content,
lectureType = lecture.lectureType,
credit = lecture.credit,
instructor = lecture.user.name,
maxRegisteredUser = lecture.maxRegisteredUser
instructor = lecture.instructor,
maxRegisteredUser = lecture.maxRegisteredUser,
approveStatus = ApproveStatus.APPROVED
)

lectureRepository.save(approveLecture)
}

/**
* 강의 개설 신청을 거절하는 비지니스 로직입니다.
* @param 거절할 강의의 id
* @param 개설을 거절할 대기 상태의 강의 id
*/
@Transactional(rollbackFor = [Exception::class])
override fun rejectLecture(id: UUID) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ class SecurityConfig(

// lecture
.mvcMatchers(HttpMethod.POST, "/lecture").hasAnyRole(PROFESSOR, COMPANY_INSTRUCTOR, GOVERNMENT)
.mvcMatchers(HttpMethod.PATCH, "/lecture/{id}/approve").hasAnyRole(ADMIN)
.mvcMatchers(HttpMethod.DELETE, "/lecture/{id}/reject").hasAnyRole(ADMIN)
.mvcMatchers(HttpMethod.POST, "/lecture/{id}").hasRole(STUDENT)
.mvcMatchers(HttpMethod.PATCH, "/lecture/{id}/approve").hasRole(ADMIN)
.mvcMatchers(HttpMethod.DELETE, "/lecture/{id}/reject").hasRole(ADMIN)

// faq
.mvcMatchers(HttpMethod.POST, "/faq").hasRole(ADMIN)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package team.msg.domain.lecture.repository

import org.springframework.data.repository.CrudRepository
import team.msg.domain.lecture.model.Lecture
import team.msg.domain.lecture.model.RegisteredLecture
import team.msg.domain.student.model.Student
import java.util.UUID

interface RegisteredLectureRepository : CrudRepository<RegisteredLecture,UUID> {
fun findAllByStudent(student: Student): List<RegisteredLecture>
fun findAllByLecture(lecture: Lecture): List<RegisteredLecture>
fun existsByStudentAndLecture(student: Student, lecture: Lecture): Boolean
}