feat(gift): 관리자 선물함 HTTP 조회를 추가한다
This commit is contained in:
+23
-1
@@ -3,12 +3,16 @@ package kr.co.vividnext.sodalive.v2.api.admin.gift.adapter.`in`.web
|
|||||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftCategoryRequest
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftCategoryRequest
|
||||||
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftCategoryResponse
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftCategoryResponse
|
||||||
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftDetailResponse
|
||||||
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftListResponse
|
||||||
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftMarkUndeliverableRequest
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftMarkUndeliverableRequest
|
||||||
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftOperationStatusResponse
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftOperationStatusResponse
|
||||||
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftSizePriceRequest
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftSizePriceRequest
|
||||||
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftSizePriceResponse
|
import kr.co.vividnext.sodalive.v2.api.admin.gift.dto.AdminGiftSizePriceResponse
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.application.GiftAdminQueryService
|
||||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftAdminService
|
import kr.co.vividnext.sodalive.v2.gift.application.GiftAdminService
|
||||||
import kr.co.vividnext.sodalive.v2.gift.domain.GiftSize
|
import kr.co.vividnext.sodalive.v2.gift.domain.GiftSize
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus
|
||||||
import org.springframework.security.access.prepost.PreAuthorize
|
import org.springframework.security.access.prepost.PreAuthorize
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping
|
import org.springframework.web.bind.annotation.DeleteMapping
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
@@ -17,12 +21,30 @@ import org.springframework.web.bind.annotation.PostMapping
|
|||||||
import org.springframework.web.bind.annotation.PutMapping
|
import org.springframework.web.bind.annotation.PutMapping
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v2/admin")
|
@RequestMapping("/api/v2/admin")
|
||||||
@PreAuthorize("hasRole('ADMIN')")
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
class AdminGiftController(private val service: GiftAdminService) {
|
class AdminGiftController(
|
||||||
|
private val service: GiftAdminService,
|
||||||
|
private val queryService: GiftAdminQueryService
|
||||||
|
) {
|
||||||
|
@GetMapping("/gifts")
|
||||||
|
fun getGifts(
|
||||||
|
@RequestParam(required = false) status: GiftStatus?,
|
||||||
|
@RequestParam(required = false) applicationNo: String?,
|
||||||
|
@RequestParam(required = false) nickname: String?,
|
||||||
|
@RequestParam(defaultValue = "0") page: Int,
|
||||||
|
@RequestParam(defaultValue = "20") size: Int
|
||||||
|
) = ApiResponse.ok(AdminGiftListResponse.from(queryService.getGifts(status, applicationNo, nickname, page, size)))
|
||||||
|
|
||||||
|
@GetMapping("/gifts/{applicationNo}")
|
||||||
|
fun getGiftDetail(@PathVariable applicationNo: String) = ApiResponse.ok(
|
||||||
|
AdminGiftDetailResponse.from(queryService.getGiftDetail(applicationNo))
|
||||||
|
)
|
||||||
|
|
||||||
@GetMapping("/gift-categories")
|
@GetMapping("/gift-categories")
|
||||||
fun getCategories() = ApiResponse.ok(service.getCategories().map { AdminGiftCategoryResponse.from(it) })
|
fun getCategories() = ApiResponse.ok(service.getCategories().map { AdminGiftCategoryResponse.from(it) })
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.api.admin.gift.dto
|
package kr.co.vividnext.sodalive.v2.api.admin.gift.dto
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.extensions.toUtcIso
|
import kr.co.vividnext.sodalive.extensions.toUtcIso
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.application.AdminGiftDetailResult
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.application.AdminGiftInboundDeliveryInfoResult
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.application.AdminGiftListItemResult
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.application.AdminGiftListResult
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.application.AdminGiftMemberInfoResult
|
||||||
|
import kr.co.vividnext.sodalive.v2.gift.application.AdminGiftProductInfoResult
|
||||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftCategoryResult
|
import kr.co.vividnext.sodalive.v2.gift.application.GiftCategoryResult
|
||||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftOperationStatusResult
|
import kr.co.vividnext.sodalive.v2.gift.application.GiftOperationStatusResult
|
||||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftSizePriceResult
|
import kr.co.vividnext.sodalive.v2.gift.application.GiftSizePriceResult
|
||||||
@@ -63,3 +69,121 @@ data class AdminGiftOperationStatusResponse(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class AdminGiftListResponse(
|
||||||
|
val totalCount: Long,
|
||||||
|
val items: List<AdminGiftListItemResponse>,
|
||||||
|
val page: Int,
|
||||||
|
val size: Int,
|
||||||
|
val hasNext: Boolean
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun from(result: AdminGiftListResult) = AdminGiftListResponse(
|
||||||
|
totalCount = result.totalCount,
|
||||||
|
items = result.items.map { AdminGiftListItemResponse.from(it) },
|
||||||
|
page = result.page,
|
||||||
|
size = result.size,
|
||||||
|
hasNext = result.hasNext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class AdminGiftListItemResponse(
|
||||||
|
val applicationNo: String,
|
||||||
|
val senderNickname: String,
|
||||||
|
val recipientNickname: String,
|
||||||
|
val sizeCode: String,
|
||||||
|
val sizeName: String,
|
||||||
|
val categoryName: String,
|
||||||
|
val classificationNumber: String,
|
||||||
|
val courierCompanyName: String?,
|
||||||
|
val trackingNumber: String?,
|
||||||
|
val status: GiftStatus,
|
||||||
|
val statusName: String,
|
||||||
|
val availableActions: List<String>
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun from(result: AdminGiftListItemResult) = AdminGiftListItemResponse(
|
||||||
|
applicationNo = result.applicationNo,
|
||||||
|
senderNickname = result.senderNickname,
|
||||||
|
recipientNickname = result.recipientNickname,
|
||||||
|
sizeCode = result.sizeCode,
|
||||||
|
sizeName = result.sizeName,
|
||||||
|
categoryName = result.categoryName,
|
||||||
|
classificationNumber = result.classificationNumber,
|
||||||
|
courierCompanyName = result.courierCompanyName,
|
||||||
|
trackingNumber = result.trackingNumber,
|
||||||
|
status = result.status,
|
||||||
|
statusName = result.statusName,
|
||||||
|
availableActions = result.availableActions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class AdminGiftDetailResponse(
|
||||||
|
val applicationNo: String,
|
||||||
|
val senderInfo: AdminGiftMemberInfoResponse,
|
||||||
|
val recipientInfo: AdminGiftMemberInfoResponse,
|
||||||
|
val productInfo: AdminGiftProductInfoResponse,
|
||||||
|
val inboundDeliveryInfo: AdminGiftInboundDeliveryInfoResponse,
|
||||||
|
val status: GiftStatus,
|
||||||
|
val statusName: String,
|
||||||
|
val availableActions: List<String>
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun from(result: AdminGiftDetailResult) = AdminGiftDetailResponse(
|
||||||
|
applicationNo = result.applicationNo,
|
||||||
|
senderInfo = AdminGiftMemberInfoResponse.from(result.senderInfo),
|
||||||
|
recipientInfo = AdminGiftMemberInfoResponse.from(result.recipientInfo),
|
||||||
|
productInfo = AdminGiftProductInfoResponse.from(result.productInfo),
|
||||||
|
inboundDeliveryInfo = AdminGiftInboundDeliveryInfoResponse.from(result.inboundDeliveryInfo),
|
||||||
|
status = result.status,
|
||||||
|
statusName = result.statusName,
|
||||||
|
availableActions = result.availableActions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class AdminGiftMemberInfoResponse(
|
||||||
|
val nickname: String,
|
||||||
|
val name: String,
|
||||||
|
val phoneNumber: String,
|
||||||
|
val address: String
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun from(result: AdminGiftMemberInfoResult) = AdminGiftMemberInfoResponse(
|
||||||
|
nickname = result.nickname,
|
||||||
|
name = result.name,
|
||||||
|
phoneNumber = result.phoneNumber,
|
||||||
|
address = result.address
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class AdminGiftProductInfoResponse(
|
||||||
|
val sizeCode: String,
|
||||||
|
val sizeName: String,
|
||||||
|
val categoryName: String,
|
||||||
|
val classificationNumber: String
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun from(result: AdminGiftProductInfoResult) = AdminGiftProductInfoResponse(
|
||||||
|
sizeCode = result.sizeCode,
|
||||||
|
sizeName = result.sizeName,
|
||||||
|
categoryName = result.categoryName,
|
||||||
|
classificationNumber = result.classificationNumber
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class AdminGiftInboundDeliveryInfoResponse(
|
||||||
|
val courierCompanyName: String?,
|
||||||
|
val trackingNumber: String?
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun from(result: AdminGiftInboundDeliveryInfoResult) = AdminGiftInboundDeliveryInfoResponse(
|
||||||
|
courierCompanyName = result.courierCompanyName,
|
||||||
|
trackingNumber = result.trackingNumber
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+141
-1
@@ -1,7 +1,10 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.api.admin.gift.adapter.`in`.web
|
package kr.co.vividnext.sodalive.v2.api.admin.gift.adapter.`in`.web
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
|
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||||
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.Gift
|
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.Gift
|
||||||
|
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.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
|
||||||
@@ -46,12 +49,93 @@ class AdminGiftControllerTest @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 memberRepository: MemberRepository
|
||||||
) {
|
) {
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun deleteGiftFixtures() {
|
fun deleteGiftFixtures() {
|
||||||
giftDeliveryRepository.deleteAll()
|
giftDeliveryRepository.deleteAll()
|
||||||
giftRepository.deleteAll()
|
giftRepository.deleteAll()
|
||||||
|
categoryRepository.deleteAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("관리자는 전체 선물함 목록을 필터링해 조회한다")
|
||||||
|
fun shouldListAdminGifts() {
|
||||||
|
val (gift, _) = saveAdminGift(
|
||||||
|
applicationNo = "A-1002609300001",
|
||||||
|
status = GiftStatus.TRACKING_REGISTERED,
|
||||||
|
senderNickname = "admin-fan-alpha",
|
||||||
|
recipientNickname = "admin-creator-alpha",
|
||||||
|
withTracking = true
|
||||||
|
)
|
||||||
|
|
||||||
|
mockMvc.perform(
|
||||||
|
get("/api/v2/admin/gifts")
|
||||||
|
.with(user("admin").roles("ADMIN"))
|
||||||
|
.param("status", "TRACKING_REGISTERED")
|
||||||
|
.param("applicationNo", "0001")
|
||||||
|
.param("nickname", "alpha")
|
||||||
|
.param("page", "0")
|
||||||
|
.param("size", "20")
|
||||||
|
)
|
||||||
|
.andExpect(status().isOk)
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.data.totalCount").value(1))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].applicationNo").value(gift.applicationNo))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].senderNickname").value("admin-fan-alpha"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].recipientNickname").value("admin-creator-alpha"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].sizeCode").value("SMALL"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].sizeName").value("소형"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].categoryName").value("인형"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].classificationNumber").value("100"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].courierCompanyName").value("CJ대한통운"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].trackingNumber").value("1234567890"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].status").value("TRACKING_REGISTERED"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].statusName").value("발송 확인"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].availableActions[0]").value("ARRIVE_MAILBOX"))
|
||||||
|
.andExpect(jsonPath("$.data.items[0].availableActions[1]").value("MARK_UNDELIVERABLE"))
|
||||||
|
.andExpect(jsonPath("$.data.page").value(0))
|
||||||
|
.andExpect(jsonPath("$.data.size").value(20))
|
||||||
|
.andExpect(jsonPath("$.data.hasNext").value(false))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("관리자는 선물 상세를 조회하고 미입력 수취인 정보는 빈 문자열로 받는다")
|
||||||
|
fun shouldGetAdminGiftDetail() {
|
||||||
|
saveAdminGift(
|
||||||
|
applicationNo = "A-1002609300002",
|
||||||
|
status = GiftStatus.ARRIVED_AT_MAILBOX,
|
||||||
|
senderNickname = "admin-fan-beta",
|
||||||
|
recipientNickname = "admin-creator-beta",
|
||||||
|
withTracking = true
|
||||||
|
)
|
||||||
|
|
||||||
|
mockMvc.perform(
|
||||||
|
get("/api/v2/admin/gifts/A-1002609300002")
|
||||||
|
.with(user("admin").roles("ADMIN"))
|
||||||
|
)
|
||||||
|
.andExpect(status().isOk)
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.data.applicationNo").value("A-1002609300002"))
|
||||||
|
.andExpect(jsonPath("$.data.senderInfo.nickname").value("admin-fan-beta"))
|
||||||
|
.andExpect(jsonPath("$.data.senderInfo.name").value("홍길동"))
|
||||||
|
.andExpect(jsonPath("$.data.senderInfo.phoneNumber").value("01012345678"))
|
||||||
|
.andExpect(jsonPath("$.data.senderInfo.address").value("(06234) 서울시 강남구, 101동 1001호"))
|
||||||
|
.andExpect(jsonPath("$.data.recipientInfo.nickname").value("admin-creator-beta"))
|
||||||
|
.andExpect(jsonPath("$.data.recipientInfo.name").value(""))
|
||||||
|
.andExpect(jsonPath("$.data.recipientInfo.phoneNumber").value(""))
|
||||||
|
.andExpect(jsonPath("$.data.recipientInfo.address").value(""))
|
||||||
|
.andExpect(jsonPath("$.data.productInfo.sizeCode").value("SMALL"))
|
||||||
|
.andExpect(jsonPath("$.data.productInfo.sizeName").value("소형"))
|
||||||
|
.andExpect(jsonPath("$.data.productInfo.categoryName").value("인형"))
|
||||||
|
.andExpect(jsonPath("$.data.productInfo.classificationNumber").value("100"))
|
||||||
|
.andExpect(jsonPath("$.data.inboundDeliveryInfo.courierCompanyName").value("CJ대한통운"))
|
||||||
|
.andExpect(jsonPath("$.data.inboundDeliveryInfo.trackingNumber").value("1234567890"))
|
||||||
|
.andExpect(jsonPath("$.data.status").value("ARRIVED_AT_MAILBOX"))
|
||||||
|
.andExpect(jsonPath("$.data.statusName").value("사서함 도착"))
|
||||||
|
.andExpect(jsonPath("$.data.availableActions[0]").value("COMPLETE_INSPECTION"))
|
||||||
|
.andExpect(jsonPath("$.data.availableActions[1]").value("MARK_UNDELIVERABLE"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -242,6 +326,62 @@ class AdminGiftControllerTest @Autowired constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun saveAdminGift(
|
||||||
|
applicationNo: String,
|
||||||
|
status: GiftStatus,
|
||||||
|
senderNickname: String,
|
||||||
|
recipientNickname: String,
|
||||||
|
withTracking: Boolean
|
||||||
|
): Pair<Gift, GiftDelivery> {
|
||||||
|
val sender = memberRepository.save(Member(password = "password", nickname = senderNickname))
|
||||||
|
val recipient = memberRepository.save(Member(password = "password", nickname = recipientNickname))
|
||||||
|
val category = categoryRepository.save(
|
||||||
|
GiftCategory(
|
||||||
|
classificationNumber = "100",
|
||||||
|
categoryCode = "ADMIN_${applicationNo.takeLast(4)}",
|
||||||
|
name = "인형",
|
||||||
|
receiptCode = "A",
|
||||||
|
representativeItem = "피규어"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val gift = giftRepository.save(
|
||||||
|
Gift(
|
||||||
|
applicationNo = applicationNo,
|
||||||
|
senderMemberId = sender.id!!,
|
||||||
|
recipientMemberId = recipient.id!!,
|
||||||
|
status = status,
|
||||||
|
sizeCode = GiftSize.SMALL,
|
||||||
|
categoryId = category.id!!,
|
||||||
|
categoryNameSnapshot = category.name,
|
||||||
|
salePriceCan = 80,
|
||||||
|
canUsageId = 10L,
|
||||||
|
senderTermsAgreed = true,
|
||||||
|
senderPrivacyAgreed = true,
|
||||||
|
senderTermsAgreedAt = NOW.minusDays(1),
|
||||||
|
senderPrivacyAgreedAt = NOW.minusDays(1),
|
||||||
|
damageWaiverAgreed = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val delivery = giftDeliveryRepository.save(
|
||||||
|
GiftDelivery(
|
||||||
|
giftId = requireNotNull(gift.id),
|
||||||
|
senderName = "홍길동",
|
||||||
|
senderPhoneNumber = "01012345678",
|
||||||
|
senderZipCode = "06234",
|
||||||
|
senderAddress = "서울시 강남구",
|
||||||
|
senderAddressDetail = "101동 1001호",
|
||||||
|
trackingDeadlineAt = NOW.minusDays(1)
|
||||||
|
).apply {
|
||||||
|
if (withTracking) {
|
||||||
|
courierCompanyName = "CJ대한통운"
|
||||||
|
trackingNumber = "1234567890"
|
||||||
|
trackingRegisteredAt = NOW.minusHours(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return gift to delivery
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val APPLICATION_NO = "G20260929000001"
|
const val APPLICATION_NO = "G20260929000001"
|
||||||
const val SENDER_MEMBER_ID = 1L
|
const val SENDER_MEMBER_ID = 1L
|
||||||
|
|||||||
Reference in New Issue
Block a user