Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;
import org.springframework.stereotype.Repository;

@Repository
public interface ItemSearchRepository extends ElasticsearchRepository<ItemDocument, String> {

@Query("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import hekireki.sanjijiksong.domain.order.dto.OrderListUpdateRequest;
import hekireki.sanjijiksong.domain.order.dto.OrderRequest;
import hekireki.sanjijiksong.domain.order.dto.OrderResponse;
import hekireki.sanjijiksong.domain.order.dto.PaymentRequest;
import hekireki.sanjijiksong.domain.order.service.OrderService;
import hekireki.sanjijiksong.global.security.dto.CustomUserDetails;
import jakarta.validation.Valid;
Expand All @@ -15,9 +16,14 @@
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/orders")
Expand All @@ -30,19 +36,27 @@ public class OrderController implements OrderApi {
// 주문 생성
@PostMapping
public ResponseEntity<OrderResponse> createOrder(
@RequestBody @Valid OrderRequest request,
@AuthenticationPrincipal CustomUserDetails userDetails
@RequestBody @Valid OrderRequest request,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
OrderResponse response = orderService.createOrder(userDetails.getUser(), request);
return ResponseEntity.status(HttpStatus.CREATED).body(response);

}

@PostMapping("/confirm")
public ResponseEntity<?> confirmOrder(
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody PaymentRequest paymentRequest
) {
return ResponseEntity.ok().body(orderService.confirmOrder(paymentRequest));
}

// 주문 취소
@PatchMapping("/{orderId}/cancel")
public ResponseEntity<Void> cancelOrder(
@PathVariable("orderId") Long orderId,
@AuthenticationPrincipal CustomUserDetails userDetails
@PathVariable("orderId") Long orderId,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
orderService.cancelOrder(orderId, userDetails.getUser());
return ResponseEntity.noContent().build();
Expand All @@ -51,9 +65,9 @@ public ResponseEntity<Void> cancelOrder(
// 주문 수정
@PatchMapping("/{orderId}/items/{itemId}")
public ResponseEntity<OrderResponse> updateOrderItems(
@PathVariable("orderId") Long orderId,
@RequestBody @Valid OrderListUpdateRequest request,
@AuthenticationPrincipal CustomUserDetails userDetails) {
@PathVariable("orderId") Long orderId,
@RequestBody @Valid OrderListUpdateRequest request,
@AuthenticationPrincipal CustomUserDetails userDetails) {
OrderResponse response = orderService.updateOrderItems(request, userDetails.getUser());
return ResponseEntity.ok(response);
}
Expand All @@ -62,8 +76,8 @@ public ResponseEntity<OrderResponse> updateOrderItems(
// 단일 주문 조회
@GetMapping("/{orderId}")
public ResponseEntity<OrderResponse> getOrderDetail(
@PathVariable("orderId") Long orderId,
@AuthenticationPrincipal CustomUserDetails userDetails
@PathVariable("orderId") Long orderId,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
OrderResponse response = orderService.getOrderDetail(orderId, userDetails.getUser());
return ResponseEntity.ok(response);
Expand All @@ -72,9 +86,9 @@ public ResponseEntity<OrderResponse> getOrderDetail(
// 내 주문 전체 조회
@GetMapping
public ResponseEntity<Page<OrderResponse>> getMyOrders(
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "10") int size
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "10") int size
) {
Pageable pageable = PageRequest.of(page, size);
Page<OrderResponse> orders = orderService.getMyOrders(userDetails.getUser(), pageable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,53 @@
import hekireki.sanjijiksong.domain.order.entity.Order;
import hekireki.sanjijiksong.domain.order.entity.OrderList;
import hekireki.sanjijiksong.domain.order.entity.OrderStatus;
import lombok.Builder;

import java.util.List;
import lombok.Builder;

public record OrderResponse(
Long orderId,
OrderStatus orderStatus,
int totalCount,
int totalPrice,
List<OrderListResponse> orderLists
Long orderId,
OrderStatus orderStatus,
int totalCount,
int totalPrice,
String payOrderId,
String paymentKey,
List<OrderListResponse> orderLists
) {

@Builder
public static OrderResponse from(Order order) {
return new OrderResponse(
order.getId(),
order.getOrderStatus(),
order.getStock(),
order.getTotalPrice(),
order.getOrderLists().stream()
.map(OrderListResponse::from)
.toList()
order.getId(),
order.getOrderStatus(),
order.getStock(),
order.getTotalPrice(),
order.getOrderId().toString(),
order.getTossPaymentKey(),
order.getOrderLists().stream()
.map(OrderListResponse::from)
.toList()
);
}

public record OrderListResponse(
Long itemId,
String itemName,
int price,
int count,
int totalPrice,
Long storeId,
String storeName
Long itemId,
String itemName,
int price,
int count,
int totalPrice,
Long storeId,
String storeName
) {

public static OrderListResponse from(OrderList ol) {
return new OrderListResponse(
ol.getItem().getId(),
ol.getItem().getName(),
ol.getItem().getPrice(),
ol.getCount(),
ol.getCountPrice(),
ol.getStore().getId(),
ol.getStore().getName()
ol.getItem().getId(),
ol.getItem().getName(),
ol.getItem().getPrice(),
ol.getCount(),
ol.getCountPrice(),
ol.getStore().getId(),
ol.getStore().getName()
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package hekireki.sanjijiksong.domain.order.dto;

public record PaymentRequest(String orderId, String amount, String paymentKey) {

}
177 changes: 103 additions & 74 deletions src/main/java/hekireki/sanjijiksong/domain/order/entity/Order.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@
import hekireki.sanjijiksong.domain.user.entity.User;
import hekireki.sanjijiksong.global.common.BaseTimeEntity;
import hekireki.sanjijiksong.global.common.exception.OrderException;
import jakarta.persistence.*;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import lombok.Setter;

@NoArgsConstructor
@AllArgsConstructor
Expand All @@ -20,74 +33,90 @@
@Table(name = "`ORDER`")
public class Order extends BaseTimeEntity {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderList> orderLists = new ArrayList<>();

@Enumerated(EnumType.STRING)
private OrderStatus orderStatus;

@Column(nullable = false)
private int stock; // 총 수량

@Column(nullable = false)
private int totalPrice; // 총 금액

// 주문 항목 추가
public void addOrderItem(OrderList item) {
this.orderLists.add(item);
this.stock += item.getCount();
this.totalPrice += item.getCountPrice();
}

// 총 주문 금액 재계산
public int calculateTotalAmount() {
return orderLists.stream()
.mapToInt(OrderList::calculateTotalPrice)
.sum();
}

// 총 주문 수량 재계산
public int calculateTotalQuantity() {
return orderLists.stream()
.mapToInt(OrderList::getCount)
.sum();
}

// 취소 가능 여부
public boolean isCancelable() {
return this.orderStatus == OrderStatus.ORDERED|| this.orderStatus == OrderStatus.PAID;
}

// 주문 취소 처리
public void cancel() {
if (!isCancelable()) {
throw new OrderException.OrderNotCancelableException();
}
this.orderStatus = OrderStatus.CANCELED;
}

// 수정 가능 여부
public boolean isUpdatable() {
return this.orderStatus == OrderStatus.ORDERED;
}

// 주문 수정
public void updateOrderSummary(int oldCount, int oldPrice, int newCount, int newPrice) {
this.stock = this.stock - oldCount + newCount;
this.totalPrice = this.totalPrice - oldPrice + newPrice;
}

public Order(User user, OrderStatus orderStatus) {
this.user = user;
this.orderStatus = orderStatus;
this.stock = 0;
this.totalPrice = 0;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderList> orderLists = new ArrayList<>();

@Enumerated(EnumType.STRING)
private OrderStatus orderStatus;

@Column(nullable = false)
private int stock; // 총 수량

@Column(nullable = false)
private int totalPrice; // 총 금액

@Builder.Default
private UUID orderId = UUID.randomUUID();

@Setter
private String tossPaymentKey;

public Order(User user, OrderStatus orderStatus) {
this.user = user;
this.orderStatus = orderStatus;
this.stock = 0;
this.totalPrice = 0;
this.orderId = UUID.randomUUID();
}

// 주문 항목 추가
public void addOrderItem(OrderList item) {
this.orderLists.add(item);
this.stock += item.getCount();
this.totalPrice += item.getCountPrice();
}

// 총 주문 금액 재계산
public int calculateTotalAmount() {
return orderLists.stream()
.mapToInt(OrderList::calculateTotalPrice)
.sum();
}

// 총 주문 수량 재계산
public int calculateTotalQuantity() {
return orderLists.stream()
.mapToInt(OrderList::getCount)
.sum();
}

// 취소 가능 여부
public boolean isCancelable() {
return this.orderStatus == OrderStatus.ORDERED || this.orderStatus == OrderStatus.PAID;
}

// 주문 취소 처리
public void cancel() {
if (!isCancelable()) {
throw new OrderException.OrderNotCancelableException();
}
this.orderStatus = OrderStatus.CANCELED;
}

// 수정 가능 여부
public boolean isUpdatable() {
return this.orderStatus == OrderStatus.ORDERED;
}

public void paid(String paymentKey) {
if (this.orderStatus == OrderStatus.PAID) {
throw new OrderException.OrderAlreadyPaidException();
}
this.orderStatus = OrderStatus.PAID;
this.tossPaymentKey = paymentKey;
}

// 주문 수정
public void updateOrderSummary(int oldCount, int oldPrice, int newCount, int newPrice) {
this.stock = this.stock - oldCount + newCount;
this.totalPrice = this.totalPrice - oldPrice + newPrice;
}
}
Loading