diff --git a/src/main/kotlin/domain/CourseManager.kt b/src/main/kotlin/domain/CourseManager.kt new file mode 100644 index 0000000..e3b65e0 --- /dev/null +++ b/src/main/kotlin/domain/CourseManager.kt @@ -0,0 +1,6 @@ +package domain + +import domain.entity.Application +import domain.entity.Course +import domain.entity.Status + diff --git a/src/main/kotlin/domain/entity/CourseTakingApplicationList.kt b/src/main/kotlin/domain/CourseTakingApplicationList.kt similarity index 61% rename from src/main/kotlin/domain/entity/CourseTakingApplicationList.kt rename to src/main/kotlin/domain/CourseTakingApplicationList.kt index 57b5617..d97dcc1 100644 --- a/src/main/kotlin/domain/entity/CourseTakingApplicationList.kt +++ b/src/main/kotlin/domain/CourseTakingApplicationList.kt @@ -1,4 +1,6 @@ -package domain.entity +package domain + +import domain.entity.* class CourseTakingApplicationList( private val id: StudentId, @@ -15,20 +17,17 @@ class CourseTakingApplicationList( } fun addCourseTakingApplication(courseTakingApplication: CourseTakingApplication) { - if (checkCanAdd(courseTakingApplication)){ - courseTakingApplications.add(courseTakingApplication) - updateCredits() - }else { - throw IllegalStateException("取得可能な単位数を超過しています。") - } + courseTakingApplications.add(courseTakingApplication) + updateCredits() } + fun removeCourseTakingApplication(courseTakingApplicationId: CourseTakingApplicationId) { - courseTakingApplications.remove(getCourseTakingApplicationOfId(courseTakingApplicationId)) - updateCredits() + courseTakingApplications.remove(getCourseTakingApplicationOfId(courseTakingApplicationId)) + updateCredits() } - private fun checkCanAdd(courseTakingApplication: CourseTakingApplication): Boolean { - return maxCredits >= credits + courseTakingApplication.getCourse().getCredit() + fun isWithinLimit(): Boolean { + return maxCredits >= credits } private fun updateCredits() { diff --git a/src/main/kotlin/domain/entity/Course.kt b/src/main/kotlin/domain/entity/Course.kt index f1ba6aa..c6ff70c 100644 --- a/src/main/kotlin/domain/entity/Course.kt +++ b/src/main/kotlin/domain/entity/Course.kt @@ -34,12 +34,16 @@ class Course( return max } - fun getCredit():Int { + fun getCredit(): Int { return credit } } data class DowAndPeriod( - val dow: String, + val dow: Dow, val period: String -) \ No newline at end of file +) + +enum class Dow { + Monday, Tuesday, Wednesday, Thursday, Friday +} \ No newline at end of file diff --git a/src/main/kotlin/domain/entity/CourseTakingApplication.kt b/src/main/kotlin/domain/entity/CourseTakingApplication.kt index 83caa86..e3ad115 100644 --- a/src/main/kotlin/domain/entity/CourseTakingApplication.kt +++ b/src/main/kotlin/domain/entity/CourseTakingApplication.kt @@ -28,7 +28,6 @@ class CourseTakingApplication( } /*抽選で当選する*/ - fun confirm() { if (state == State.UNCONFIRMED) state = State.CONFIRMED @@ -45,4 +44,35 @@ class CourseTakingApplication( enum class State { UNCONFIRMED, CONFIRMED, INVALIDATED -} \ No newline at end of file +} + +/*システムで扱うクラス*/ +class Application( + val id: String, + val student: Student, + val course: Course, + private var status: Status, +) { + fun getStatus() = status + fun markAsRegistered() { + status = Status.REGISTERED + } + + fun markAsRejected() { + status = Status.REJECTED + } +} + +enum class Status { + NOT_REGISTERED, + REGISTERED, + REJECTED +} + +/*永続化するデータのクラス*/ +class ApplicationData( + val id: String, + val studentId: String, + val courseId: String, + private var status: Status, +) \ No newline at end of file diff --git a/src/main/kotlin/domain/service/CourseTakingApplicationService.kt b/src/main/kotlin/domain/service/CourseTakingApplicationService.kt index 61e5463..fcff300 100644 --- a/src/main/kotlin/domain/service/CourseTakingApplicationService.kt +++ b/src/main/kotlin/domain/service/CourseTakingApplicationService.kt @@ -1,12 +1,13 @@ package domain.service +import domain.CourseTakingApplicationList import domain.entity.* interface CourseTakingApplicationService { suspend fun applyCourseTaking( courseTakingApplicationId: CourseTakingApplicationId, studentId: StudentId, courseId: CourseId - ) : CourseTakingApplicationList + ) : CourseTakingApplicationList? suspend fun cancelCourseTaking(studentId: StudentId, courseTakingApplicationId: CourseTakingApplicationId) : CourseTakingApplicationList suspend fun getCourseTakingApplications(studentId: StudentId): CourseTakingApplicationList } diff --git a/src/main/kotlin/domain/service/impl/CourseTakingApplicationServiceImpl.kt b/src/main/kotlin/domain/service/impl/CourseTakingApplicationServiceImpl.kt index e1f77b8..5a29798 100644 --- a/src/main/kotlin/domain/service/impl/CourseTakingApplicationServiceImpl.kt +++ b/src/main/kotlin/domain/service/impl/CourseTakingApplicationServiceImpl.kt @@ -3,7 +3,9 @@ package domain.service.impl import data.repository.CourseTakingApplicationsRepository import data.repository.CoursesRepository +import domain.CourseTakingApplicationList import domain.entity.* + import domain.service.CourseTakingApplicationService /* @@ -11,7 +13,7 @@ import domain.service.CourseTakingApplicationService * * */ class CourseTakingApplicationServiceImpl( - private val courseTakingApplicationRepository: CourseTakingApplicationsRepository, + private val courseTakingApplicationsRepository: CourseTakingApplicationsRepository, private val coursesRepository: CoursesRepository ) : CourseTakingApplicationService { @@ -21,14 +23,17 @@ class CourseTakingApplicationServiceImpl( courseTakingApplicationId: CourseTakingApplicationId, studentId: StudentId, courseId: CourseId - ): CourseTakingApplicationList { + ): CourseTakingApplicationList? { val courseTakingApplicationList = getCourseTakingApplicationList(studentId) val newCourseTakingApplication = createCourseTakingApplication(courseTakingApplicationId,studentId,courseId) courseTakingApplicationList.addCourseTakingApplication(newCourseTakingApplication) - courseTakingApplicationRepository.save(newCourseTakingApplication) - - return courseTakingApplicationList + if(courseTakingApplicationList.isWithinLimit()){ + courseTakingApplicationsRepository.save(newCourseTakingApplication) + return courseTakingApplicationList + }else{ + throw Exception("取得可能な単位数を超過しています。") + } } override suspend fun cancelCourseTaking( @@ -38,7 +43,7 @@ class CourseTakingApplicationServiceImpl( val courseTakingApplicationList = getCourseTakingApplicationList(studentId) courseTakingApplicationList.removeCourseTakingApplication(courseTakingApplicationId) - courseTakingApplicationRepository.delete(courseTakingApplicationId) + courseTakingApplicationsRepository.delete(courseTakingApplicationId) return courseTakingApplicationList } @@ -49,7 +54,7 @@ class CourseTakingApplicationServiceImpl( /*CourseTakingApplicationListの生成*/ private suspend fun getCourseTakingApplicationList(studentId: StudentId): CourseTakingApplicationList { - val courseTakingApplications = courseTakingApplicationRepository.findByStudentId(studentId) + val courseTakingApplications = courseTakingApplicationsRepository.findByStudentId(studentId) return CourseTakingApplicationList( studentId, courseTakingApplications.toMutableList(), diff --git a/src/main/kotlin/latestModel/Application.kt b/src/main/kotlin/latestModel/Application.kt new file mode 100644 index 0000000..2f5ec2b --- /dev/null +++ b/src/main/kotlin/latestModel/Application.kt @@ -0,0 +1,25 @@ +package latestModel + + +/*システムで扱うクラス*/ +class Application( + val id: String = "", + val student: Student = Student(), + val course: Course = Course(), + private var status: Status = Status.CREATED, +) { + fun getStatus() = status + fun markAsRegistered() { + status = Status.REGISTERED + } + + fun markAsRejected() { + status = Status.REJECTED + } +} + +enum class Status { + CREATED, + REGISTERED, + REJECTED +} diff --git a/src/main/kotlin/latestModel/Course.kt b/src/main/kotlin/latestModel/Course.kt new file mode 100644 index 0000000..0a9ffb7 --- /dev/null +++ b/src/main/kotlin/latestModel/Course.kt @@ -0,0 +1,7 @@ +package latestModel + +class Course( + val id: String = "", + val credit: Int = 0, + val capacity: Int = 0, +) \ No newline at end of file diff --git a/src/main/kotlin/latestModel/CourseManager.kt b/src/main/kotlin/latestModel/CourseManager.kt new file mode 100644 index 0000000..6233db6 --- /dev/null +++ b/src/main/kotlin/latestModel/CourseManager.kt @@ -0,0 +1,18 @@ +package latestModel + +class CourseManager( + private val course: Course, + private val applications:List +) { + fun canApplyWithFirstArrival():Boolean = applications.size <= course.capacity + + fun selectApplications(){ + /*落選したApplicationをRejected状態にする*/ + applications.subList(0,3).forEach { it.markAsRejected() } + } + + fun registerMembers(){ + /*登録するApplicationをRegistered状態にする*/ + applications.filterNot { it.getStatus() == Status.REJECTED }.forEach { it.markAsRegistered() } + } +} \ No newline at end of file diff --git a/src/main/kotlin/latestModel/CourseSchedule.kt b/src/main/kotlin/latestModel/CourseSchedule.kt new file mode 100644 index 0000000..245ec2d --- /dev/null +++ b/src/main/kotlin/latestModel/CourseSchedule.kt @@ -0,0 +1,38 @@ +package latestModel + + +class CourseSchedule( + private val applications: List +) { + private val MAX_CREDITS = 24 + + private fun totalCredit(): Int = applications.filterNot { it.getStatus() == Status.REJECTED }.size + + private fun checkNotOver(): Boolean = totalCredit() <= MAX_CREDITS + + fun apply(student: Student, course: Course): Result { + val newApplication = createApplication(student, course) + applications + newApplication + + if (checkNotOver()) { + return Result.success(Unit) + } else { + return Result.failure(Exception("最大取得単位数を超過")) + } + } + + fun cancel(applicationId: String): Result { + val application = applications.find { it.id == applicationId } + ?: return Result.failure(Exception("存在しないid")) + + if (application.getStatus() == Status.CREATED) { + return Result.success(Unit) + } else { + return Result.failure(Exception("キャンセル不可")) + } + } + + private fun createApplication(student: Student, course: Course): Application { + return Application("applicationId", student, course, Status.CREATED) + } +} diff --git a/src/main/kotlin/latestModel/Student.kt b/src/main/kotlin/latestModel/Student.kt new file mode 100644 index 0000000..c454b31 --- /dev/null +++ b/src/main/kotlin/latestModel/Student.kt @@ -0,0 +1,5 @@ +package latestModel + +class Student( + val id: String = "" +) \ No newline at end of file diff --git a/src/main/kotlin/latestModel/dataStore/ApplicationsDataStore.kt b/src/main/kotlin/latestModel/dataStore/ApplicationsDataStore.kt new file mode 100644 index 0000000..7d96637 --- /dev/null +++ b/src/main/kotlin/latestModel/dataStore/ApplicationsDataStore.kt @@ -0,0 +1,14 @@ +package latestModel.dataStore + +import latestModel.Application + + +interface ApplicationsDataStore { + fun findById(applicationId:String):Application + fun findByCourseId(courseId:String):List + fun findByStudentId(studentId:String):List + + fun save(application: Application) + fun save(applications: List) + fun delete(applicationId: String) +} \ No newline at end of file diff --git a/src/main/kotlin/latestModel/dataStore/CourseMembersDataStore.kt b/src/main/kotlin/latestModel/dataStore/CourseMembersDataStore.kt new file mode 100644 index 0000000..604af23 --- /dev/null +++ b/src/main/kotlin/latestModel/dataStore/CourseMembersDataStore.kt @@ -0,0 +1,9 @@ +package latestModel.dataStore + +import latestModel.Student + + +interface CourseMembersDataStore { + + fun save(members:List) +} \ No newline at end of file diff --git a/src/main/kotlin/latestModel/dataStore/StudentDataStore.kt b/src/main/kotlin/latestModel/dataStore/StudentDataStore.kt new file mode 100644 index 0000000..b5521d0 --- /dev/null +++ b/src/main/kotlin/latestModel/dataStore/StudentDataStore.kt @@ -0,0 +1,4 @@ +package latestModel.dataStore + +interface StudentDataStore { +} \ No newline at end of file diff --git a/src/main/kotlin/latestModel/useCase/apply.kt b/src/main/kotlin/latestModel/useCase/apply.kt new file mode 100644 index 0000000..096a48c --- /dev/null +++ b/src/main/kotlin/latestModel/useCase/apply.kt @@ -0,0 +1,24 @@ +package latestModel.useCase + +import latestModel.* +import latestModel.dataStore.ApplicationsDataStore + + +fun apply( + studentId: String, + courseId: String, +) { + /*IO*/ + val applications = listOf() + val myApplications = listOf() + val course = Course(courseId) + val student = Student(studentId) + + /*aggregate*/ + val courseSchedule = CourseSchedule(myApplications) + courseSchedule.apply(student, course) + + /*IO*/ + //dataStore.save(newApplication) +} + diff --git a/src/main/kotlin/latestModel/useCase/applyAsFirstserve.kt b/src/main/kotlin/latestModel/useCase/applyAsFirstserve.kt new file mode 100644 index 0000000..7d318d3 --- /dev/null +++ b/src/main/kotlin/latestModel/useCase/applyAsFirstserve.kt @@ -0,0 +1,27 @@ +package latestModel.useCase + +import latestModel.* +import latestModel.dataStore.ApplicationsDataStore + + +fun applyAsFirstServe( + studentId: String, + courseId: String, + dataStore: ApplicationsDataStore +) { + /*IO*/ + val applications = listOf() + val myApplications = listOf() + val student = Student(studentId) + val course = Course(courseId) + + /*aggregate*/ + val courseManager = CourseManager(course, applications) + val courseSchedule = CourseSchedule(myApplications) + if (courseManager.canApplyAsFirstserve()) { + courseSchedule.apply(student, course) + } + + /*IO*/ + //dataStore.save(newApplication) +} \ No newline at end of file diff --git a/src/main/kotlin/latestModel/useCase/cancelApplication.kt b/src/main/kotlin/latestModel/useCase/cancelApplication.kt new file mode 100644 index 0000000..bee64bd --- /dev/null +++ b/src/main/kotlin/latestModel/useCase/cancelApplication.kt @@ -0,0 +1,25 @@ +package latestModel.useCase + +import latestModel.Application +import latestModel.Course +import latestModel.CourseManager +import latestModel.CourseSchedule +import latestModel.dataStore.ApplicationsDataStore + +fun cancelApplication( + applicationId: String, + applicationsDataStore: ApplicationsDataStore +) { + /*IO*/ + val application = Application() + val applications = listOf() + val myApplications = listOf() + + /*aggregate*/ + val courseSchedule = CourseSchedule(CourseManager(application.course,applications),myApplications) + courseSchedule.cancel(applicationId) + + /*IO*/ + applicationsDataStore.delete(application.id) + +} \ No newline at end of file diff --git a/src/main/kotlin/latestModel/useCase/register.kt b/src/main/kotlin/latestModel/useCase/register.kt new file mode 100644 index 0000000..b71084e --- /dev/null +++ b/src/main/kotlin/latestModel/useCase/register.kt @@ -0,0 +1,24 @@ +package latestModel.useCase + +import latestModel.Application +import latestModel.Course +import latestModel.CourseManager +import latestModel.dataStore.ApplicationsDataStore +import latestModel.dataStore.CourseMembersDataStore + + +fun register( + courseId: String, +){ + /*IO*/ + val applications = listOf() + val course = Course(courseId) + + /*aggregate*/ + val courseManager = CourseManager(course,applications) + courseManager.registerMembers() + + /*IO*/ + //applicationsDataStore.save(registeredApplication) + //courseMembersDataStore.save(members) +} \ No newline at end of file diff --git a/src/main/kotlin/latestModel/useCase/selectAndRegister.kt b/src/main/kotlin/latestModel/useCase/selectAndRegister.kt new file mode 100644 index 0000000..2370a44 --- /dev/null +++ b/src/main/kotlin/latestModel/useCase/selectAndRegister.kt @@ -0,0 +1,29 @@ +package latestModel.useCase + +import latestModel.Application +import latestModel.Course +import latestModel.CourseManager +import latestModel.CourseSchedule +import latestModel.dataStore.ApplicationsDataStore +import latestModel.dataStore.CourseMembersDataStore + + +fun selectAndRegister( + courseId: String, + applicationsDataStore: ApplicationsDataStore, + courseMembersDataStore: CourseMembersDataStore + +){ + /*IO*/ + val applications = listOf() + val course = Course(courseId) + + /*aggregate*/ + val courseManager = CourseManager(course,applications) + courseManager.selectApplications() + courseManager.registerMembers() + + /*IO*/ + //applicationsDataStore.save(registeredApplication + rejectedApplication) + //courseMembersDataStore.save(members) +} \ No newline at end of file diff --git a/src/main/kotlin/webServer/Routes.kt b/src/main/kotlin/webServer/Routes.kt index d5b3f7b..0573d6d 100644 --- a/src/main/kotlin/webServer/Routes.kt +++ b/src/main/kotlin/webServer/Routes.kt @@ -75,11 +75,11 @@ class CourseTakingAndRegistration( * {studentId} * */ private fun getApplications(request: Request): Response { + /*requestからstudentIdを取得*/ + val studentId: StudentId = StudentId("someStudentId") + val result = CoroutineScope(Dispatchers.IO).async { runCatching { - /*requestからstudentIdを取得*/ - val studentId: StudentId = StudentId("someStudentId") - courseTakingApplicationService.getCourseTakingApplications(studentId) } } @@ -96,12 +96,13 @@ class CourseTakingAndRegistration( * {studentId, courseId} * */ private fun applyCourseTaking(request: Request): Response { + /*requestからuser, applicationを取得*/ + val studentId: StudentId = StudentId("someStudentId") + val courseId: CourseId = CourseId("someCourseId") + val format: String = "first-served" + val result = CoroutineScope(Dispatchers.IO).async { runCatching { - /*requestからuser, applicationを取得*/ - val studentId: StudentId = StudentId("someStudentId") - val courseId: CourseId = CourseId("someCourseId") - val format: String = "first-served" /*先着管理*/ if (firstServedManagementService.checkCanTake(courseId)) { /*申請*/ @@ -128,14 +129,14 @@ class CourseTakingAndRegistration( * {courseTakingApplicationId} * */ private fun cancelCourseTaking(request: Request): Response { + /*requestからapplicationIdを取得*/ + val courseTakingApplicationId: CourseTakingApplicationId = + CourseTakingApplicationId("someCourseTakingApplicationId") + val studentId: StudentId = + StudentId("someStudentId") + val result = CoroutineScope(Dispatchers.IO).async { runCatching { - /*requestからapplicationIdを取得*/ - val courseTakingApplicationId: CourseTakingApplicationId = - CourseTakingApplicationId("someCourseTakingApplicationId") - val studentId: StudentId = - StudentId("someStudentId") - /*申請のキャンセル*/ courseTakingApplicationService.cancelCourseTaking( studentId, @@ -153,10 +154,11 @@ class CourseTakingAndRegistration( } private fun drawAndRegisterCourseMembers(request: Request): Response { + /*requestからcourseIdを取得*/ + val courseId: CourseId = CourseId("someCourseId") + val result = CoroutineScope(Dispatchers.IO).async { runCatching { - /*requestからcourseIdを取得*/ - val courseId: CourseId = CourseId("someCourseId") /*抽選する*/ courseRegistrationService.drawingAndRegisterMembers(courseId) } @@ -172,16 +174,16 @@ class CourseTakingAndRegistration( } private fun registerCourseMembers(request: Request): Response { + /*requestからcourseIdを取得*/ + val courseId: CourseId = CourseId("someCourseId") + val result = CoroutineScope(Dispatchers.IO).async { runCatching { - /*requestからcourseIdを取得*/ - val courseId: CourseId = CourseId("someCourseId") /*抽選する*/ courseRegistrationService.registerMembers(courseId) } } - /*結果を返す*/ return if (result.getCompleted().isSuccess) { Response(OK)