diff --git a/src/main/kotlin/org/store/clothstar/category/repository/CategoryRepository.kt b/src/main/kotlin/org/store/clothstar/category/repository/CategoryJpaRepository.kt similarity index 100% rename from src/main/kotlin/org/store/clothstar/category/repository/CategoryRepository.kt rename to src/main/kotlin/org/store/clothstar/category/repository/CategoryJpaRepository.kt diff --git a/src/main/kotlin/org/store/clothstar/common/config/CustomAuthenticationEntryPoint.kt b/src/main/kotlin/org/store/clothstar/common/config/CustomAuthenticationEntryPoint.kt index d8c7d3e..d9464ef 100644 --- a/src/main/kotlin/org/store/clothstar/common/config/CustomAuthenticationEntryPoint.kt +++ b/src/main/kotlin/org/store/clothstar/common/config/CustomAuthenticationEntryPoint.kt @@ -22,7 +22,7 @@ class CustomAuthenticationEntryPoint : AuthenticationEntryPoint { authException: AuthenticationException, ) { log.error { "인증 실패 로직 실행" } - + response.status = HttpServletResponse.SC_UNAUTHORIZED response.characterEncoding = "UTF-8" response.contentType = "application/json" diff --git a/src/main/kotlin/org/store/clothstar/member/domain/Address.kt b/src/main/kotlin/org/store/clothstar/member/domain/Address.kt index 052401a..160daf8 100644 --- a/src/main/kotlin/org/store/clothstar/member/domain/Address.kt +++ b/src/main/kotlin/org/store/clothstar/member/domain/Address.kt @@ -16,5 +16,4 @@ class Address( @Embedded val addressInfo: AddressInfo, -) : BaseEntity() { -} \ No newline at end of file +) : BaseEntity() \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/member/domain/vo/AddressInfo.kt b/src/main/kotlin/org/store/clothstar/member/domain/vo/AddressInfo.kt index 6e9d1e9..cf7fb6c 100644 --- a/src/main/kotlin/org/store/clothstar/member/domain/vo/AddressInfo.kt +++ b/src/main/kotlin/org/store/clothstar/member/domain/vo/AddressInfo.kt @@ -7,4 +7,14 @@ class AddressInfo( val addressBasic: String, val addressDetail: String, val zipNo: String, -) \ No newline at end of file +) { + companion object { + fun init(): AddressInfo { + return AddressInfo( + addressBasic = "address1", + addressDetail = "address2", + zipNo = "01234", + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/member/dto/request/MemberLoginRequest.kt b/src/main/kotlin/org/store/clothstar/member/dto/request/MemberLoginRequest.kt index 84b999b..f4589d3 100644 --- a/src/main/kotlin/org/store/clothstar/member/dto/request/MemberLoginRequest.kt +++ b/src/main/kotlin/org/store/clothstar/member/dto/request/MemberLoginRequest.kt @@ -9,6 +9,6 @@ class MemberLoginRequest( val password: String, ) { constructor() : this("", "") { - + } } \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/member/service/AddressServiceImpl.kt b/src/main/kotlin/org/store/clothstar/member/service/AddressServiceImpl.kt index e11b474..c747bb8 100644 --- a/src/main/kotlin/org/store/clothstar/member/service/AddressServiceImpl.kt +++ b/src/main/kotlin/org/store/clothstar/member/service/AddressServiceImpl.kt @@ -3,7 +3,6 @@ package org.store.clothstar.member.service import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -import org.springframework.web.server.ResponseStatusException import org.store.clothstar.common.error.ErrorCode import org.store.clothstar.common.error.exception.NotFoundAddressException import org.store.clothstar.common.error.exception.NotFoundMemberException diff --git a/src/main/kotlin/org/store/clothstar/order/controller/OrderDetailController.kt b/src/main/kotlin/org/store/clothstar/order/controller/OrderDetailController.kt deleted file mode 100644 index e5584c4..0000000 --- a/src/main/kotlin/org/store/clothstar/order/controller/OrderDetailController.kt +++ /dev/null @@ -1,19 +0,0 @@ -//package org.store.clothstar.order.controller - -//@Tag(name = "OrderDetail", description = "주문 내 개별 상품에 대한 옵션, 수량 등을 나타내는, 주문상세(OrderDetail) 정보 관리에 대한 API 입니다.") -//@RestController -//class OrderDetailController( -// private val orderDetailService: OrderDetailService, -//) { -// @Operation(summary = "주문상세 추가 저장", description = "개별 상품에 대한 주문상세(상품명, 가격, 개수...)를 특정 주문에 추가 저장한다.") -// @PostMapping -// fun addOrderDetail(@RequestBody @Validated addOrderDetailRequest: AddOrderDetailRequest): ResponseEntity { -// val orderDetailId = orderDetailService.addOrderDetail(addOrderDetailRequest) -// -// return ResponseEntity.ok( -// SaveResponseDTO( -// orderDetailId, HttpStatus.OK.value(), "주문상세가 정상적으로 생성되었습니다." -// ) -// ) -// } -//} \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/order/controller/OrderSellerController.kt b/src/main/kotlin/org/store/clothstar/order/controller/OrderSellerController.kt index 3ef5894..4cf6e01 100644 --- a/src/main/kotlin/org/store/clothstar/order/controller/OrderSellerController.kt +++ b/src/main/kotlin/org/store/clothstar/order/controller/OrderSellerController.kt @@ -8,12 +8,10 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.PatchMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController +import org.springframework.web.bind.annotation.* import org.store.clothstar.common.dto.ErrorResponseDTO import org.store.clothstar.common.dto.MessageDTO +import org.store.clothstar.order.dto.response.OrderResponse import org.store.clothstar.order.service.OrderSellerService @Tag(name = "OrderSeller", description = "판매자(OrderSeller)의 주문 정보 관리에 대한 API 입니다.") @@ -22,13 +20,13 @@ import org.store.clothstar.order.service.OrderSellerService class OrderSellerController( private val orderSellerService: OrderSellerService ) { -// -// @Operation(summary = "(판매자) WAITING 주문 리스트 조회", description = "(판매자) 주문상태가 '승인대기'인 주문 리스트를 조회한다.") -// @GetMapping -// fun getWaitingOrder(): ResponseEntity> { -// val orderResponseList: List = orderSellerService.getConfirmedOrder() -// return ResponseEntity.ok(orderResponseList) -// } + + @Operation(summary = "(판매자) WAITING 주문 리스트 조회", description = "(판매자) 주문상태가 '승인대기'인 주문 리스트를 조회한다.") + @GetMapping + fun getWaitingOrder(): ResponseEntity> { + val orderResponseList: List = orderSellerService.getConfirmedOrders() + return ResponseEntity.ok(orderResponseList) + } @Operation(summary = "판매자 주문 승인", description = "판매자가 주문을 출고처리한다.") @ApiResponses( diff --git a/src/main/kotlin/org/store/clothstar/order/controller/OrderUserController.kt b/src/main/kotlin/org/store/clothstar/order/controller/OrderUserController.kt index 10479eb..d07256d 100644 --- a/src/main/kotlin/org/store/clothstar/order/controller/OrderUserController.kt +++ b/src/main/kotlin/org/store/clothstar/order/controller/OrderUserController.kt @@ -6,13 +6,20 @@ import io.swagger.v3.oas.annotations.media.Schema import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable +import org.springframework.data.domain.Slice +import org.springframework.data.web.PageableDefault import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.* import org.store.clothstar.common.dto.ErrorResponseDTO import org.store.clothstar.common.dto.MessageDTO +import org.store.clothstar.common.dto.SaveResponseDTO +import org.store.clothstar.order.dto.request.AddOrderDetailRequest import org.store.clothstar.order.dto.request.OrderRequestWrapper +import org.store.clothstar.order.dto.response.OrderResponse import org.store.clothstar.order.dto.response.SaveOrderResponse import org.store.clothstar.order.service.OrderUserService @@ -20,14 +27,32 @@ import org.store.clothstar.order.service.OrderUserService @RestController @RequestMapping("/v1/orders") class OrderUserController( - private val orderService: OrderUserService + private val orderUserService: OrderUserService, ) { -// @Operation(summary = "단일 주문 조회", description = "단일 주문의 정보를 조회한다.") -// @GetMapping("/{orderId}") -// fun getOrder(@PathVariable orderId: String): ResponseEntity { -// val orderResponse: OrderResponse = orderService.getOrder(orderId) -// return ResponseEntity.ok(orderResponse) -// } + @Operation(summary = "단일 주문 조회", description = "단일 주문의 정보를 조회한다.") + @GetMapping("/{orderId}") + fun getOrder(@PathVariable orderId: String): ResponseEntity { + val orderResponse: OrderResponse = orderUserService.getOrder(orderId) + return ResponseEntity.ok(orderResponse) + } + + @Operation(summary = "전체 주문 조회 offset 페이징", description = "전체 주문 리스트를 offset 페이징 형식으로 가져온다.") + @GetMapping("/offset") + fun getAllOrderOffsetPaging( + @PageableDefault(size = 15) pageable: Pageable + ): ResponseEntity> { + val orderPages: Page = orderUserService.getAllOrderOffsetPaging(pageable) + return ResponseEntity.ok(orderPages) + } + + @Operation(summary = "전체 주문 조회 slice 페이징", description = "전체 주문 리스트를 slice 페이징 형식으로 가져온다.") + @GetMapping("/slice") + fun getAllOrderSlicePaging( + @PageableDefault(size = 15) pageable: Pageable + ): ResponseEntity> { + val orderPages: Slice = orderUserService.getAllOrderSlicePaging(pageable) + return ResponseEntity.ok(orderPages) + } @Operation(summary = "주문 생성", description = "단일 주문을 생성한다.") @ApiResponses( @@ -48,11 +73,35 @@ class OrderUserController( ) @PostMapping fun saveOrder(@RequestBody @Validated orderRequestWrapper: OrderRequestWrapper): ResponseEntity { - val orderId: String = orderService.saveOrder(orderRequestWrapper) + val orderId: String = orderUserService.saveOrder(orderRequestWrapper) val saveOrderResponse = SaveOrderResponse(orderId, HttpStatus.OK.value(), "주문이 정상적으로 생성되었습니다.") return ResponseEntity.ok(saveOrderResponse) } + @Operation(summary = "주문상세 추가 저장", description = "개별 상품에 대한 주문상세(상품명, 가격, 개수...)를 특정 주문에 추가 저장한다.") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", description = "주문상세가 정상적으로 생성되었습니다.", + content = [Content(schema = Schema(implementation = SaveOrderResponse::class))] + ), + ApiResponse( + responseCode = "404", description = "", + content = [Content(schema = Schema(implementation = ErrorResponseDTO::class))] + ), + ApiResponse( + responseCode = "400", description = "", + content = [Content(schema = Schema(implementation = ErrorResponseDTO::class))] + ), + ] + ) + @PostMapping("/details") + fun addOrderDetail(@RequestBody @Validated addOrderDetailRequest: AddOrderDetailRequest): ResponseEntity { + val orderDetailId = orderUserService.addOrderDetail(addOrderDetailRequest) + val saveResponseDTO = SaveResponseDTO(orderDetailId, HttpStatus.OK.value(), "주문상세가 정상적으로 생성되었습니다.") + return ResponseEntity.ok(saveResponseDTO) + } + @Operation(summary = "구매자 구매 확정", description = "구매자가 주문을 구매확정하면, 주문상태가 '구매확정'으로 변경된다(단, 주문상태가 '배송완료'일 때만 가능).") @ApiResponses( value = [ @@ -72,7 +121,7 @@ class OrderUserController( ) @PatchMapping("{orderId}/complete") fun confirmOrder(@PathVariable orderId: String): ResponseEntity { - orderService.completeOrder(orderId) + orderUserService.completeOrder(orderId) val messageDTO = MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 구매 확정 되었습니다.") return ResponseEntity.ok(messageDTO) } @@ -99,7 +148,7 @@ class OrderUserController( ) @PatchMapping("{orderId}/cancel") fun cancelOrder(@PathVariable orderId: String): ResponseEntity { - orderService.cancelOrder(orderId) + orderUserService.cancelOrder(orderId) val messageDTO = MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 취소되었습니다.") return ResponseEntity.ok(messageDTO) } @@ -119,7 +168,7 @@ class OrderUserController( @Operation(summary = "주문 삭제", description = "주문 삭제시간을 현재시간으로 업데이트 한다.") @DeleteMapping("{orderId}") fun deleteOrder(@PathVariable orderId: String): ResponseEntity { - orderService.updateDeleteAt(orderId) + orderUserService.updateDeleteAt(orderId) val messageDTO = MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 삭제되었습니다.") return ResponseEntity.ok(messageDTO) } diff --git a/src/main/kotlin/org/store/clothstar/order/dto/response/OrderDetailResponse.kt b/src/main/kotlin/org/store/clothstar/order/dto/response/OrderDetailResponse.kt deleted file mode 100644 index 5fb27dc..0000000 --- a/src/main/kotlin/org/store/clothstar/order/dto/response/OrderDetailResponse.kt +++ /dev/null @@ -1,42 +0,0 @@ -//package org.store.clothstar.order.dto.response -// -//import io.swagger.v3.oas.annotations.media.Schema -// -//@Schema(description = "주문 상세 조회용 Response") -//class OrderDetailResponse( -// @Schema(description = "주문 상세 번호", example = "1") -// val orderDetailId: Long, -// -// @Schema(description = "주문 번호", example = "1") -// val orderId: String, -// -// @Schema(description = "상품 번호", example = "1") -// val productLineId: Long, -// -// @Schema(description = "상품 옵션 번호", example = "1") -// val productId: Long, -// -// @Schema(description = "상품 수량", example = "2") -// val quantity: Int = 0, -// -// @Schema(description = "고정 가격", example = "15000") -// val fixedPrice: Int = 0, -// -// @Schema(description = "상품 종류 하나당 총 가격", example = "30000") -// val oneKindTotalPrice: Int = 0, -// -// @Schema(description = "상품 이름", example = "나이키 반팔티") -// val name: String, -// -// @Schema(description = "옵션 상품 재고", example = "30") -// val stock: Long, -// -// @Schema(description = "옵션 이름", example = "검정") -// val optionName: String, -// -// @Schema(description = "옵션 추가 비용", example = "0") -// val extraCharge: Int, -// -// @Schema(description = "브랜드 이름", example = "나이키") -// val brandName: String, -//) \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/order/dto/response/OrderResponse.kt b/src/main/kotlin/org/store/clothstar/order/dto/response/OrderResponse.kt index 9c2e831..f411538 100644 --- a/src/main/kotlin/org/store/clothstar/order/dto/response/OrderResponse.kt +++ b/src/main/kotlin/org/store/clothstar/order/dto/response/OrderResponse.kt @@ -29,7 +29,7 @@ class OrderResponse( val totalPrice: TotalPrice, - var orderDetailList: List = ArrayList(), + var orderDetailList: List = arrayListOf(), ) { fun updateOrderDetailList(orderDetailDTOList: List) { diff --git a/src/main/kotlin/org/store/clothstar/order/repository/OrderRepository.kt b/src/main/kotlin/org/store/clothstar/order/repository/OrderRepository.kt index 7a2cc75..ccd63a1 100644 --- a/src/main/kotlin/org/store/clothstar/order/repository/OrderRepository.kt +++ b/src/main/kotlin/org/store/clothstar/order/repository/OrderRepository.kt @@ -1,25 +1,12 @@ package org.store.clothstar.order.repository import org.springframework.data.jpa.repository.JpaRepository -import org.springframework.data.jpa.repository.Modifying import org.springframework.data.jpa.repository.Query -import org.springframework.data.repository.query.Param -import org.springframework.transaction.annotation.Transactional import org.store.clothstar.order.domain.Order interface OrderRepository : JpaRepository { - @Query("SELECT o FROM orders o WHERE o.status = 'CONFIRMED' AND o.deletedAt is null") - fun findConfirmedOrders(): List - - @Transactional - @Modifying - @Query("UPDATE orders o SET o.status = 'APPROVE' WHERE o.orderId = :orderId") - fun approveOrder(@Param("orderId") orderId: String) - - @Transactional - @Modifying - @Query("UPDATE orders o SET o.status = 'CANCEL' WHERE o.orderId = :orderId") - fun cancelOrder(@Param("orderId") orderId: String) - fun findByOrderIdAndDeletedAtIsNull(orderId: String): Order? + + @Query("SELECT o FROM orders o WHERE o.status = 'CONFIRMED' AND o.deletedAt is null") + fun findConfirmedAndNotDeletedOrders(): List } \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/order/service/OrderDetailService.kt b/src/main/kotlin/org/store/clothstar/order/service/OrderDetailService.kt deleted file mode 100644 index 65e82b6..0000000 --- a/src/main/kotlin/org/store/clothstar/order/service/OrderDetailService.kt +++ /dev/null @@ -1,117 +0,0 @@ -package org.store.clothstar.order.service - -import org.springframework.data.repository.findByIdOrNull -import org.springframework.http.HttpStatus -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.server.ResponseStatusException -import org.store.clothstar.order.domain.vo.Status -import org.store.clothstar.order.dto.request.AddOrderDetailRequest -import org.store.clothstar.order.dto.request.CreateOrderDetailRequest -import org.store.clothstar.order.repository.OrderDetailRepository -import org.store.clothstar.order.repository.OrderRepository -import org.store.clothstar.product.domain.Item -import org.store.clothstar.product.repository.ItemRepository -import org.store.clothstar.product.repository.ProductRepository -import org.store.clothstar.product.service.ItemService - -@Service -class OrderDetailService( - private val orderRepository: OrderRepository, - private val orderDetailRepository: OrderDetailRepository, - private val productRepository: ProductRepository, - private val itemRepository: ItemRepository, - private val itemService: ItemService, -) { - // 주문 생성시 같이 호출되는 주문 상세 생성 메서드 - 하나의 트랜잭션으로 묶임 - @Transactional - fun saveOrderDetailWithOrder(createOrderDetailRequest: CreateOrderDetailRequest, orderId: String) { - val order = orderRepository.findByIdOrNull(orderId) - ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "주문 정보를 찾을 수 없습니다.") - - val product = productRepository.findByIdOrNull(createOrderDetailRequest.productId) - ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "상품 옵션 정보를 찾을 수 없습니다.") - - val item = itemRepository.findByIdOrNull(createOrderDetailRequest.itemId) - ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "상품 정보를 찾을 수 없습니다.") - - // 주문상세 생성 유효성 검사: 주문 수량이 상품 재고보다 클 경우, 주문이 생성되지 않는다. - if (createOrderDetailRequest.quantity > item.stock) { - throw ResponseStatusException(HttpStatus.BAD_REQUEST, "주문 개수가 재고보다 더 많습니다.") - } - - val orderDetail = createOrderDetailRequest.toOrderDetail(order, product, item) - orderDetailRepository.save(orderDetail) - - // 주문 정보 업데이트: 주문 상세 생성에 따른, 총 상품 금액과 총 결제 금액 업데이트 - val newTotalProductsPrice = order.totalPrice.products + orderDetail.price.oneKindTotalPrice - val newTotalPaymentPrice = - order.totalPrice.products + order.totalPrice.shipping + orderDetail.price.oneKindTotalPrice - - order.totalPrice.updatePrices(newTotalProductsPrice, newTotalPaymentPrice) - - // 주문 수량만큼 상품 재고 차감 - updateProductStock(item, orderDetail.quantity) - } - - // 주문 상세 추가 생성 - @Transactional - fun addOrderDetail(addOrderDetailRequest: AddOrderDetailRequest): Long { - val order = orderRepository.findByIdOrNull(addOrderDetailRequest.orderId) - ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "주문 정보를 찾을 수 없습니다.") - - val product = productRepository.findByIdOrNull(addOrderDetailRequest.productId) - ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "상품 옵션 정보를 찾을 수 없습니다.") - - val item = itemRepository.findByIdOrNull(addOrderDetailRequest.itemId) - ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "상품 정보를 찾을 수 없습니다.") - - if (addOrderDetailRequest.quantity > item.stock) { - throw ResponseStatusException(HttpStatus.BAD_REQUEST, "주문 개수가 재고보다 더 많습니다.") - } - - if (order.status != Status.CONFIRMED) { - throw ResponseStatusException(HttpStatus.BAD_REQUEST, "이미 입금된 상태에서는 추가 주문이 불가능합니다.") - } - - val orderDetail = addOrderDetailRequest.toOrderDetail(order, product, item) - orderDetailRepository.save(orderDetail) - - val newTotalProductsPrice = order.totalPrice.products + orderDetail.price.oneKindTotalPrice - val newTotalPaymentPrice = - order.totalPrice.products + order.totalPrice.shipping + orderDetail.price.oneKindTotalPrice - - order.totalPrice.updatePrices(newTotalProductsPrice, newTotalPaymentPrice) - - updateProductStock(item, orderDetail.quantity) - - return orderDetail.orderDetailId!! - } - - @Transactional - fun updateDeleteAt(orderDetailId: Long) { - val orderDetail = orderDetailRepository.findById(orderDetailId) - .orElseThrow { ResponseStatusException(HttpStatus.NOT_FOUND, "주문상세 번호를 찾을 수 없습니다.") } - - if (orderDetail.deletedAt != null) { - throw ResponseStatusException(HttpStatus.NOT_FOUND, "이미 삭제된 주문입니다.") - } - - restoreStockByOrderDetail(orderDetailId) - orderDetail.updateDeletedAt() - } - - @Transactional - fun updateProductStock(item: Item, quantity: Int) { - val updatedStock = item.stock - quantity - item.updateStock(updatedStock) - } - - @Transactional - fun restoreStockByOrderDetail(orderDetailId: Long) { - val orderDetail = orderDetailRepository.findByIdOrNull(orderDetailId) - ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "주문상세 번호를 찾을 수 없습니다.") - - itemService.restoreProductStockByOrderDetail(orderDetail) - } -} \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/order/service/OrderSellerService.kt b/src/main/kotlin/org/store/clothstar/order/service/OrderSellerService.kt index 0419a79..6989674 100644 --- a/src/main/kotlin/org/store/clothstar/order/service/OrderSellerService.kt +++ b/src/main/kotlin/org/store/clothstar/order/service/OrderSellerService.kt @@ -1,13 +1,19 @@ package org.store.clothstar.order.service import org.springframework.data.repository.findByIdOrNull +import org.springframework.http.HttpStatus import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import org.springframework.web.server.ResponseStatusException import org.store.clothstar.common.error.ErrorCode import org.store.clothstar.common.error.exception.order.OrderNotFoundException +import org.store.clothstar.member.domain.Address +import org.store.clothstar.member.domain.Member +import org.store.clothstar.member.domain.Seller import org.store.clothstar.member.service.AddressService import org.store.clothstar.member.service.MemberService import org.store.clothstar.member.service.SellerService +import org.store.clothstar.order.domain.Order import org.store.clothstar.order.domain.OrderDetail import org.store.clothstar.order.domain.vo.OrderDetailDTO import org.store.clothstar.order.domain.vo.Status @@ -28,40 +34,50 @@ class OrderSellerService( private val productService: ProductService, ) { @Transactional(readOnly = true) - fun getConfirmedOrder(): List { - val confirmedOrders = orderRepository.findConfirmedOrders() + fun getConfirmedOrders(): List { + val confirmedOrders: List = orderRepository.findConfirmedAndNotDeletedOrders() - return confirmedOrders - .map { order -> - order?.let { - val member = memberService.getMemberByMemberId(order.memberId) - val seller = sellerService.getSellerById(order.memberId) - val address = addressService.getAddressById(order.addressId) - val orderResponse = OrderResponse.from(order, member, address) + return confirmedOrders.map { + // order 관련 member, address, seller 불러오기 + val member: Member = memberService.getMemberByMemberId(it.memberId) + val address: Address = addressService.getAddressById(it.addressId) + val seller: Seller = sellerService.getSellerById(it.memberId) - val orderDetails = order.orderDetails - .filter { orderDetail -> orderDetail.deletedAt == null } - .toList() - val itemIds = orderDetails.map(OrderDetail::itemId).toList() - val productIds = orderDetails.map(OrderDetail::productId).toList() + // 응답 DTO 생성(주문상세 리스트는 빈 상태) + val orderResponse = OrderResponse.from(it, member, address) - val items = itemService.findByIdIn(itemIds) - val products = productService.findByProductIdIn(productIds) + // 주문으로부터 주문상세 리스트 가져오기 + val orderDetails: List = it.orderDetails + .filter { it.deletedAt == null } - val itemMap: Map = items.map { it.itemId!! to it }.toMap() - val productMap: Map = products.map { it.productId!! to it }.toMap() + // 주문상세 리스트로부터 productId/itemId 리스트 가져오기 + val productIds: List = orderDetails.map { it.productId } + val itemIds: List = orderDetails.map { it.itemId } - val orderDetailDTOList = orderDetails.map { orderDetail: OrderDetail -> - val itemEntity = itemMap[orderDetail.itemId]!! - val productEntity = productMap[orderDetail.productId]!! - val brandName = seller.brandName - OrderDetailDTO.from(orderDetail, itemEntity, productEntity, brandName) - }.toList() + // productIds, itemIds로부터 Product/Item 리스트 가져오기 + val products: List = productService.findByProductIdIn(productIds) + val items: List = itemService.findByIdIn(itemIds) - orderResponse.updateOrderDetailList(orderDetailDTOList) - orderResponse - } ?: throw IllegalArgumentException("오더 리스트가 없습니다.") - }.toList() + // Id, Entity를 Map으로 만들기 + val productMap: Map = products.associateBy { it.productId!! } + val itemMap: Map = items.associateBy { it.itemId!! } + + // Map으로부터 Id, Entity를 가져오면서 주문상세 DTO 리스트 만들기 + val orderDetailDTOList: List = orderDetails.map { + val product: Product = productMap[it.productId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found") + val item: Item = itemMap[it.itemId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Item not found") + val brandName: String = seller.brandName + OrderDetailDTO.from(it, item, product, brandName) + } + + // 응답 DTO에 주문상세 DTO 리스트 추가 + orderResponse.updateOrderDetailList(orderDetailDTOList) + + // 응답 DTO 반환 + orderResponse + } } @Transactional diff --git a/src/main/kotlin/org/store/clothstar/order/service/OrderUserService.kt b/src/main/kotlin/org/store/clothstar/order/service/OrderUserService.kt index 6fc83a5..89bf978 100644 --- a/src/main/kotlin/org/store/clothstar/order/service/OrderUserService.kt +++ b/src/main/kotlin/org/store/clothstar/order/service/OrderUserService.kt @@ -1,27 +1,227 @@ package org.store.clothstar.order.service +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable +import org.springframework.data.domain.Slice import org.springframework.data.repository.findByIdOrNull +import org.springframework.http.HttpStatus import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import org.springframework.web.server.ResponseStatusException import org.store.clothstar.common.error.ErrorCode +import org.store.clothstar.common.error.exception.order.InsufficientStockException import org.store.clothstar.common.error.exception.order.OrderNotFoundException +import org.store.clothstar.member.domain.Address +import org.store.clothstar.member.domain.Member +import org.store.clothstar.member.domain.Seller +import org.store.clothstar.member.service.AddressService +import org.store.clothstar.member.service.MemberService +import org.store.clothstar.member.service.SellerService +import org.store.clothstar.order.domain.Order +import org.store.clothstar.order.domain.OrderDetail +import org.store.clothstar.order.domain.vo.OrderDetailDTO import org.store.clothstar.order.domain.vo.Status +import org.store.clothstar.order.dto.request.AddOrderDetailRequest import org.store.clothstar.order.dto.request.OrderRequestWrapper +import org.store.clothstar.order.dto.response.OrderResponse import org.store.clothstar.order.repository.OrderDetailRepository import org.store.clothstar.order.repository.OrderRepository import org.store.clothstar.order.service.OrderSave.OrderSaveFacade +import org.store.clothstar.product.domain.Item +import org.store.clothstar.product.domain.Product +import org.store.clothstar.product.service.ItemService +import org.store.clothstar.product.service.ProductService @Service class OrderUserService( private val orderSaveFacade: OrderSaveFacade, private val orderRepository: OrderRepository, private val orderDetailRepository: OrderDetailRepository, + private val memberService: MemberService, + private val addressService: AddressService, + private val sellerService: SellerService, + private val productService: ProductService, + private val itemService: ItemService, ) { + @Transactional(readOnly = true) + fun getOrder(orderId: String): OrderResponse { + // orderId 관련 order, member, address, seller 불러오기 + val order: Order = orderRepository.findByOrderIdAndDeletedAtIsNull(orderId) + ?: throw OrderNotFoundException(ErrorCode.NOT_FOUND_ORDER) + val member: Member = memberService.getMemberByMemberId(order.memberId) + val address: Address = addressService.getAddressById(order.addressId) + val seller: Seller = sellerService.getSellerById(order.memberId) + + // 응답 DTO 생성(주문상세 리스트는 빈 상태) + val orderResponse = OrderResponse.from(order, member, address) + + // 주문으로부터 주문상세 리스트 가져오기 + val orderDetails: List = order.orderDetails + .filter { it.deletedAt == null } + + // 주문상세 리스트로부터 productId/itemId 리스트 가져오기 + val productIds: List = orderDetails.map { it.productId } + val itemIds: List = orderDetails.map { it.itemId } + + // productIds, itemIds로부터 Product/Item 리스트 가져오기 + val products: List = productService.findByProductIdIn(productIds) + val items: List = itemService.findByIdIn(itemIds) + + // Id, Entity를 Map으로 만들기 + val productMap: Map = products.associateBy { it.productId!! } + val itemMap: Map = items.associateBy { it.itemId!! } + + // Map으로부터 Id, Entity를 가져오면서 주문상세 DTO 리스트 만들기 + val orderDetailDTOList: List = orderDetails.map { + val product: Product = productMap[it.productId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found") + val item: Item = itemMap[it.itemId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Item not found") + val brandName: String = seller.brandName + OrderDetailDTO.from(it, item, product, brandName) + } + + // 응답 DTO에 주문상세 DTO 리스트 추가 + orderResponse.updateOrderDetailList(orderDetailDTOList) + + // 응답 DTO 반환 + return orderResponse + } + + fun getAllOrderOffsetPaging(pageable: Pageable): Page { + val orders: Page = orderRepository.findAll(pageable) + + return orders.map { + // order 관련 member, address, seller 불러오기 + val member: Member = memberService.getMemberByMemberId(it.memberId) + val address: Address = addressService.getAddressById(it.addressId) + val seller: Seller = sellerService.getSellerById(it.memberId) + + // 응답 DTO 생성(주문상세 리스트는 빈 상태) + val orderResponse = OrderResponse.from(it, member, address) + + // 주문으로부터 주문상세 리스트 가져오기 + val orderDetails: List = it.orderDetails + .filter { it.deletedAt == null } + + // 주문상세 리스트로부터 productId/itemId 리스트 가져오기 + val productIds: List = orderDetails.map { it.productId } + val itemIds: List = orderDetails.map { it.itemId } + + // productIds, itemIds로부터 Product/Item 리스트 가져오기 + val products: List = productService.findByProductIdIn(productIds) + val items: List = itemService.findByIdIn(itemIds) + + // Id, Entity를 Map으로 만들기 + val productMap: Map = products.associateBy { it.productId!! } + val itemMap: Map = items.associateBy { it.itemId!! } + + // Map으로부터 Id, Entity를 가져오면서 주문상세 DTO 리스트 만들기 + val orderDetailDTOList: List = orderDetails.map { + val product: Product = productMap[it.productId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found") + val item: Item = itemMap[it.itemId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Item not found") + val brandName: String = seller.brandName + OrderDetailDTO.from(it, item, product, brandName) + } + + // 응답 DTO에 주문상세 DTO 리스트 추가 + orderResponse.updateOrderDetailList(orderDetailDTOList) + + // 응답 DTO 반환 + orderResponse + } + } + + fun getAllOrderSlicePaging(pageable: Pageable): Slice { + val orders: Slice = orderRepository.findAll(pageable) + + return orders.map { + // order 관련 member, address, seller 불러오기 + val member: Member = memberService.getMemberByMemberId(it.memberId) + val address: Address = addressService.getAddressById(it.addressId) + val seller: Seller = sellerService.getSellerById(it.memberId) + + // 응답 DTO 생성(주문상세 리스트는 빈 상태) + val orderResponse = OrderResponse.from(it, member, address) + + // 주문으로부터 주문상세 리스트 가져오기 + val orderDetails: List = it.orderDetails + .filter { it.deletedAt == null } + + // 주문상세 리스트로부터 productId/itemId 리스트 가져오기 + val productIds: List = orderDetails.map { it.productId } + val itemIds: List = orderDetails.map { it.itemId } + + // productIds, itemIds로부터 Product/Item 리스트 가져오기 + val products: List = productService.findByProductIdIn(productIds) + val items: List = itemService.findByIdIn(itemIds) + + // Id, Entity를 Map으로 만들기 + val productMap: Map = products.associateBy { it.productId!! } + val itemMap: Map = items.associateBy { it.itemId!! } + + // Map으로부터 Id, Entity를 가져오면서 주문상세 DTO 리스트 만들기 + val orderDetailDTOList: List = orderDetails.map { + val product: Product = productMap[it.productId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found") + val item: Item = itemMap[it.itemId] + ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Item not found") + val brandName: String = seller.brandName + OrderDetailDTO.from(it, item, product, brandName) + } + + // 응답 DTO에 주문상세 DTO 리스트 추가 + orderResponse.updateOrderDetailList(orderDetailDTOList) + + // 응답 DTO 반환 + orderResponse + } + } + @Transactional fun saveOrder(orderRequestWrapper: OrderRequestWrapper): String { return orderSaveFacade.saveOrder(orderRequestWrapper) } + // 주문 상세 추가 생성( + @Transactional + fun addOrderDetail(addOrderDetailRequest: AddOrderDetailRequest): Long { + // 요청 DTO와 관련된 order, product, item 불러오기 + val order = orderRepository.findByIdOrNull(addOrderDetailRequest.orderId) + ?: throw OrderNotFoundException(ErrorCode.NOT_FOUND_ORDER) + val product: Product = productService.getProductById(addOrderDetailRequest.productId) + val item: Item = itemService.getItemById(addOrderDetailRequest.itemId) + + if (addOrderDetailRequest.quantity > item.stock) { + throw InsufficientStockException(ErrorCode.INSUFFICIENT_STOCK) + } + + if (order.status != Status.CONFIRMED) { + throw ResponseStatusException(HttpStatus.BAD_REQUEST, "이미 입금된 상태에서는 추가 주문이 불가능합니다.") + } + + val orderDetail = addOrderDetailRequest.toOrderDetail(order, product, item) + orderDetailRepository.save(orderDetail) + + val newTotalProductsPrice = order.totalPrice.products + orderDetail.price.oneKindTotalPrice + val newTotalPaymentPrice = + order.totalPrice.products + order.totalPrice.shipping + orderDetail.price.oneKindTotalPrice + + order.totalPrice.updatePrices(newTotalProductsPrice, newTotalPaymentPrice) + + updateProductStock(item, orderDetail.quantity) + + return orderDetail.orderDetailId!! + } + + @Transactional + fun updateProductStock(item: Item, quantity: Int) { + val updatedStock = item.stock - quantity + item.updateStock(updatedStock) + } + @Transactional fun completeOrder(orderId: String) { val order = orderRepository.findByIdOrNull(orderId) diff --git a/src/main/kotlin/org/store/clothstar/order/utils/CreateOrderObject.kt b/src/main/kotlin/org/store/clothstar/order/utils/CreateOrderObject.kt new file mode 100644 index 0000000..4138ed1 --- /dev/null +++ b/src/main/kotlin/org/store/clothstar/order/utils/CreateOrderObject.kt @@ -0,0 +1,75 @@ +package org.store.clothstar.order.utils + +import org.store.clothstar.category.domain.Category +import org.store.clothstar.order.domain.Order +import org.store.clothstar.order.domain.OrderDetail +import org.store.clothstar.order.domain.vo.PaymentMethod +import org.store.clothstar.order.domain.vo.Price +import org.store.clothstar.order.domain.vo.Status +import org.store.clothstar.order.domain.vo.TotalPrice +import org.store.clothstar.product.domain.Item +import org.store.clothstar.product.domain.Product +import org.store.clothstar.product.domain.type.DisplayStatus +import org.store.clothstar.product.domain.type.SaleStatus + +class CreateOrderObject { + companion object { + fun getCategory(): Category { + return Category( + categoryId = 1L, + categoryType = "상의", + ) + } + + fun getProduct(): Product { + return Product( + productId = 1L, + memberId = 1L, + categoryId = this.getCategory().categoryId!!, + name = "상품", + content = "상품내용", + price = 1000, + saleCount = 0, + displayStatus = DisplayStatus.VISIBLE, + saleStatus = SaleStatus.ALL, + ) + } + + fun getItem(): Item { + return Item( + itemId = 1L, + name = "상품 옵션 이름", + finalPrice = 2000, + stock = 10, + saleStatus = SaleStatus.ALL, + displayStatus = DisplayStatus.HIDDEN, + product = this.getProduct() + ) + } + + fun getOrder(): Order { + return Order( + orderId = "0eb44b79-6b9a-4ca9-8984-761e18101511", + memberId = 1L, + addressId = 1L, + status = Status.CONFIRMED, + paymentMethod = PaymentMethod.CARD, + totalPrice = TotalPrice(shipping = 0, products = 0, payment = 0) + ) + } + + fun getOrderDetail(): OrderDetail { + return OrderDetail( + orderDetailId = 1L, + productId = this.getProduct().productId!!, + itemId = this.getItem().itemId!!, + quantity = 1, + price = Price( + fixedPrice = this.getProduct().price, + oneKindTotalPrice = 10000 + ), + order = this.getOrder() + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/store/clothstar/product/controller/ProductController.kt b/src/main/kotlin/org/store/clothstar/product/controller/ProductController.kt index 9adf938..19e0d4c 100644 --- a/src/main/kotlin/org/store/clothstar/product/controller/ProductController.kt +++ b/src/main/kotlin/org/store/clothstar/product/controller/ProductController.kt @@ -18,7 +18,7 @@ import org.store.clothstar.product.service.ProductApplicationService @RestController private class ProductController( private val productApplicationService: ProductApplicationService, - ) { +) { @PostMapping @Operation( summary = "상품 등록", diff --git a/src/main/kotlin/org/store/clothstar/product/domain/Item.kt b/src/main/kotlin/org/store/clothstar/product/domain/Item.kt index a4efefe..b336704 100644 --- a/src/main/kotlin/org/store/clothstar/product/domain/Item.kt +++ b/src/main/kotlin/org/store/clothstar/product/domain/Item.kt @@ -1,7 +1,6 @@ package org.store.clothstar.product.domain import jakarta.persistence.* -import org.hibernate.annotations.BatchSize import org.store.clothstar.product.domain.type.DisplayStatus import org.store.clothstar.product.domain.type.SaleStatus diff --git a/src/main/kotlin/org/store/clothstar/product/domain/ItemAttribute.kt b/src/main/kotlin/org/store/clothstar/product/domain/ItemAttribute.kt index 8262c68..505038a 100644 --- a/src/main/kotlin/org/store/clothstar/product/domain/ItemAttribute.kt +++ b/src/main/kotlin/org/store/clothstar/product/domain/ItemAttribute.kt @@ -1,7 +1,6 @@ package org.store.clothstar.product.domain import jakarta.persistence.Embeddable -import org.hibernate.annotations.BatchSize /** * { "optionId": 1, "name": "색상", "value": "중청", "valueId": 1 } diff --git a/src/main/kotlin/org/store/clothstar/product/domain/Product.kt b/src/main/kotlin/org/store/clothstar/product/domain/Product.kt index d415eca..066e501 100644 --- a/src/main/kotlin/org/store/clothstar/product/domain/Product.kt +++ b/src/main/kotlin/org/store/clothstar/product/domain/Product.kt @@ -1,7 +1,6 @@ package org.store.clothstar.product.domain import jakarta.persistence.* -import org.hibernate.annotations.BatchSize import org.hibernate.annotations.Fetch import org.hibernate.annotations.FetchMode import org.store.clothstar.common.entity.BaseEntity diff --git a/src/main/kotlin/org/store/clothstar/product/domain/ProductImage.kt b/src/main/kotlin/org/store/clothstar/product/domain/ProductImage.kt index d1002c5..be79774 100644 --- a/src/main/kotlin/org/store/clothstar/product/domain/ProductImage.kt +++ b/src/main/kotlin/org/store/clothstar/product/domain/ProductImage.kt @@ -3,7 +3,6 @@ package org.store.clothstar.product.domain import jakarta.persistence.Embeddable import jakarta.persistence.EnumType import jakarta.persistence.Enumerated -import org.hibernate.annotations.BatchSize import org.store.clothstar.product.domain.type.ImageType @Embeddable diff --git a/src/main/kotlin/org/store/clothstar/product/domain/ProductOption.kt b/src/main/kotlin/org/store/clothstar/product/domain/ProductOption.kt index 8bb58f5..6024d5a 100644 --- a/src/main/kotlin/org/store/clothstar/product/domain/ProductOption.kt +++ b/src/main/kotlin/org/store/clothstar/product/domain/ProductOption.kt @@ -1,7 +1,6 @@ package org.store.clothstar.product.domain import jakarta.persistence.* -import org.hibernate.annotations.BatchSize /** diff --git a/src/main/kotlin/org/store/clothstar/product/dto/request/UpdateDisplayStatusRequest.kt b/src/main/kotlin/org/store/clothstar/product/dto/request/UpdateDisplayStatusRequest.kt index a44536a..667cbe9 100644 --- a/src/main/kotlin/org/store/clothstar/product/dto/request/UpdateDisplayStatusRequest.kt +++ b/src/main/kotlin/org/store/clothstar/product/dto/request/UpdateDisplayStatusRequest.kt @@ -4,7 +4,7 @@ package org.store.clothstar.product.dto.request import jakarta.validation.constraints.NotNull import org.store.clothstar.product.domain.type.DisplayStatus -class UpdateDisplayStatusRequest ( +class UpdateDisplayStatusRequest( @NotNull(message = "진열 상태를 설정해주세요.") val displayStatus: DisplayStatus, diff --git a/src/main/kotlin/org/store/clothstar/product/repository/ProductRepository.kt b/src/main/kotlin/org/store/clothstar/product/repository/ProductRepository.kt index 33113c9..ebe40e4 100644 --- a/src/main/kotlin/org/store/clothstar/product/repository/ProductRepository.kt +++ b/src/main/kotlin/org/store/clothstar/product/repository/ProductRepository.kt @@ -1,6 +1,5 @@ package org.store.clothstar.product.repository -import org.springframework.data.jpa.repository.EntityGraph import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository import org.store.clothstar.product.domain.Product diff --git a/src/main/kotlin/org/store/clothstar/product/service/ProductApplicationService.kt b/src/main/kotlin/org/store/clothstar/product/service/ProductApplicationService.kt index 0dcf8b7..d670f94 100644 --- a/src/main/kotlin/org/store/clothstar/product/service/ProductApplicationService.kt +++ b/src/main/kotlin/org/store/clothstar/product/service/ProductApplicationService.kt @@ -6,7 +6,6 @@ import org.springframework.web.multipart.MultipartFile import org.store.clothstar.member.domain.Member import org.store.clothstar.member.domain.vo.MemberShoppingActivity import org.store.clothstar.member.service.MemberService -import org.store.clothstar.product.domain.Product import org.store.clothstar.product.domain.ProductImage import org.store.clothstar.product.domain.type.DisplayStatus import org.store.clothstar.product.domain.type.ImageType diff --git a/src/main/resources/order.sql b/src/main/resources/order.sql index a9652a1..260568b 100644 --- a/src/main/resources/order.sql +++ b/src/main/resources/order.sql @@ -54,6 +54,9 @@ INSERT INTO product (product_id, created_at, deleted_at, updated_at, category_id name, price, sale_count, sale_status) VALUES (1, CURRENT_TIMESTAMP, NULL, CURRENT_TIMESTAMP, 1, '반팔', 'HIDDEN', 1, '오구반팔', 19900, 1000, 'ON_SALE'); +INSERT INTO seller (member_id, created_at, deleted_at, updated_at, biz_no, brand_name, total_sell_price) +VALUES (12, CURRENT_TIMESTAMP, NULL, CURRENT_TIMESTAMP, 1232 - 1234, '아디다스', 1000); + show create table order_detail; drop table if exists orders; @@ -70,4 +73,10 @@ from item; select * from product; select * -from address; \ No newline at end of file +from address; +select * +from member; +select * +from seller; +select * +from category; \ No newline at end of file diff --git a/src/test/kotlin/org/store/clothstar/member/util/CreateObject.kt b/src/test/kotlin/org/store/clothstar/member/util/CreateObject.kt index 50764e5..c0dbd89 100644 --- a/src/test/kotlin/org/store/clothstar/member/util/CreateObject.kt +++ b/src/test/kotlin/org/store/clothstar/member/util/CreateObject.kt @@ -1,15 +1,13 @@ package org.store.clothstar.member.util -import org.store.clothstar.member.domain.Account -import org.store.clothstar.member.domain.Member -import org.store.clothstar.member.domain.MemberRole +import org.store.clothstar.member.domain.* +import org.store.clothstar.member.domain.vo.AddressInfo import org.store.clothstar.member.domain.vo.MemberShoppingActivity import org.store.clothstar.member.dto.request.CreateAddressRequest import org.store.clothstar.member.dto.request.CreateMemberRequest import org.store.clothstar.member.dto.request.CreateSellerRequest import org.store.clothstar.member.dto.request.MemberLoginRequest - class CreateObject { companion object { private const val email = "test@naver.com" @@ -44,12 +42,33 @@ class CreateObject { fun getMember(): Member { return Member( + memberId = 1L, telNo = "010-1234-4444", name = "현수", memberShoppingActivity = MemberShoppingActivity.init() ) } + fun getAddress(): Address { + return Address( + addressId = 1L, + receiverName = "현수", + telNo = "010-1234-4444", + memberId = this.getMember().memberId!!, + deliveryRequest = "문 앞에 놔주세요", + addressInfo = AddressInfo.init() + ) + } + + fun getSeller(): Seller { + return Seller( + memberId = this.getMember().memberId!!, + brandName = "나이키", + bizNo = "123-123", + totalSellPrice = 1000 + ) + } + fun getAccount(userId: Long): Account { return Account( email = email, diff --git a/src/test/kotlin/org/store/clothstar/order/OrderIntegrationTest.kt b/src/test/kotlin/org/store/clothstar/order/OrderIntegrationTest.kt new file mode 100644 index 0000000..fcbb8da --- /dev/null +++ b/src/test/kotlin/org/store/clothstar/order/OrderIntegrationTest.kt @@ -0,0 +1,124 @@ +package org.store.clothstar.order + +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.http.MediaType +import org.springframework.test.annotation.DirtiesContext +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.ResultActions +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import org.springframework.transaction.annotation.Transactional +import org.store.clothstar.category.repository.CategoryJpaRepository +import org.store.clothstar.member.repository.AddressRepository +import org.store.clothstar.member.repository.MemberRepository +import org.store.clothstar.member.repository.SellerRepository +import org.store.clothstar.member.util.CreateObject +import org.store.clothstar.order.domain.Order +import org.store.clothstar.order.domain.OrderDetail +import org.store.clothstar.order.repository.OrderDetailRepository +import org.store.clothstar.order.repository.OrderRepository +import org.store.clothstar.order.utils.CreateOrderObject +import org.store.clothstar.product.repository.ItemRepository +import org.store.clothstar.product.repository.ProductRepository + +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") +@Transactional +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +class OrderIntegrationTest( + @Autowired + private val mockMvc: MockMvc, + + @Autowired + private val orderRepository: OrderRepository, + + @Autowired + private val memberRepository: MemberRepository, + + @Autowired + private val addressRepository: AddressRepository, + + @Autowired + private val categoryRepository: CategoryJpaRepository, + + @Autowired + private val productRepository: ProductRepository, + + @Autowired + private val itemRepository: ItemRepository, + + @Autowired + private val sellerRepository: SellerRepository, + + @Autowired + private val orderDetailRepository: OrderDetailRepository, +) { + private val ORDER_URL: String = "/v1/orders" + +// @Autowired +// private lateinit var mockMvc: MockMvc +// +// @Autowired +// private lateinit var orderRepository: OrderRepository +// +// @Autowired +// private lateinit var memberRepository: MemberRepository +// +// @Autowired +// private lateinit var addressRepository: AddressRepository +// +// @Autowired +// private lateinit var categoryRepository: CategoryJpaRepository +// +// @Autowired +// private lateinit var productRepository: ProductRepository +// +// @Autowired +// private lateinit var itemRepository: ItemRepository +// +// @Autowired +// private lateinit var sellerRepository: SellerRepository +// +// private val ORDER_URL: String = "/v1/orders" +// +// @Autowired +// private lateinit var orderDetailRepository: OrderDetailRepository + + @DisplayName("단일 주문 조회 통합테스트") + @Test + fun testGetOrder() { + //given + memberRepository.save(CreateObject.getMember()) + addressRepository.save(CreateObject.getAddress()) + categoryRepository.save(CreateOrderObject.getCategory()) + sellerRepository.save(CreateObject.getSeller()) + productRepository.save(CreateOrderObject.getProduct()) + itemRepository.save(CreateOrderObject.getItem()) + + val order: Order = CreateOrderObject.getOrder() + orderRepository.save(order) + val orderDetail: OrderDetail = orderDetailRepository.save(CreateOrderObject.getOrderDetail()) + order.addOrderDetail(orderDetail) + orderRepository.save(order) + + val orderId: String = order.orderId + val getOrderURL: String = ORDER_URL + "/" + orderId + + //when + val actions: ResultActions = mockMvc.perform( + MockMvcRequestBuilders.get(getOrderURL) + .contentType(MediaType.APPLICATION_JSON) + ) + + //then + actions.andExpect(status().isOk) + .andExpect(jsonPath("$.orderId").value(orderId)) + } +} \ No newline at end of file