feat(gift): 선물 받을 주소 관리자 서비스를 추가한다

This commit is contained in:
2026-10-01 22:57:07 +09:00
parent f66c89fb7f
commit 33b6662cb4
2 changed files with 113 additions and 1 deletions
@@ -4,6 +4,8 @@ import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategory import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategory
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategoryRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategoryRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDeliveryRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDeliveryRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftMailbox
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftMailboxRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePrice import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePrice
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePriceRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePriceRepository
@@ -41,6 +43,14 @@ data class GiftSizePriceCommand(
val isActive: Boolean val isActive: Boolean
) )
data class GiftMailboxCommand(
val name: String,
val phoneNumber: String,
val zipCode: String,
val address: String,
val addressDetail: String?
)
data class GiftSizePriceResult( data class GiftSizePriceResult(
val sizeCode: GiftSize, val sizeCode: GiftSize,
val sizeName: String, val sizeName: String,
@@ -62,8 +72,31 @@ class GiftAdminService(
private val sizePriceRepository: GiftSizePriceRepository, private val sizePriceRepository: GiftSizePriceRepository,
private val giftRepository: GiftRepository, private val giftRepository: GiftRepository,
private val giftDeliveryRepository: GiftDeliveryRepository, private val giftDeliveryRepository: GiftDeliveryRepository,
private val giftMailboxRepository: GiftMailboxRepository,
private val giftPushService: GiftPushService private val giftPushService: GiftPushService
) { ) {
@Transactional(readOnly = true)
fun getMailbox(): GiftMailboxResult? = giftMailboxRepository.findByIdOrNull(GiftMailbox.SINGLETON_ID)?.toResult()
@Transactional
fun updateMailbox(command: GiftMailboxCommand): GiftMailboxResult {
validateMailbox(command)
val mailbox = giftMailboxRepository.findByIdOrNull(GiftMailbox.SINGLETON_ID)
?: GiftMailbox(
name = command.name,
phoneNumber = command.phoneNumber,
zipCode = command.zipCode,
address = command.address,
addressDetail = command.addressDetail?.takeIf { it.isNotBlank() }
)
mailbox.name = command.name
mailbox.phoneNumber = command.phoneNumber
mailbox.zipCode = command.zipCode
mailbox.address = command.address
mailbox.addressDetail = command.addressDetail?.takeIf { it.isNotBlank() }
return giftMailboxRepository.save(mailbox).toResult()
}
@Transactional(readOnly = true) @Transactional(readOnly = true)
fun getCategories(): List<GiftCategoryResult> = categoryRepository.findAll().map { it.toResult() } fun getCategories(): List<GiftCategoryResult> = categoryRepository.findAll().map { it.toResult() }
@@ -198,6 +231,22 @@ class GiftAdminService(
if (command.salePriceCan <= 0 || command.salePriceCan > command.basePriceCan) throw invalidRequest() if (command.salePriceCan <= 0 || command.salePriceCan > command.basePriceCan) throw invalidRequest()
} }
private fun validateMailbox(command: GiftMailboxCommand) {
if (
command.name.isBlank() ||
command.name.length > 50 ||
command.phoneNumber.isBlank() ||
command.phoneNumber.length > 30 ||
command.zipCode.isBlank() ||
command.zipCode.length > 20 ||
command.address.isBlank() ||
command.address.length > 255 ||
(command.addressDetail?.length ?: 0) > 255
) {
throw invalidRequest()
}
}
private fun GiftCategory.toResult() = GiftCategoryResult( private fun GiftCategory.toResult() = GiftCategoryResult(
categoryId = id ?: throw invalidRequest(), categoryId = id ?: throw invalidRequest(),
classificationNumber = classificationNumber, classificationNumber = classificationNumber,
@@ -217,6 +266,15 @@ class GiftAdminService(
isActive = isActive isActive = isActive
) )
private fun GiftMailbox.toResult() = GiftMailboxResult(
name = name,
address = formatAddress(zipCode, address, addressDetail),
phoneNumber = phoneNumber
)
private fun formatAddress(zipCode: String, address: String, detail: String?) =
"($zipCode) $address" + if (detail.isNullOrBlank()) "" else ", $detail"
private fun invalidRequest() = SodaException(messageKey = "common.error.invalid_request") private fun invalidRequest() = SodaException(messageKey = "common.error.invalid_request")
private companion object { private companion object {
@@ -6,6 +6,7 @@ import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.Gift
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategoryRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategoryRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDelivery import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDelivery
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDeliveryRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDeliveryRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftMailboxRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftRepository
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePriceRepository import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePriceRepository
import kr.co.vividnext.sodalive.v2.gift.domain.GiftSize import kr.co.vividnext.sodalive.v2.gift.domain.GiftSize
@@ -33,7 +34,8 @@ class GiftAdminServiceTest @Autowired constructor(
private val categoryRepository: GiftCategoryRepository, private val categoryRepository: GiftCategoryRepository,
private val sizePriceRepository: GiftSizePriceRepository, private val sizePriceRepository: GiftSizePriceRepository,
private val giftRepository: GiftRepository, private val giftRepository: GiftRepository,
private val giftDeliveryRepository: GiftDeliveryRepository private val giftDeliveryRepository: GiftDeliveryRepository,
private val giftMailboxRepository: GiftMailboxRepository
) { ) {
private val giftPushService = Mockito.mock(GiftPushService::class.java) private val giftPushService = Mockito.mock(GiftPushService::class.java)
private val service = GiftAdminService( private val service = GiftAdminService(
@@ -41,9 +43,61 @@ class GiftAdminServiceTest @Autowired constructor(
sizePriceRepository, sizePriceRepository,
giftRepository, giftRepository,
giftDeliveryRepository, giftDeliveryRepository,
giftMailboxRepository,
giftPushService giftPushService
) )
@Test
@DisplayName("받을 주소는 미등록이면 null이고 저장 후 단일 설정으로 갱신된다")
fun shouldUpsertGiftMailbox() {
assertEquals(null, service.getMailbox())
val created = service.updateMailbox(
GiftMailboxCommand(
name = "소다라이브 선물 담당자",
phoneNumber = "01012345678",
zipCode = "06234",
address = "서울시 강남구",
addressDetail = "3층 선물 접수처"
)
)
val updated = service.updateMailbox(
GiftMailboxCommand(
name = "소다라이브 운영팀",
phoneNumber = "01087654321",
zipCode = "04524",
address = "서울시 중구",
addressDetail = null
)
)
assertEquals("소다라이브 선물 담당자", created.name)
assertEquals("(06234) 서울시 강남구, 3층 선물 접수처", created.address)
assertEquals("01012345678", created.phoneNumber)
assertEquals("소다라이브 운영팀", updated.name)
assertEquals("(04524) 서울시 중구", updated.address)
assertEquals(1, giftMailboxRepository.count())
}
@Test
@DisplayName("받을 주소 필수값이 공백이면 저장할 수 없다")
fun shouldRejectInvalidGiftMailbox() {
val exception = assertThrows(SodaException::class.java) {
service.updateMailbox(
GiftMailboxCommand(
name = " ",
phoneNumber = "01012345678",
zipCode = "06234",
address = "서울시 강남구",
addressDetail = null
)
)
}
assertEquals("common.error.invalid_request", exception.messageKey)
assertEquals(0, giftMailboxRepository.count())
}
@Test @Test
@DisplayName("카테고리를 등록, 수정, 논리삭제한다") @DisplayName("카테고리를 등록, 수정, 논리삭제한다")
fun shouldCreateUpdateAndDeactivateCategory() { fun shouldCreateUpdateAndDeactivateCategory() {