diff --git a/src/main/java/me/barion/capstoneprojectbarion/Entity/Menu.java b/src/main/java/me/barion/capstoneprojectbarion/Entity/Menu.java index d49180f..0af2d13 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/Entity/Menu.java +++ b/src/main/java/me/barion/capstoneprojectbarion/Entity/Menu.java @@ -14,7 +14,7 @@ public class Menu { private Long menuId; private int category; - private int orderId; +// private int orderId; @Column(length = 100, nullable = false) private String menuName; diff --git a/src/main/java/me/barion/capstoneprojectbarion/Entity/Order.java b/src/main/java/me/barion/capstoneprojectbarion/Entity/Order.java index 69be1f4..efcf077 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/Entity/Order.java +++ b/src/main/java/me/barion/capstoneprojectbarion/Entity/Order.java @@ -1,47 +1,35 @@ package me.barion.capstoneprojectbarion.Entity; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; -@Getter -@Setter @Entity -@Table(name = "orders") // SQL 예약어 충돌로 orders로 변경 +@Table(name = "orders") +@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder public class Order { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "order_id") private Integer orderId; - // Store와 N:1 관계 @ManyToOne(fetch = FetchType.LAZY) - @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) - @JoinColumn(name = "store_id") + @JoinColumn(name = "store_id", nullable = false) private Store store; - - @Column(name = "order_date") + @Column(name = "order_date", nullable = false) private LocalDateTime orderDate; - @Column(name = "total_amount") + @Column(name = "total_amount", nullable = false) private Integer totalAmount; - @Column(name = "order_status", length = 100) + @Column(name = "order_status", length = 100, nullable = false) private String orderStatus; - public Order() { - } - - public Order(Store store, LocalDateTime orderDate, Integer totalAmount, String orderStatus) { - this.store = store; - this.orderDate = orderDate; - this.totalAmount = totalAmount; - this.orderStatus = orderStatus; - } -} - + @Builder.Default + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) + private List items = new ArrayList<>(); +} \ No newline at end of file diff --git a/src/main/java/me/barion/capstoneprojectbarion/Entity/OrderItem.java b/src/main/java/me/barion/capstoneprojectbarion/Entity/OrderItem.java new file mode 100644 index 0000000..f60c456 --- /dev/null +++ b/src/main/java/me/barion/capstoneprojectbarion/Entity/OrderItem.java @@ -0,0 +1,36 @@ +package me.barion.capstoneprojectbarion.Entity; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Table(name = "order_item") +@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder +public class OrderItem { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long orderItemId; + + @JsonBackReference + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "order_id", nullable = false) + private Order order; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "menu_id", nullable = false) + private Menu menu; + + @Column(nullable = false) + private Integer quantity; + + @Column(nullable = false) + private Integer unitPrice; + + @PrePersist + public void applyMenuPrice() { + if (this.unitPrice == null && this.menu != null) { + this.unitPrice = menu.getPrice(); + } + } +} \ No newline at end of file diff --git a/src/main/java/me/barion/capstoneprojectbarion/controller/MenuController.java b/src/main/java/me/barion/capstoneprojectbarion/controller/MenuController.java index 7d74d09..c0a0848 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/controller/MenuController.java +++ b/src/main/java/me/barion/capstoneprojectbarion/controller/MenuController.java @@ -17,7 +17,7 @@ import java.util.List; @RestController -@RequestMapping("/menus") +@RequestMapping("/api/menus") public class MenuController { private final MenuService menuService; private final MenuOptionService menuOptionService; diff --git a/src/main/java/me/barion/capstoneprojectbarion/controller/OrderController.java b/src/main/java/me/barion/capstoneprojectbarion/controller/OrderController.java index 620e2a8..8f4ef90 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/controller/OrderController.java +++ b/src/main/java/me/barion/capstoneprojectbarion/controller/OrderController.java @@ -1,73 +1,52 @@ package me.barion.capstoneprojectbarion.controller; -import io.swagger.v3.oas.annotations.Operation; -import jakarta.persistence.EntityNotFoundException; import me.barion.capstoneprojectbarion.dto.OrderDto; -import me.barion.capstoneprojectbarion.Entity.Order; import me.barion.capstoneprojectbarion.service.OrderService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.net.URI; import java.util.List; -import java.util.NoSuchElementException; @RestController -@RequestMapping("/orders") +@RequestMapping("/api/orders") public class OrderController { - private final OrderService orderService; - @Autowired public OrderController(OrderService orderService) { this.orderService = orderService; } - @Operation(summary = "주문 생성", description = "새로운 주문을 생성합니다.") @PostMapping - public ResponseEntity createOrder(@RequestBody OrderDto orderDto) { - Order createdOrder = orderService.createOrder(orderDto); - return ResponseEntity.ok(createdOrder); + public ResponseEntity createOrder(@RequestBody OrderDto dto) { + OrderDto saved = orderService.createOrder(dto); + URI location = URI.create("/orders/" + saved.getOrderId()); + return ResponseEntity + .created(location) // 상태코드 201 + .body(saved); } - @Operation(summary = "주문 조회", description = "주문 정보를 단건 조회합니다.") @GetMapping("/{orderId}") - public ResponseEntity getOrder(@PathVariable Integer orderId) { - try { - Order order = orderService.getOrder(orderId); - return ResponseEntity.ok(order); - } catch (EntityNotFoundException | NoSuchElementException e) { - return ResponseEntity.notFound().build(); - } + public ResponseEntity getOrder(@PathVariable Integer orderId) { + return ResponseEntity.ok(orderService.getOrder(orderId)); } - @Operation(summary = "매장의 모든 주문 조회", description = "storeId로 해당 매장의 모든 주문을 조회합니다.") @GetMapping("/store/{storeId}") - public ResponseEntity> getOrdersByStoreId(@PathVariable Integer storeId) { - List orders = orderService.getOrdersByStoreId(storeId); - return ResponseEntity.ok(orders); + public ResponseEntity> getByStore(@PathVariable Integer storeId) { + return ResponseEntity.ok(orderService.getOrdersByStoreId(storeId)); } - @Operation(summary = "주문 수정", description = "주문 정보를 수정합니다.") @PutMapping("/{orderId}") - public ResponseEntity updateOrder(@PathVariable Integer orderId, - @RequestBody OrderDto orderDto) { - try { - Order updatedOrder = orderService.updateOrder(orderId, orderDto); - return ResponseEntity.ok(updatedOrder); - } catch (EntityNotFoundException e) { - return ResponseEntity.notFound().build(); - } + public ResponseEntity updateOrder( + @PathVariable Integer orderId, + @RequestBody OrderDto dto) { + return ResponseEntity.ok(orderService.updateOrder(orderId, dto)); } - @Operation(summary = "주문 삭제", description = "주문 정보를 삭제합니다.") @DeleteMapping("/{orderId}") public ResponseEntity deleteOrder(@PathVariable Integer orderId) { - try { - orderService.deleteOrder(orderId); - return ResponseEntity.noContent().build(); - } catch (EntityNotFoundException e) { - return ResponseEntity.notFound().build(); - } + orderService.deleteOrder(orderId); + return ResponseEntity.noContent().build(); } } + diff --git a/src/main/java/me/barion/capstoneprojectbarion/dto/MenuRequestDto.java b/src/main/java/me/barion/capstoneprojectbarion/dto/MenuRequestDto.java index ef1d037..fd601e3 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/dto/MenuRequestDto.java +++ b/src/main/java/me/barion/capstoneprojectbarion/dto/MenuRequestDto.java @@ -6,7 +6,7 @@ @NoArgsConstructor public class MenuRequestDto { private int category; - private int orderId; +// private int orderId; private String menuName; private int price; private int cost; diff --git a/src/main/java/me/barion/capstoneprojectbarion/dto/MenuResponseDto.java b/src/main/java/me/barion/capstoneprojectbarion/dto/MenuResponseDto.java index 10a980e..35fa41f 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/dto/MenuResponseDto.java +++ b/src/main/java/me/barion/capstoneprojectbarion/dto/MenuResponseDto.java @@ -14,7 +14,7 @@ public class MenuResponseDto { private Long menuId; private int category; - private int orderId; +// private int orderId; private String menuName; private int price; private int cost; @@ -32,7 +32,7 @@ public static MenuResponseDto fromEntity(Menu menu) { return MenuResponseDto.builder() .menuId(menu.getMenuId()) .category(menu.getCategory()) - .orderId(menu.getOrderId()) +// .orderId(menu.getOrderId()) .menuName(menu.getMenuName()) .price(menu.getPrice()) .cost(menu.getCost()) diff --git a/src/main/java/me/barion/capstoneprojectbarion/dto/OrderDto.java b/src/main/java/me/barion/capstoneprojectbarion/dto/OrderDto.java index 155b592..43e537b 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/dto/OrderDto.java +++ b/src/main/java/me/barion/capstoneprojectbarion/dto/OrderDto.java @@ -1,15 +1,16 @@ package me.barion.capstoneprojectbarion.dto; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import java.time.LocalDateTime; +import java.util.List; -@Getter -@Setter +@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder public class OrderDto { + private Integer orderId; private Integer storeId; private LocalDateTime orderDate; - private Integer totalAmount; private String orderStatus; + private List items; + private Integer totalAmount; } diff --git a/src/main/java/me/barion/capstoneprojectbarion/dto/OrderItemDto.java b/src/main/java/me/barion/capstoneprojectbarion/dto/OrderItemDto.java new file mode 100644 index 0000000..72fa034 --- /dev/null +++ b/src/main/java/me/barion/capstoneprojectbarion/dto/OrderItemDto.java @@ -0,0 +1,16 @@ +package me.barion.capstoneprojectbarion.dto; + + +import lombok.*; + +@Getter @Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class OrderItemDto { + private Long menuId; + private String menuName; // 응답 시 포함 + private Integer quantity; + private Integer unitPrice; + private Integer totalPrice; // ★ 추가 +} \ No newline at end of file diff --git a/src/main/java/me/barion/capstoneprojectbarion/repository/OrderItemRepository.java b/src/main/java/me/barion/capstoneprojectbarion/repository/OrderItemRepository.java new file mode 100644 index 0000000..dbf06af --- /dev/null +++ b/src/main/java/me/barion/capstoneprojectbarion/repository/OrderItemRepository.java @@ -0,0 +1,7 @@ +package me.barion.capstoneprojectbarion.repository; + +import me.barion.capstoneprojectbarion.Entity.OrderItem; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrderItemRepository extends JpaRepository { +} diff --git a/src/main/java/me/barion/capstoneprojectbarion/repository/OrderRepository.java b/src/main/java/me/barion/capstoneprojectbarion/repository/OrderRepository.java index 443e7ed..e60fb7e 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/repository/OrderRepository.java +++ b/src/main/java/me/barion/capstoneprojectbarion/repository/OrderRepository.java @@ -9,7 +9,6 @@ public interface OrderRepository extends JpaRepository { - // 기존 메서드들 List findByStoreStoreId(Integer storeId); @Query("SELECT COALESCE(SUM(o.totalAmount), 0) FROM Order o") diff --git a/src/main/java/me/barion/capstoneprojectbarion/service/MenuService.java b/src/main/java/me/barion/capstoneprojectbarion/service/MenuService.java index 609ee19..ac77e8e 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/service/MenuService.java +++ b/src/main/java/me/barion/capstoneprojectbarion/service/MenuService.java @@ -28,7 +28,7 @@ public MenuResponseDto createMenu(MenuRequestDto dto) throws IOException { Menu menu = new Menu(); menu.setMenuName(dto.getMenuName()); menu.setCategory(dto.getCategory()); - menu.setOrderId(dto.getOrderId()); +// menu.setOrderId(dto.getOrderId()); menu.setPrice(dto.getPrice()); menu.setCost(dto.getCost()); menu.setMenuPresent(dto.getMenuPresent()); @@ -69,7 +69,7 @@ public MenuResponseDto updateMenu(Long menuId, MenuRequestDto dto) throws IOExce menu.setMenuName(dto.getMenuName()); menu.setCategory(dto.getCategory()); - menu.setOrderId(dto.getOrderId()); +// menu.setOrderId(dto.getOrderId()); menu.setPrice(dto.getPrice()); menu.setCost(dto.getCost()); menu.setMenuPresent(dto.getMenuPresent()); diff --git a/src/main/java/me/barion/capstoneprojectbarion/service/OrderService.java b/src/main/java/me/barion/capstoneprojectbarion/service/OrderService.java index 8723ee7..f4a23c4 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/service/OrderService.java +++ b/src/main/java/me/barion/capstoneprojectbarion/service/OrderService.java @@ -2,100 +2,120 @@ import jakarta.persistence.EntityNotFoundException; import me.barion.capstoneprojectbarion.dto.OrderDto; +import me.barion.capstoneprojectbarion.dto.OrderItemDto; +import me.barion.capstoneprojectbarion.Entity.Menu; import me.barion.capstoneprojectbarion.Entity.Order; +import me.barion.capstoneprojectbarion.Entity.OrderItem; import me.barion.capstoneprojectbarion.Entity.Store; +import me.barion.capstoneprojectbarion.repository.MenuRepository; import me.barion.capstoneprojectbarion.repository.OrderRepository; import me.barion.capstoneprojectbarion.repository.StoreRepository; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.stream.Collectors; @Service public class OrderService { - - private final OrderRepository orderRepository; - private final StoreRepository storeRepository; - - @Autowired - public OrderService(OrderRepository orderRepository, StoreRepository storeRepository) { - this.orderRepository = orderRepository; - this.storeRepository = storeRepository; + private final OrderRepository orderRepo; + private final StoreRepository storeRepo; + private final MenuRepository menuRepo; + + public OrderService(OrderRepository orderRepo, StoreRepository storeRepo, MenuRepository menuRepo) { + this.orderRepo = orderRepo; + this.storeRepo = storeRepo; + this.menuRepo = menuRepo; } - /** - * 주문 생성 - */ @Transactional - public Order createOrder(OrderDto orderDto) { - // storeId를 통해 Store 엔티티를 가져옴 - Store store = storeRepository.findById(orderDto.getStoreId()) - .orElseThrow(() -> new EntityNotFoundException("Store not found with id: " + orderDto.getStoreId())); - - Order order = new Order(); - order.setStore(store); - order.setOrderDate(orderDto.getOrderDate()); - order.setTotalAmount(orderDto.getTotalAmount()); - order.setOrderStatus(orderDto.getOrderStatus()); - - return orderRepository.save(order); + public OrderDto createOrder(OrderDto dto) { + Store store = storeRepo.findById(dto.getStoreId()) + .orElseThrow(() -> new EntityNotFoundException("Store not found: " + dto.getStoreId())); + + Order order = Order.builder() + .store(store) + .orderDate(dto.getOrderDate()) + .orderStatus(dto.getOrderStatus()) + .build(); + + int total = 0; + for (OrderItemDto itemDto : dto.getItems()) { + Menu menu = menuRepo.findById(itemDto.getMenuId()) + .orElseThrow(() -> new EntityNotFoundException("Menu not found: " + itemDto.getMenuId())); + + OrderItem item = OrderItem.builder() + .order(order) + .menu(menu) + .quantity(itemDto.getQuantity()) + .unitPrice(menu.getPrice()) + .build(); + + order.getItems().add(item); + total += item.getUnitPrice() * item.getQuantity(); + } + order.setTotalAmount(total); + Order saved = orderRepo.save(order); + + // 엔티티 → DTO 변환 + OrderDto result = toDto(saved); + return result; } - /** - * 주문 조회 (단건) - */ @Transactional(readOnly = true) - public Order getOrder(Integer orderId) { - return orderRepository.findById(orderId) - .orElseThrow(() -> new EntityNotFoundException("Order not found with id: " + orderId)); + public OrderDto getOrder(Integer id) { + Order order = orderRepo.findById(id) + .orElseThrow(() -> new EntityNotFoundException("Order not found: " + id)); + return toDto(order); } - - @Transactional(readOnly = true) - public List getOrdersByStoreId(Integer storeId) { - return (List) orderRepository.findByStoreStoreId(storeId); + public List getOrdersByStoreId(Integer storeId) { + return orderRepo.findByStoreStoreId(storeId).stream() + .map(this::toDto) + .collect(Collectors.toList()); } - - /** - * 주문 수정 - */ @Transactional - public Order updateOrder(Integer orderId, OrderDto orderDto) { - // 기존 주문 정보 조회 - Order order = orderRepository.findById(orderId) - .orElseThrow(() -> new EntityNotFoundException("Order not found with id: " + orderId)); - - // storeId가 변경될 수 있다면, Store도 다시 매핑 - if (orderDto.getStoreId() != null) { - Store store = storeRepository.findById(orderDto.getStoreId()) - .orElseThrow(() -> new EntityNotFoundException("Store not found with id: " + orderDto.getStoreId())); - order.setStore(store); - } + public OrderDto updateOrder(Integer id, OrderDto dto) { + Order order = orderRepo.findById(id) + .orElseThrow(() -> new EntityNotFoundException("Order not found: " + id)); - if (orderDto.getOrderDate() != null) { - order.setOrderDate(orderDto.getOrderDate()); - } - if (orderDto.getTotalAmount() != null) { - order.setTotalAmount(orderDto.getTotalAmount()); - } - if (orderDto.getOrderStatus() != null) { - order.setOrderStatus(orderDto.getOrderStatus()); - } + if (dto.getOrderDate() != null) order.setOrderDate(dto.getOrderDate()); + if (dto.getOrderStatus() != null) order.setOrderStatus(dto.getOrderStatus()); + // items 수정 로직 생략 (필요시 추가) - return orderRepository.save(order); + Order updated = orderRepo.save(order); + return toDto(updated); } - /** - * 주문 삭제 - */ @Transactional - public void deleteOrder(Integer orderId) { - if (!orderRepository.existsById(orderId)) { - throw new EntityNotFoundException("Order not found with id: " + orderId); + public void deleteOrder(Integer id) { + if (!orderRepo.existsById(id)) { + throw new EntityNotFoundException("Order not found: " + id); } - orderRepository.deleteById(orderId); + orderRepo.deleteById(id); + } + + private OrderDto toDto(Order order) { + List items = order.getItems().stream() + .map(i -> OrderItemDto.builder() + .menuId(i.getMenu().getMenuId()) + .menuName(i.getMenu().getMenuName()) + .quantity(i.getQuantity()) + .unitPrice(i.getUnitPrice()) + // 아래에서 메뉴별 총합 가격 계산 + .totalPrice(i.getUnitPrice() * i.getQuantity()) + .build()) + .collect(Collectors.toList()); + + return OrderDto.builder() + .orderId(order.getOrderId()) + .storeId(order.getStore().getStoreId()) + .orderDate(order.getOrderDate()) + .orderStatus(order.getOrderStatus()) + .items(items) + .totalAmount(order.getTotalAmount()) + .build(); } } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 7a4bafe..d678eef 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -8,4 +8,4 @@ DELETE FROM store WHERE store_id = 0; -- 3. 새로운 store 데이터 삽입 INSERT INTO store (store_id, store_name, store_type, password, onboarding_status) -VALUES (0, '가게', '업종', 'qwer1234', true); +VALUES (0, '가게', '업종', '1234', true);