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

feat : 어드민단 주문 도메인 개발 #70

Merged
merged 10 commits into from
Aug 27, 2023
2 changes: 1 addition & 1 deletion HIGOODS-Api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

openapi3 {
setServer("http://localhost:8080")
setServer("http://localhost:8080/api")
title = "HIGOODS API Documentation"
description = "Spring REST Docs with SwaggerUI"
version = "0.0.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.higoods.api.order.controller

import com.higoods.api.order.dto.response.OrderAdminResponse
import com.higoods.api.order.usecase.OrderApproveUseCase
import com.higoods.api.order.usecase.OrderCancelUseCase
import com.higoods.api.order.usecase.OrderReadUseCase
import com.higoods.domain.order.domain.OrderState
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/v1/admins/orders")
class OrderAdminController(
private val orderCancelUseCase: OrderCancelUseCase,
private val orderApproveUseCase: OrderApproveUseCase,
private val orderReadUseCase: OrderReadUseCase
) {
// 주문 취소
@PostMapping("/{order_id}/cancellations")
fun create(
@PathVariable("order_id") orderId: Long
): Long {
return orderCancelUseCase.execute(orderId)
}

// 입금 승인
@PostMapping("/{order_id}/approvals")
fun approve(
@PathVariable("order_id") orderId: Long
): Long {
return orderApproveUseCase.execute(orderId)
}

// 명단 관리-입금 확인 목록
@PostMapping("/{project_id}")
fun get(
@PathVariable("project_id") projectId: Long,
@RequestParam(value = "state", defaultValue = "PENDING") state: OrderState,
@RequestParam(value = "name", required = false) name: String?,
@RequestParam("page") page: Int,
@RequestParam("size") size: Int
): Page<OrderAdminResponse> {
// TODO: 페이지네이션 정상 작동 api 테스트하면서 다시 확인하기
return orderReadUseCase.findByStateAndName(projectId, state, name, PageRequest.of(page, size))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.higoods.api.order.dto.response

import com.higoods.domain.order.domain.Order
import com.higoods.domain.order.domain.OrderState
import java.time.format.DateTimeFormatter

data class OrderAdminResponse(
val orderNo: String, // 주문 번호
val name: String, // 이름
val depositName: String, // 입금자명
val createdAt: String, // 주문 일시
val phoneNum: String, // 전화번호
val totalCost: Int, // 총 금액
val orderState: OrderState // 주문 상태
) {
companion object {
fun of(order: Order): OrderAdminResponse {
return OrderAdminResponse(
orderNo = order.orderNo,
name = order.name,
depositName = order.depositName,
createdAt = order.createdAt.format(DateTimeFormatter.ofPattern("yy.MM.dd HH:mm")),
phoneNum = order.phoneNum,
totalCost = order.totalCost,
orderState = order.orderState
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
package com.higoods.api.order.dto.response

import com.higoods.domain.order.domain.OrderState
import com.higoods.domain.project.domain.Project

data class OrderProjectsResponse(
val orderId: Long,
val title: String,
val titleImage: String,
val subTitle: String
val subTitle: String,
val orderState: OrderState
// TODO: 프로젝트단 관련 작업 완료되면 추가 작업 필요
// val category: String,
// TODO: 프로젝트 상채 도메인 개발 후 추가 작업 필요
// val projectStatus: String
) {
companion object {
fun of(orderId: Long, project: Project): OrderProjectsResponse {
fun of(orderId: Long, orderState: OrderState, project: Project): OrderProjectsResponse {
return OrderProjectsResponse(
orderId = orderId,
title = project.title,
titleImage = project.titleImage,
subTitle = project.subTitle
subTitle = project.subTitle,
orderState = orderState
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.higoods.api.order.usecase

import com.higoods.api.config.security.SecurityUtils
import com.higoods.common.annotation.UseCase
import com.higoods.domain.order.adapter.OrderAdapter
import com.higoods.domain.order.service.OrderDomainService
import com.higoods.domain.project.adapter.ProjectAdapter
import com.higoods.domain.project.exception.ProjectNotHostException
import org.springframework.transaction.annotation.Transactional

@UseCase
class OrderApproveUseCase(
private val orderDomainService: OrderDomainService,
private val orderAdapter: OrderAdapter,
private val projectAdapter: ProjectAdapter
) {
@Transactional
fun execute(orderId: Long): Long {
val order = orderAdapter.queryById(orderId)
val project = projectAdapter.queryById(order.projectId)
if (project.userId != SecurityUtils.currentUserId) throw ProjectNotHostException.EXCEPTION
return orderDomainService.approveOrder(order)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.higoods.api.order.usecase

import com.higoods.api.config.security.SecurityUtils
import com.higoods.common.annotation.UseCase
import com.higoods.domain.order.adapter.OrderAdapter
import com.higoods.domain.order.service.OrderDomainService
import com.higoods.domain.project.adapter.ProjectAdapter
import com.higoods.domain.project.exception.ProjectNotHostException
import com.higoods.domain.project.service.ProjectDomainService
import org.springframework.transaction.annotation.Transactional

@UseCase
class OrderCancelUseCase(
private val orderDomainService: OrderDomainService,
private val orderAdapter: OrderAdapter,
private val projectAdapter: ProjectAdapter,
private val projectDomainService: ProjectDomainService
) {
@Transactional
fun execute(orderId: Long): Long {
val order = orderAdapter.queryById(orderId)
val project = projectAdapter.queryById(order.projectId)
if (project.userId != SecurityUtils.currentUserId) throw ProjectNotHostException.EXCEPTION
projectDomainService.decreasePurchaseNum(project)
return orderDomainService.cancelOrder(order)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@ import com.higoods.domain.order.domain.OrderAnswer
import com.higoods.domain.order.service.OrderDomainService
import com.higoods.domain.project.adapter.ProjectAdapter
import com.higoods.domain.project.service.ProjectDomainService
import org.springframework.transaction.annotation.Transactional

@UseCase
class OrderCreateUseCase(
private val orderDomainService: OrderDomainService,
private val projectAdapter: ProjectAdapter,
private val projectDomainService: ProjectDomainService
) {
@Transactional
fun execute(projectId: Long, orderCreateRequest: OrderCreateRequest): OrderResponse {
val currentUserId = SecurityUtils.currentUserId
val project = projectAdapter.queryById(projectId)
// TODO: 리스폰스에 주문번호 업데이트 되는지 확인 필요
// 시간 남으면 createOrder 함수에서 옵션, 주문폽 생성 같이 하도록 리팩토링
val newOrder = orderDomainService.createOrder(orderCreateRequest.toOrder(project.id, currentUserId))
val newOrderOptions = orderDomainService.createOrderOptions(orderCreateRequest.toOrderOptionItems(newOrder.id))
var newOrderAnswers: List<OrderAnswer>? = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
package com.higoods.api.order.usecase

import com.higoods.api.config.security.SecurityUtils
import com.higoods.api.order.dto.response.OrderAdminResponse
import com.higoods.api.order.dto.response.OrderProjectsResponse
import com.higoods.api.order.dto.response.OrderResponse
import com.higoods.common.annotation.UseCase
import com.higoods.domain.order.adapter.OrderAdapter
import com.higoods.domain.order.domain.OrderState
import com.higoods.domain.order.exception.OrderNotUserException
import com.higoods.domain.project.adapter.ProjectAdapter
import com.higoods.domain.project.exception.ProjectNotHostException
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.transaction.annotation.Transactional

@UseCase
class OrderReadUseCase(
private val orderAdapter: OrderAdapter,
private val projectAdapter: ProjectAdapter
) {
@Transactional(readOnly = true)
fun findAll(): List<OrderProjectsResponse> {
val orders = orderAdapter.findAll(SecurityUtils.currentUserId)
if (orders.isNullOrEmpty()) return emptyList()
return orders.map { order ->
val project = projectAdapter.queryById(order.projectId)
OrderProjectsResponse.of(order.id, project)
OrderProjectsResponse.of(order.id, order.orderState, project)
}
}

@Transactional(readOnly = true)
fun findById(orderId: Long): OrderResponse {
val order = orderAdapter.queryById(orderId)
if (order.userId != SecurityUtils.currentUserId) throw OrderNotUserException.EXCEPTION
val orderOptions = orderAdapter.findOrderOptionItemByOrderId(orderId)
val orderAnswers = orderAdapter.findAllOrderAnswerByOrderIdOrNull(orderId)
return OrderResponse.of(order, orderOptions, orderAnswers)
}

fun findByStateAndName(
projectId: Long,
state: OrderState,
name: String?,
pageable: Pageable
): Page<OrderAdminResponse> {
val project = projectAdapter.queryById(projectId)
if (project.userId != SecurityUtils.currentUserId) throw ProjectNotHostException.EXCEPTION
val orders = orderAdapter.queryOrders(project.id, state, name, pageable)
return orders.map { order ->
OrderAdminResponse.of(order)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.higoods.api.common

import com.fasterxml.jackson.databind.ObjectMapper
import io.kotest.core.spec.style.FunSpec
import org.springframework.restdocs.ManualRestDocumentation
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
Expand All @@ -11,6 +12,7 @@ import org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder
abstract class BaseControllerTest : FunSpec() {
protected abstract val controller: Any
protected lateinit var mockMvc: MockMvc
protected lateinit var objectMapper: ObjectMapper
private val restDocumentation = ManualRestDocumentation()
init {
beforeSpec {
Expand Down
Loading