diff --git a/.gitignore b/.gitignore index b14e901..55950e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.DS_Store + .*env .env* HELP.md diff --git a/src/main/java/kr/co/knuserver/application/pubMenu/PubMenuQueryService.java b/src/main/java/kr/co/knuserver/application/pubMenu/PubMenuQueryService.java index e2e7961..52e9794 100644 --- a/src/main/java/kr/co/knuserver/application/pubMenu/PubMenuQueryService.java +++ b/src/main/java/kr/co/knuserver/application/pubMenu/PubMenuQueryService.java @@ -1,5 +1,6 @@ package kr.co.knuserver.application.pubMenu; +import java.util.List; import kr.co.knuserver.domain.pubMenu.entity.PubMenu; import kr.co.knuserver.domain.pubMenu.repository.PubMenuRepository; import kr.co.knuserver.global.exception.BusinessErrorCode; @@ -20,4 +21,8 @@ public PubMenu findPubMenuById(Long id) { return pubMenuRepository.findById(id) .orElseThrow(() -> new BusinessException(BusinessErrorCode.PUB_MENU_NOT_FOUND)); } + + public List findAllPubMenuByIds(List ids) { + return pubMenuRepository.findAllById(ids); + } } diff --git a/src/main/java/kr/co/knuserver/application/pubOrder/PubOrderCommandService.java b/src/main/java/kr/co/knuserver/application/pubOrder/PubOrderCommandService.java new file mode 100644 index 0000000..b6886c4 --- /dev/null +++ b/src/main/java/kr/co/knuserver/application/pubOrder/PubOrderCommandService.java @@ -0,0 +1,67 @@ +package kr.co.knuserver.application.pubOrder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import kr.co.knuserver.application.pubMenu.PubMenuQueryService; +import kr.co.knuserver.application.pubTableSession.PubTableSessionQueryService; +import kr.co.knuserver.domain.pubMenu.entity.PubMenu; +import kr.co.knuserver.domain.pubOrder.entity.PubOrder; +import kr.co.knuserver.domain.pubOrder.repository.PubOrderRepository; +import kr.co.knuserver.domain.pubTableSession.entity.PubTableSession; +import kr.co.knuserver.global.exception.BusinessErrorCode; +import kr.co.knuserver.global.exception.BusinessException; +import kr.co.knuserver.presentation.pubOrder.dto.OrderMenus; +import kr.co.knuserver.presentation.pubOrder.dto.OrderedMenus; +import kr.co.knuserver.presentation.pubOrder.dto.PubOrderRequestDto; +import kr.co.knuserver.presentation.pubOrder.dto.PubOrderResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class PubOrderCommandService { + + private final PubOrderRepository pubOrderRepository; + private final PubOrderQueryService pubOrderQueryService; + private final PubTableSessionQueryService pubTableSessionQueryService; + private final PubMenuQueryService pubMenuQueryService; + + public PubOrderResponseDto createOrder(PubOrderRequestDto request) { + PubTableSession pubTableSession = pubTableSessionQueryService.getPubTableSessionById(request.pubTableSessionId()); + + List menuIds = request.orderMenus().stream() + .map(OrderMenus::menuId) + .distinct() + .toList(); + List foundMenus = pubMenuQueryService.findAllPubMenuByIds(menuIds); + + if (foundMenus.size() != menuIds.size()) { + throw new BusinessException(BusinessErrorCode.PUB_MENU_NOT_FOUND); + } + + Map pubMenuMap = foundMenus.stream() + .collect(Collectors.toMap(PubMenu::getId, Function.identity())); + + List pubOrders = new ArrayList<>(); + for (OrderMenus orderMenus : request.orderMenus()) { + pubOrders.add(PubOrder.createPubOrder(pubTableSession.getId(), orderMenus.menuId(), orderMenus.quantity())); + } + List savedPubOrders = pubOrderRepository.saveAll(pubOrders); + + List orderedMenus = savedPubOrders.stream().map((pubOrder -> { + PubMenu pubMenu = pubMenuMap.get(pubOrder.getPubMenuId()); + return OrderedMenus.fromEntity(pubOrder, pubMenu); + })).toList(); + return PubOrderResponseDto.fromEntity(request.pubTableSessionId(), orderedMenus); + } + + public void deleteOrder(Long pubOrderId) { + PubOrder pubOrder = pubOrderQueryService.findByOrderId(pubOrderId); + pubOrderRepository.delete(pubOrder); + } +} diff --git a/src/main/java/kr/co/knuserver/application/pubOrder/PubOrderQueryService.java b/src/main/java/kr/co/knuserver/application/pubOrder/PubOrderQueryService.java new file mode 100644 index 0000000..858888c --- /dev/null +++ b/src/main/java/kr/co/knuserver/application/pubOrder/PubOrderQueryService.java @@ -0,0 +1,37 @@ +package kr.co.knuserver.application.pubOrder; + +import java.util.List; +import kr.co.knuserver.application.pubMenu.PubMenuQueryService; +import kr.co.knuserver.domain.pubMenu.entity.PubMenu; +import kr.co.knuserver.domain.pubOrder.entity.PubOrder; +import kr.co.knuserver.domain.pubOrder.repository.PubOrderRepository; +import kr.co.knuserver.global.exception.BusinessErrorCode; +import kr.co.knuserver.global.exception.BusinessException; +import kr.co.knuserver.presentation.pubOrder.dto.OrderedMenus; +import kr.co.knuserver.presentation.pubOrder.dto.PubOrderResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true, propagation = Propagation.SUPPORTS) +public class PubOrderQueryService { + + private final PubOrderRepository pubOrderRepository; + private final PubMenuQueryService pubMenuQueryService; + + public PubOrder findByOrderId(Long orderId) { + return pubOrderRepository.findById(orderId).orElseThrow(() -> new BusinessException(BusinessErrorCode.PUB_ORDER_NOT_FOUND)); + } + + public PubOrderResponseDto getAllByPubTableSessionId(Long pubTableSessionId) { + List pubOrderList = pubOrderRepository.findAllByPubTableSessionId(pubTableSessionId); + List orderedMenus = pubOrderList.stream().map((pubOrder -> { + PubMenu pubMenu = pubMenuQueryService.findPubMenuById(pubOrder.getPubMenuId()); + return OrderedMenus.fromEntity(pubOrder, pubMenu); + })).toList(); + return PubOrderResponseDto.fromEntity(pubTableSessionId, orderedMenus); + } +} diff --git a/src/main/java/kr/co/knuserver/domain/pubTableSession/entity/PubOrder.java b/src/main/java/kr/co/knuserver/domain/pubOrder/entity/PubOrder.java similarity index 65% rename from src/main/java/kr/co/knuserver/domain/pubTableSession/entity/PubOrder.java rename to src/main/java/kr/co/knuserver/domain/pubOrder/entity/PubOrder.java index 0d27d0d..532f270 100644 --- a/src/main/java/kr/co/knuserver/domain/pubTableSession/entity/PubOrder.java +++ b/src/main/java/kr/co/knuserver/domain/pubOrder/entity/PubOrder.java @@ -1,4 +1,4 @@ -package kr.co.knuserver.domain.pubTableSession.entity; +package kr.co.knuserver.domain.pubOrder.entity; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -6,6 +6,8 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; +import kr.co.knuserver.global.exception.BusinessErrorCode; +import kr.co.knuserver.global.exception.BusinessException; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -21,7 +23,7 @@ public class PubOrder { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "pub_table_id") + @Column(name = "pub_order_id") private Long id; @Column(name = "pub_table_session_id", nullable = false) @@ -30,10 +32,18 @@ public class PubOrder { @Column(name = "pub_menu_id", nullable = false) private Long pubMenuId; - public static PubOrder createPubOrder(Long pubSessionId, Long pubMenuId) { + @Column(name = "quantity", nullable = false) + private Integer quantity; + + public static PubOrder createPubOrder(Long pubSessionId, Long pubMenuId, Integer quantity) { + if (quantity == null || quantity <= 0) { + throw new BusinessException("주문 수량은 양수만 입력 가능합니다.", BusinessErrorCode.INVALID_INPUT_VALUE); + } + return PubOrder.builder() .pubTableSessionId(pubSessionId) .pubMenuId(pubMenuId) + .quantity(quantity) .build(); } } diff --git a/src/main/java/kr/co/knuserver/domain/pubOrder/repository/PubOrderRepository.java b/src/main/java/kr/co/knuserver/domain/pubOrder/repository/PubOrderRepository.java new file mode 100644 index 0000000..e3c0882 --- /dev/null +++ b/src/main/java/kr/co/knuserver/domain/pubOrder/repository/PubOrderRepository.java @@ -0,0 +1,9 @@ +package kr.co.knuserver.domain.pubOrder.repository; + +import java.util.List; +import kr.co.knuserver.domain.pubOrder.entity.PubOrder; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PubOrderRepository extends JpaRepository { + List findAllByPubTableSessionId(Long pubTableSessionId); +} diff --git a/src/main/java/kr/co/knuserver/global/exception/BusinessErrorCode.java b/src/main/java/kr/co/knuserver/global/exception/BusinessErrorCode.java index 288bc54..e7f52b1 100644 --- a/src/main/java/kr/co/knuserver/global/exception/BusinessErrorCode.java +++ b/src/main/java/kr/co/knuserver/global/exception/BusinessErrorCode.java @@ -54,6 +54,7 @@ public enum BusinessErrorCode implements ErrorCode { */ PUB_BOOTH_NOT_FOUND(HttpStatus.NOT_FOUND, "C301", "해당 주점을 찾을 수 없습니다."), PUB_MENU_NOT_FOUND(HttpStatus.NOT_FOUND, "C302", "해당 주점 메뉴를 찾을 수 없습니다."), + PUB_ORDER_NOT_FOUND(HttpStatus.NOT_FOUND, "C206", "해당 주문을 찾을 수 없습니다."), /* * 405 METHOD_NOT_ALLOWED: 허용되지 않은 Request Method 호출 diff --git a/src/main/java/kr/co/knuserver/presentation/pubOrder/controller/PubOrderCommandController.java b/src/main/java/kr/co/knuserver/presentation/pubOrder/controller/PubOrderCommandController.java new file mode 100644 index 0000000..b51a518 --- /dev/null +++ b/src/main/java/kr/co/knuserver/presentation/pubOrder/controller/PubOrderCommandController.java @@ -0,0 +1,33 @@ +package kr.co.knuserver.presentation.pubOrder.controller; + +import jakarta.validation.Valid; +import kr.co.knuserver.application.pubOrder.PubOrderCommandService; +import kr.co.knuserver.presentation.pubOrder.dto.PubOrderRequestDto; +import kr.co.knuserver.presentation.pubOrder.dto.PubOrderResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +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.RestController; + +@RestController +@RequestMapping("/admin/v1/pubOrder") +@RequiredArgsConstructor +public class PubOrderCommandController { + + private final PubOrderCommandService pubOrderCommandService; + + @PostMapping + public ResponseEntity createOrder(@Valid @RequestBody PubOrderRequestDto request) { + return ResponseEntity.ok().body(pubOrderCommandService.createOrder(request)); + } + + @DeleteMapping("/{pubOrderId}") + public ResponseEntity deleteOrder(@PathVariable("pubOrderId") Long pubOrderId) { + pubOrderCommandService.deleteOrder(pubOrderId); + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/kr/co/knuserver/presentation/pubOrder/controller/PubOrderQueryController.java b/src/main/java/kr/co/knuserver/presentation/pubOrder/controller/PubOrderQueryController.java new file mode 100644 index 0000000..d272889 --- /dev/null +++ b/src/main/java/kr/co/knuserver/presentation/pubOrder/controller/PubOrderQueryController.java @@ -0,0 +1,23 @@ +package kr.co.knuserver.presentation.pubOrder.controller; + +import kr.co.knuserver.application.pubOrder.PubOrderQueryService; +import kr.co.knuserver.presentation.pubOrder.dto.PubOrderResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/admin/v1/pubOrder") +@RequiredArgsConstructor +public class PubOrderQueryController { + + private final PubOrderQueryService pubOrderQueryService; + + @GetMapping("/{pubTableSessionId}") + public ResponseEntity getAllByPubTableSessionId(@PathVariable("pubTableSessionId") Long pubTableSessionId) { + return ResponseEntity.ok(pubOrderQueryService.getAllByPubTableSessionId(pubTableSessionId)); + } +} diff --git a/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/OrderMenus.java b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/OrderMenus.java new file mode 100644 index 0000000..1f3796f --- /dev/null +++ b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/OrderMenus.java @@ -0,0 +1,9 @@ +package kr.co.knuserver.presentation.pubOrder.dto; + +import jakarta.validation.constraints.NotNull; + +public record OrderMenus( + @NotNull Long menuId, + @NotNull Integer quantity +) { +} diff --git a/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/OrderedMenus.java b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/OrderedMenus.java new file mode 100644 index 0000000..dfc0642 --- /dev/null +++ b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/OrderedMenus.java @@ -0,0 +1,24 @@ +package kr.co.knuserver.presentation.pubOrder.dto; + +import kr.co.knuserver.domain.pubMenu.entity.PubMenu; +import kr.co.knuserver.domain.pubOrder.entity.PubOrder; +import lombok.Builder; + +@Builder +public record OrderedMenus( + Long orderId, + Long menuId, + String name, + int price, + Integer quantity +) { + public static OrderedMenus fromEntity(PubOrder pubOrder, PubMenu pubMenu) { + return OrderedMenus.builder() + .orderId(pubOrder.getId()) + .menuId(pubMenu.getId()) + .name(pubMenu.getName()) + .price(pubMenu.getPrice()) + .quantity(pubOrder.getQuantity()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/PubOrderRequestDto.java b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/PubOrderRequestDto.java new file mode 100644 index 0000000..1a4105b --- /dev/null +++ b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/PubOrderRequestDto.java @@ -0,0 +1,12 @@ +package kr.co.knuserver.presentation.pubOrder.dto; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import java.util.List; + +public record PubOrderRequestDto( + @NotNull Long pubTableSessionId, + @NotEmpty List<@Valid OrderMenus> orderMenus +) { +} diff --git a/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/PubOrderResponseDto.java b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/PubOrderResponseDto.java new file mode 100644 index 0000000..6084b7a --- /dev/null +++ b/src/main/java/kr/co/knuserver/presentation/pubOrder/dto/PubOrderResponseDto.java @@ -0,0 +1,19 @@ +package kr.co.knuserver.presentation.pubOrder.dto; + +import jakarta.validation.constraints.NotNull; +import java.util.List; +import kr.co.knuserver.domain.pubOrder.entity.PubOrder; +import lombok.Builder; + +@Builder +public record PubOrderResponseDto( + @NotNull Long pubTableSessionId, + @NotNull List orderedMenus +) { + public static PubOrderResponseDto fromEntity(Long pubTableSessionId, List orderedMenus) { + return PubOrderResponseDto.builder() + .pubTableSessionId(pubTableSessionId) + .orderedMenus(orderedMenus) + .build(); + } +}