Skip to content

Commit

Permalink
feat(#58) : add fine list API
Browse files Browse the repository at this point in the history
  • Loading branch information
xonmin committed Jun 18, 2023
1 parent 8b922da commit 6a387ce
Show file tree
Hide file tree
Showing 16 changed files with 183 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ class FineController(
@Operation(summary = "벌금 리스트 조회 API", description = "벌금 리스트 조회 API")
@GetMapping
fun fineList(@PathVariable("moitId") moitId: Long): MoitApiResponse<FineListResponse> {
return MoitApiResponse.success(FineListResponse.sample())
return MoitApiResponse.success(fineFacade.getFineList(moitId))
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.mashup.moit.fine.controller.dto

import com.mashup.moit.domain.attendance.AttendanceStatus
import com.mashup.moit.domain.fine.Fine
import com.mashup.moit.domain.study.Study
import com.mashup.moit.domain.user.User
import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotNull
import java.time.LocalDate
Expand All @@ -23,35 +26,7 @@ data class FineListResponse(
val fineComplete: List<FineResponseForListView>,
) {
companion object {
fun sample() = FineListResponse(
totalFineAmount = 100000000000,
fineNotYet = listOf(
FineResponseForListView(
id = 2L,
fineAmount = 50000000000,
userId = 1L,
userName = "박재민",
attendanceStatus = AttendanceStatus.ABSENCE,
studyOrder = 5,
isConfirmed = false,
registerAt = LocalDate.of(2023, 6, 8),
paymentAt = LocalDate.of(2023, 6, 15)
)
),
fineComplete = listOf(
FineResponseForListView(
id = 1L,
fineAmount = 50000000000,
userId = 1L,
userName = "박재민",
attendanceStatus = AttendanceStatus.ABSENCE,
studyOrder = 5,
isConfirmed = true,
registerAt = LocalDate.of(2023, 6, 8),
paymentAt = null
)
)
)
fun emptyFineList() = FineListResponse(0, emptyList(), emptyList())
}
}

Expand All @@ -63,16 +38,31 @@ data class FineResponseForListView(
val fineAmount: Long,
@Schema(description = "Fine 대상 User id")
val userId: Long,
@Schema(description = "Fine 대상 User 이름")
val userName: String,
@Schema(description = "Fine 대상 User nickname")
val userNickname: String,
@Schema(description = "Fine 대상 출석 상태 (LATE, ABSENCE)")
val attendanceStatus: AttendanceStatus,
@Schema(description = "Fine 대상 스터디 회차")
val studyOrder: Int,
@Schema(description = "Fine 납부 인증 유무")
val isConfirmed: Boolean,
val isApproved: Boolean,
@Schema(description = "Fine 등록 일자 YYYY-mm-dd")
val registerAt: LocalDate,
@Schema(description = "Fine 납부 일자 YYYY-mm-dd")
val paymentAt: LocalDate?,
)
val approveAt: LocalDate?,
) {
companion object {
fun of(fine: Fine, user: User, study: Study) =
FineResponseForListView(
id = fine.id,
fineAmount = fine.amount,
userId = fine.userId,
userNickname = user.nickname,
attendanceStatus = fine.attendanceStatus,
studyOrder = study.order,
isApproved = fine.isApproved,
registerAt = fine.registerAt.toLocalDate(),
approveAt = fine.approvedAt?.toLocalDate()
)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,40 @@
package com.mashup.moit.fine.facade

import com.mashup.moit.domain.fine.FineService
import com.mashup.moit.domain.study.StudyService
import com.mashup.moit.domain.user.UserService
import com.mashup.moit.fine.controller.dto.FineListResponse
import com.mashup.moit.fine.controller.dto.FineResponseForListView
import org.springframework.stereotype.Component

@Component
class FineFacade {
class FineFacade(
private val fineService: FineService,
private val studyService: StudyService,
private val userService: UserService
) {
fun getFineList(moitId: Long): FineListResponse {
val fineList = fineService.getFineListByMoitId(moitId)
if (fineList.isEmpty()) {
return FineListResponse.emptyFineList()
}

val fineUserIds = fineList.map { it.userId }.distinct()
val fineUsersMap = userService.findUsersByIds(fineUserIds).associateBy { it.id }

val fineStudyIds = fineList.map { it.studyId }.distinct()
val fineStudyMap = studyService.findByStudyIds(fineStudyIds).associateBy { it.id }

val totalFineAmount = fineList.sumOf { it.amount }
val (fineComplete, fineNotYet) = fineList.partition { it.isApproved }
.let { (approvedFineList, isNotApprovedFineList) ->
approvedFineList.map {
FineResponseForListView.of(it, fineUsersMap[it.userId]!!, fineStudyMap[it.studyId]!!)
} to isNotApprovedFineList.map {
FineResponseForListView.of(it, fineUsersMap[it.userId]!!, fineStudyMap[it.studyId]!!)
}
}

return FineListResponse(totalFineAmount, fineNotYet, fineComplete)
}
}
17 changes: 17 additions & 0 deletions moit-domain/src/main/kotlin/com/mashup/moit/domain/fine/Fine.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
package com.mashup.moit.domain.fine

import com.mashup.moit.domain.attendance.AttendanceStatus
import java.time.LocalDateTime

enum class FineApproveStatus {
NEW, IN_PROGRESS, REJECTED, APPROVED;
}

data class Fine(
val id: Long,
val moitId: Long,
val studyId: Long,
val userId: Long,
val attendanceStatus: AttendanceStatus,
val amount: Long,
val isApproved: Boolean,
val approveStatus: FineApproveStatus,
val approvedAt: LocalDateTime?,
val approveImageUrl: String?,
val registerAt: LocalDateTime,
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class FineEntity(
@JoinColumn(name = "attendance_id", nullable = false)
var attendance: AttendanceEntity,

@Column(name = "amount", nullable = false)
val amount: Long,

@Enumerated(EnumType.STRING)
@Column(name = "approve_status", nullable = false)
val approveStatus: FineApproveStatus = FineApproveStatus.NEW,
Expand All @@ -33,7 +36,27 @@ class FineEntity(

@Column(name = "moit_id", nullable = false)
val moitId: Long,

@Column(name = "study_id", nullable = false)
val studyId: Long,
) : BaseEntity()
) : BaseEntity() {
fun toDomain(): Fine {
val isApproved = when (approveStatus) {
FineApproveStatus.APPROVED -> true
else -> false
}

return Fine(
id = id,
moitId = moitId,
studyId = attendance.studyId,
userId = userId,
attendanceStatus = attendance.status,
amount = amount,
isApproved = isApproved,
approveStatus = approveStatus,
approvedAt = approvedAt,
approveImageUrl = approveImageUrl,
registerAt = createdAt
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.mashup.moit.domain.fine

import org.springframework.data.jpa.repository.JpaRepository

interface FineRepository : JpaRepository<FineEntity, Long> {
fun findByMoitId(moitId: Long) : List<FineEntity>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.mashup.moit.domain.fine

import org.springframework.stereotype.Service

@Service
class FineService(
private val fineRepository: FineRepository
) {
fun getFineListByMoitId(moitId: Long): List<Fine> {
return fineRepository.findByMoitId(moitId).map { it.toDomain() }
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.mashup.moit.domain.moit

import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalTime
import com.mashup.moit.common.exception.MoitException
import com.mashup.moit.common.exception.MoitExceptionType
import org.apache.commons.lang3.RandomStringUtils
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalTime
import java.util.*

@Service
Expand Down Expand Up @@ -69,6 +69,12 @@ class MoitService(
}
}

fun getMoitById(moitId: Long): Moit {
return moitRepository.findById(moitId)
.orElseThrow { MoitException.of(MoitExceptionType.NOT_EXIST) }
.toDomain()
}

fun getMoitByInvitationCode(invitationCode: String): Moit {
val moit = (moitRepository.findByInvitationCode(invitationCode.uppercase(Locale.getDefault()))
?: throw MoitException.of(MoitExceptionType.NOT_EXIST))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.mashup.moit.domain.study

data class Study(
val id: Long,
val moitId: Long,
val order: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,10 @@ class StudyEntity(

@Column(name = "attendance_code")
var attendanceCode: String? = null

fun toDomain() = Study(
id = id,
moitId = moitId,
order = order,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ package com.mashup.moit.domain.study

import org.springframework.data.jpa.repository.JpaRepository

interface StudyRepository : JpaRepository<StudyEntity, Long>
interface StudyRepository : JpaRepository<StudyEntity, Long> {
fun findByIdIn(ids: List<Long>): List<StudyEntity>
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class StudyService(
private val studyRepository: StudyRepository,
private val moitRepository: MoitRepository,
) {
fun findByStudyIds(ids: List<Long>): List<Study> {
return studyRepository.findByIdIn(ids).map { it.toDomain() }
}

@Transactional
fun createStudies(moitId: Long) {
val moit = moitRepository.findById(moitId).orElseThrow { MoitException.of(MoitExceptionType.NOT_EXIST) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ enum class SocialType {

data class User(
val id: Long,
val socialType: String
val socialType: SocialType,
val nickname: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,28 @@ class UserEntity(

@Column(name = "kakao_id")
val kakaoId: Long? = null,

@Column(name = "nickname")
val nickname: String,
) : BaseEntity() {
fun toDomain() =
User(
id = id,
socialType = socialType,
nickname = nickname
)

companion object {
fun createAppleUser(appleId: Long): UserEntity = UserEntity(
fun createAppleUser(appleId: Long, nickname: String): UserEntity = UserEntity(
appleId = appleId,
socialType = SocialType.APPLE
socialType = SocialType.APPLE,
nickname = nickname
)

fun createKakaoUser(kakaoId: Long): UserEntity = UserEntity(
fun createKakaoUser(kakaoId: Long, nickname: String): UserEntity = UserEntity(
kakaoId = kakaoId,
socialType = SocialType.KAKAO
socialType = SocialType.KAKAO,
nickname = nickname
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ package com.mashup.moit.domain.user

import org.springframework.data.jpa.repository.JpaRepository

interface UserRepository : JpaRepository<UserEntity, Long>
interface UserRepository : JpaRepository<UserEntity, Long> {
fun findByIdIn(ids: List<Long>): List<UserEntity>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.mashup.moit.domain.user

import org.springframework.stereotype.Service

@Service
class UserService(
private val userRepository: UserRepository
) {
fun findUsersByIds(ids: List<Long>): List<User> {
return userRepository.findByIdIn(ids)
.map { it.toDomain() }
}
}

0 comments on commit 6a387ce

Please sign in to comment.