From aa31b61202ef587cf35a9e755a9c6cf056905654 Mon Sep 17 00:00:00 2001 From: hwanwoo Date: Mon, 25 Sep 2023 22:59:53 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feature(order):=20step2=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81(menuProductPrice=20=EC=98=81?= =?UTF-8?q?=EC=86=8D=ED=99=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../menus/tobe/domain/menu/MenuProduct.java | 10 ++-- .../tobe/domain/menu/MenuProductPrice.java | 46 +++++++++++++++++++ src/test/java/kitchenpos/Fixtures.java | 3 +- 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProductPrice.java diff --git a/src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProduct.java b/src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProduct.java index bfc94e3d6..c67b14985 100644 --- a/src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProduct.java +++ b/src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProduct.java @@ -30,20 +30,20 @@ public class MenuProduct { @Embedded private MenuProductQuantity quantity; - @Transient - private BigDecimal menuProductPrice; + @Embedded + private MenuProductPrice menuProductPrice; protected MenuProduct() { } - public MenuProduct(UUID productId, MenuProductQuantity quantity, BigDecimal menuProductPrice) { + public MenuProduct(UUID productId, MenuProductQuantity quantity, MenuProductPrice menuProductPrice) { this.productId = productId; this.quantity = quantity; this.menuProductPrice = menuProductPrice; } public static MenuProduct of(UUID productId, MenuProductQuantity quantity, ProductClient productClient) { - return new MenuProduct(productId, quantity, productClient.getProductPrice(productId)); + return new MenuProduct(productId, quantity, new MenuProductPrice(productClient.getProductPrice(productId))); } public Long getSeq() { @@ -59,6 +59,6 @@ public UUID getProductId() { } public BigDecimal getMenuProductPrice() { - return menuProductPrice; + return menuProductPrice.getMenuProductPrice(); } } diff --git a/src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProductPrice.java b/src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProductPrice.java new file mode 100644 index 000000000..abae9dde4 --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/menu/MenuProductPrice.java @@ -0,0 +1,46 @@ +package kitchenpos.menus.tobe.domain.menu; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.math.BigDecimal; +import java.util.Objects; + +@Embeddable +public class MenuProductPrice { + @Column(name = "price", nullable = false) + private BigDecimal menuProductPrice; + + protected MenuProductPrice() { + } + + public MenuProductPrice(BigDecimal menuProductPrice) { + validateMenuProductPrice(menuProductPrice); + this.menuProductPrice = menuProductPrice; + } + + private void validateMenuProductPrice(BigDecimal menuProductPrice) { + if (Objects.isNull(menuProductPrice)) { + throw new IllegalArgumentException("메뉴 상풍 가격은 필수로 존재해야 합니다."); + } + if (menuProductPrice.compareTo(BigDecimal.ZERO) < 0) { + throw new IllegalArgumentException("메뉴 상품 가격은 0원 이상이어야 합니다."); + } + } + + public BigDecimal getMenuProductPrice() { + return menuProductPrice; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MenuProductPrice that = (MenuProductPrice) o; + return Objects.equals(menuProductPrice, that.menuProductPrice); + } + + @Override + public int hashCode() { + return Objects.hash(menuProductPrice); + } +} diff --git a/src/test/java/kitchenpos/Fixtures.java b/src/test/java/kitchenpos/Fixtures.java index 3aa74b979..baf728be4 100644 --- a/src/test/java/kitchenpos/Fixtures.java +++ b/src/test/java/kitchenpos/Fixtures.java @@ -5,6 +5,7 @@ import kitchenpos.menus.tobe.domain.menu.Menu; import kitchenpos.menus.tobe.domain.menu.MenuName; import kitchenpos.menus.tobe.domain.menu.MenuPrice; +import kitchenpos.menus.tobe.domain.menu.MenuProductPrice; import kitchenpos.menus.tobe.domain.menu.MenuProductQuantity; import kitchenpos.menus.tobe.domain.menu.MenuProducts; import kitchenpos.menus.tobe.domain.menu.ProductClient; @@ -57,7 +58,7 @@ public static MenuProduct menuProduct() { } public static MenuProduct menuProduct(final Product product, final long quantity) { - final MenuProduct menuProduct = new MenuProduct(product.getId(), new MenuProductQuantity(quantity), product.getPrice()); + final MenuProduct menuProduct = new MenuProduct(product.getId(), new MenuProductQuantity(quantity), new MenuProductPrice(product.getPrice())); return menuProduct; } From ce277ce16624082183d771bd27c3e8a5c160cfa7 Mon Sep 17 00:00:00 2001 From: yuhwanwoo <6514687@naver.com> Date: Thu, 28 Sep 2023 20:27:03 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feature(order):=20=EB=B0=B0=EB=8B=AC=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deliveryorders/{infra => domain}/KitchenridersClient.java | 0 src/main/java/kitchenpos/takeoutorders/empty.txt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/main/java/kitchenpos/deliveryorders/{infra => domain}/KitchenridersClient.java (100%) delete mode 100644 src/main/java/kitchenpos/takeoutorders/empty.txt diff --git a/src/main/java/kitchenpos/deliveryorders/infra/KitchenridersClient.java b/src/main/java/kitchenpos/deliveryorders/domain/KitchenridersClient.java similarity index 100% rename from src/main/java/kitchenpos/deliveryorders/infra/KitchenridersClient.java rename to src/main/java/kitchenpos/deliveryorders/domain/KitchenridersClient.java diff --git a/src/main/java/kitchenpos/takeoutorders/empty.txt b/src/main/java/kitchenpos/takeoutorders/empty.txt deleted file mode 100644 index e69de29bb..000000000 From 267e94342adb55b6b58e068f75af11b914fe2ded Mon Sep 17 00:00:00 2001 From: yuhwanwoo <6514687@naver.com> Date: Thu, 28 Sep 2023 20:27:23 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feature(order):=20=EB=B0=B0=EB=8B=AC=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 +- .../application/DeliveryOrderService.java | 112 ++++++++++ .../deliveryorders/domain/DeliveryOrder.java | 137 ++++++++++++ .../domain/DeliveryOrderAddress.java | 42 ++++ .../domain/DeliveryOrderLineItem.java | 84 ++++++++ .../domain/DeliveryOrderLineItemPrice.java | 36 ++++ .../domain/DeliveryOrderLineItemQuantity.java | 28 +++ .../domain/DeliveryOrderLineItems.java | 45 ++++ .../domain/DeliveryOrderRepository.java | 11 + .../domain/KitchenridersClient.java | 2 +- .../deliveryorders/domain/MenuClient.java | 13 ++ .../infra/DefaultKitchenridersClient.java | 1 + .../infra/JpaDeliveryOrderRepository.java | 10 + .../deliveryorders/infra/MenuClientImpl.java | 29 +++ .../shared/dto/DeliveryOrderDto.java | 43 ++++ .../shared/dto/DeliveryOrderLineItemDto.java | 31 +++ .../request/DeliveryOrderCreateRequest.java | 24 +++ .../ui/DeliveryOrderRestController.java | 14 ++ .../eatinorders/application/OrderService.java | 2 +- .../shared/dto/EatInOrderLineItemDto.java | 4 + .../dto/request/EatInOrderCreateRequest.java | 11 + .../shared/dto/request/MenuCreateRequest.java | 7 + .../kitchenpos/shared/util/ConvertUtil.java | 5 +- .../domain/TakeOutOrderService.java | 195 ++++++++++++++++++ src/test/java/kitchenpos/Fixtures.java | 13 ++ .../application/DeliveryOrderServiceTest.java | 184 +++++++++++++++++ .../InMemoryDeliveryOrderRepository.java | 31 +++ .../application/InMemoryMenuClient.java | 28 +++ .../domain/DeliveryOrderAddressTest.java | 18 ++ .../DeliveryOrderLineItemQuantityTest.java | 16 ++ .../domain/DeliveryOrderLineItemTest.java | 68 ++++++ .../domain/DeliveryOrderTest.java | 9 + .../application/FakeKitchenridersClient.java | 2 +- 33 files changed, 1261 insertions(+), 16 deletions(-) create mode 100644 src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddress.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItem.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemPrice.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantity.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderRepository.java create mode 100644 src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java create mode 100644 src/main/java/kitchenpos/deliveryorders/infra/JpaDeliveryOrderRepository.java create mode 100644 src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java create mode 100644 src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderDto.java create mode 100644 src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderLineItemDto.java create mode 100644 src/main/java/kitchenpos/deliveryorders/shared/dto/request/DeliveryOrderCreateRequest.java create mode 100644 src/main/java/kitchenpos/deliveryorders/ui/DeliveryOrderRestController.java create mode 100644 src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java create mode 100644 src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java create mode 100644 src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java create mode 100644 src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java create mode 100644 src/test/java/kitchenpos/deliveryorders/application/InMemoryDeliveryOrderRepository.java create mode 100644 src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java create mode 100644 src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddressTest.java create mode 100644 src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantityTest.java create mode 100644 src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemTest.java create mode 100644 src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderTest.java diff --git a/README.md b/README.md index 93670e572..6b52cee78 100644 --- a/README.md +++ b/README.md @@ -134,18 +134,18 @@ docker compose -p kitchenpos up -d ### 배달 주문 -| 한글명 | 영문명 | 설명 | -| --- | --- | --- | -| 배달 | delivering | 배달원이 매장을 방문하여 배달 음식의 픽업을 완료하고 배달을 시작하는 단계 | -| 배달 대행사 | delivery agency | 준비한 음식을 고객에게 직접 배달하는 서비스 | -| 배달 완료 | delivered | 배달원이 주문한 음식을 고객에게 배달 완료한 단계 | -| 서빙 | served | 조리가 완료되어 음식이 나갈 수 있는 단계 | -| 완료 | completed | 배달 및 결제 완료 단계 | -| 접수 | accepted | 주문을 받고 음식을 조리하는 단계 | -| 접수 대기 | waiting | 주문이 생성되어 매장으로 전달된 단계 | -| 주문 | order | 집이나 직장 등 고객이 선택한 주소로 음식을 배달한다. | +| 한글명 | 영문명 | 설명 | +| --- | --- |------------------------------------------------| +| 배달 | delivering | 배달원이 매장을 방문하여 배달 음식의 픽업을 완료하고 배달을 시작하는 단계 | +| 배달 대행사 | delivery agency | 준비한 음식을 고객에게 직접 배달하는 서비스 | +| 배달 완료 | delivered | 배달원이 주문한 음식을 고객에게 배달 완료한 단계 | +| 서빙 | served | 조리가 완료되어 음식이 나갈 수 있는 단계 | +| 완료 | completed | 배달이 완료된 후 주문을 마무리 하는 단계 | +| 접수 | accepted | 주문을 받고 음식을 조리하는 단계 | +| 접수 대기 | waiting | 주문이 생성되어 매장으로 전달된 단계 | +| 주문 | order | 집이나 직장 등 고객이 선택한 주소로 음식을 배달한다. | | 주문 상태 | order status | 주문이 생성되면 매장에서 주문을 접수하고 고객이 음식을 받기까지의 단계를 표시한다. | -| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 | +| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 | ### 포장 주문 diff --git a/src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java b/src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java new file mode 100644 index 000000000..da59658cd --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java @@ -0,0 +1,112 @@ +package kitchenpos.deliveryorders.application; + +import kitchenpos.deliveryorders.domain.DeliveryOrder; +import kitchenpos.deliveryorders.domain.DeliveryOrderAddress; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItem; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItemPrice; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItemQuantity; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItems; +import kitchenpos.deliveryorders.domain.DeliveryOrderRepository; +import kitchenpos.deliveryorders.domain.KitchenridersClient; +import kitchenpos.deliveryorders.domain.MenuClient; +import kitchenpos.deliveryorders.shared.dto.DeliveryOrderLineItemDto; +import kitchenpos.deliveryorders.shared.dto.DeliveryOrderDto; +import kitchenpos.deliveryorders.shared.dto.request.DeliveryOrderCreateRequest; +import kitchenpos.shared.util.ConvertUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +@Service +public class DeliveryOrderService { + private DeliveryOrderRepository deliveryOrderRepository; + private MenuClient menuClient; + private KitchenridersClient kitchenridersClient; + + public DeliveryOrderService(DeliveryOrderRepository deliveryOrderRepository, MenuClient menuClient, KitchenridersClient kitchenridersClient) { + this.deliveryOrderRepository = deliveryOrderRepository; + this.menuClient = menuClient; + this.kitchenridersClient = kitchenridersClient; + } + + @Transactional + public DeliveryOrderDto create(final DeliveryOrderCreateRequest request) { + final List orderLineItemRequests = request.getOrderLineItems(); + + if (Objects.isNull(orderLineItemRequests) || orderLineItemRequests.isEmpty()) { + throw new IllegalArgumentException(); + } + + List deliveryOrderLineItems = request.getOrderLineItems().stream() + .map(deliveryOrderLineItemDto -> DeliveryOrderLineItem.of( + deliveryOrderLineItemDto.getMenuId(), + new DeliveryOrderLineItemQuantity(deliveryOrderLineItemDto.getQuantity()), + new DeliveryOrderLineItemPrice(deliveryOrderLineItemDto.getPrice()), + menuClient + )) + .collect(Collectors.toList()); + + DeliveryOrder deliveryOrder = DeliveryOrder.of( + new DeliveryOrderLineItems(deliveryOrderLineItems), + new DeliveryOrderAddress(request.getDeliveryAddress()), + menuClient + ); + + return ConvertUtil.convert(deliveryOrderRepository.save(deliveryOrder), DeliveryOrderDto.class); + } + + @Transactional + public DeliveryOrderDto accept(final UUID orderId) { + DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + deliveryOrder.accept(kitchenridersClient); + + return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); + } + + @Transactional + public DeliveryOrderDto serve(final UUID orderId) { + DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + + deliveryOrder.serve(); + return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); + } + + @Transactional + public DeliveryOrderDto startDelivery(final UUID orderId) { + DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + + deliveryOrder.startDelivery(); + return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); + } + + @Transactional + public DeliveryOrderDto completeDelivery(final UUID orderId) { + DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + + deliveryOrder.completeDelivery(); + return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); + } + + @Transactional + public DeliveryOrderDto complete(final UUID orderId) { + DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + + deliveryOrder.complete(); + return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); + } + + @Transactional(readOnly = true) + public List findAll() { + return ConvertUtil.convertList(deliveryOrderRepository.findAll(), DeliveryOrderDto.class); + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java new file mode 100644 index 000000000..b79cd7df5 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java @@ -0,0 +1,137 @@ +package kitchenpos.deliveryorders.domain; + +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.domain.OrderType; +import kitchenpos.menus.tobe.domain.menu.Menu; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Table(name = "delivery_orders") +@Entity +public class DeliveryOrder { + @Column(name = "id", columnDefinition = "binary(16)") + @Id + private UUID id; + + @Column(name = "type", nullable = false) + @Enumerated(EnumType.STRING) + private OrderType type; + + @Column(name = "status", nullable = false) + @Enumerated(EnumType.STRING) + private OrderStatus status; + + @Column(name = "order_date_time", nullable = false) + private LocalDateTime orderDateTime; + + @Embedded + private DeliveryOrderLineItems orderLineItems; + + @Embedded + private DeliveryOrderAddress deliveryAddress; + + protected DeliveryOrder() { + } + + public DeliveryOrder(UUID id, OrderType type, OrderStatus status, LocalDateTime orderDateTime, DeliveryOrderLineItems orderLineItems, DeliveryOrderAddress deliveryAddress) { + this.id = id; + this.type = type; + this.status = status; + this.orderDateTime = orderDateTime; + this.orderLineItems = orderLineItems; + this.deliveryAddress = deliveryAddress; + } + + public static DeliveryOrder of(DeliveryOrderLineItems orderLineItems, DeliveryOrderAddress orderAddress, MenuClient menuClient) { + validateDeliveryOrder(orderLineItems, menuClient); + return new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.WAITING, LocalDateTime.now(), orderLineItems, orderAddress); + } + + private static void validateDeliveryOrder(DeliveryOrderLineItems orderLineItems, MenuClient menuClient) { + List menus = menuClient.findAllByIdIn( + orderLineItems.getOrderLineItems().stream() + .map(DeliveryOrderLineItem::getMenuId) + .collect(Collectors.toList()) + ); + if (menus.size() != orderLineItems.getOrderLineItems().size()) { + throw new IllegalArgumentException(); + } + } + + public UUID getId() { + return id; + } + + public OrderType getType() { + return type; + } + + public OrderStatus getStatus() { + return status; + } + + public LocalDateTime getOrderDateTime() { + return orderDateTime; + } + + public List getOrderLineItems() { + return orderLineItems.getOrderLineItems(); + } + + public String getDeliveryAddress() { + return deliveryAddress.getDeliveryOrderAddress(); + } + + public void accept(KitchenridersClient kitchenridersClient) { + if (status != OrderStatus.WAITING) { + throw new IllegalStateException(); + } + + kitchenridersClient.requestDelivery(id, orderLineItems.getTotalDeliveryOrderLineItemsPrice(), getDeliveryAddress()); + status = OrderStatus.ACCEPTED; + } + + public void serve() { + if (status != OrderStatus.ACCEPTED) { + throw new IllegalStateException(); + } + this.status = OrderStatus.SERVED; + } + + public void startDelivery() { + if (type != OrderType.DELIVERY) { + throw new IllegalStateException(); + } + if (status != OrderStatus.SERVED) { + throw new IllegalStateException(); + } + status = OrderStatus.DELIVERING; + } + + public void completeDelivery() { + if (status != OrderStatus.DELIVERING) { + throw new IllegalStateException(); + } + status = OrderStatus.DELIVERED; + } + + public void complete() { + if (type != OrderType.DELIVERY) { + throw new IllegalStateException(); + } + if (status != OrderStatus.DELIVERED) { + throw new IllegalStateException(); + } + status = OrderStatus.COMPLETED; + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddress.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddress.java new file mode 100644 index 000000000..27c26097f --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddress.java @@ -0,0 +1,42 @@ +package kitchenpos.deliveryorders.domain; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.util.Objects; + +@Embeddable +public class DeliveryOrderAddress { + @Column(name = "address", nullable = false) + private String deliveryOrderAddress; + + protected DeliveryOrderAddress() { + } + + public DeliveryOrderAddress(String deliveryOrderAddress) { + validateDeliveryOrderAddress(deliveryOrderAddress); + this.deliveryOrderAddress = deliveryOrderAddress; + } + + private void validateDeliveryOrderAddress(String deliveryOrderAddress) { + if (Objects.isNull(deliveryOrderAddress) || deliveryOrderAddress.isEmpty()) { + throw new IllegalArgumentException(); + } + } + + public String getDeliveryOrderAddress() { + return deliveryOrderAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeliveryOrderAddress that = (DeliveryOrderAddress) o; + return Objects.equals(deliveryOrderAddress, that.deliveryOrderAddress); + } + + @Override + public int hashCode() { + return Objects.hash(deliveryOrderAddress); + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItem.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItem.java new file mode 100644 index 000000000..809fca691 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItem.java @@ -0,0 +1,84 @@ +package kitchenpos.deliveryorders.domain; + +import kitchenpos.menus.tobe.domain.menu.Menu; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.math.BigDecimal; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.UUID; + +@Table(name = "delivery_order_line_item") +@Entity +public class DeliveryOrderLineItem { + @Column(name = "seq") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + private Long seq; + + private UUID menuId; + + @Embedded + private DeliveryOrderLineItemQuantity quantity; + + @Embedded + private DeliveryOrderLineItemPrice price; + + protected DeliveryOrderLineItem() { + } + + public DeliveryOrderLineItem(UUID menuId, DeliveryOrderLineItemQuantity quantity, DeliveryOrderLineItemPrice price) { + this.menuId = menuId; + this.quantity = quantity; + this.price = price; + } + + public static DeliveryOrderLineItem of(UUID menuId, DeliveryOrderLineItemQuantity quantity, DeliveryOrderLineItemPrice price, MenuClient menuClient) { + validateDeliveryOrderLineItem(menuId, price, menuClient); + return new DeliveryOrderLineItem(menuId, quantity, price); + } + + private static void validateDeliveryOrderLineItem(UUID menuId, DeliveryOrderLineItemPrice price, MenuClient menuClient) { + Menu menu = menuClient.findById(menuId) + .orElseThrow(() -> new NoSuchElementException("메뉴가 존재하지 않습니다. menuId: " + menuId)); + + if (!menu.isDisplayed()) { + throw new IllegalStateException(); + } + + if (menu.getPrice().compareTo(price.getDeliveryOrderLineItemPrice()) != 0) { + throw new IllegalArgumentException(); + } + } + + public UUID getMenuId() { + return menuId; + } + + public long getQuantity() { + return quantity.getQuantity(); + } + + public BigDecimal getPrice() { + return price.getDeliveryOrderLineItemPrice(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeliveryOrderLineItem that = (DeliveryOrderLineItem) o; + return Objects.equals(seq, that.seq); + } + + @Override + public int hashCode() { + return Objects.hash(seq); + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemPrice.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemPrice.java new file mode 100644 index 000000000..df97858b4 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemPrice.java @@ -0,0 +1,36 @@ +package kitchenpos.deliveryorders.domain; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.math.BigDecimal; +import java.util.Objects; + +@Embeddable +public class DeliveryOrderLineItemPrice { + @Column(name = "price", nullable = false) + private BigDecimal deliveryOrderLineItemPrice; + + protected DeliveryOrderLineItemPrice() { + } + + public DeliveryOrderLineItemPrice(BigDecimal deliveryOrderLineItemPrice) { + this.deliveryOrderLineItemPrice = deliveryOrderLineItemPrice; + } + + public BigDecimal getDeliveryOrderLineItemPrice() { + return deliveryOrderLineItemPrice; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeliveryOrderLineItemPrice that = (DeliveryOrderLineItemPrice) o; + return Objects.equals(deliveryOrderLineItemPrice, that.deliveryOrderLineItemPrice); + } + + @Override + public int hashCode() { + return Objects.hash(deliveryOrderLineItemPrice); + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantity.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantity.java new file mode 100644 index 000000000..58c0f4943 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantity.java @@ -0,0 +1,28 @@ +package kitchenpos.deliveryorders.domain; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class DeliveryOrderLineItemQuantity { + @Column + private long quantity; + + protected DeliveryOrderLineItemQuantity() { + } + + public DeliveryOrderLineItemQuantity(long quantity) { + validateDeliveryOrderLineItemQuantity(quantity); + this.quantity = quantity; + } + + private void validateDeliveryOrderLineItemQuantity(long quantity) { + if (quantity < 0) { + throw new IllegalArgumentException("배달 주문의 주문 항목 개수는 0이상이어야 합니다."); + } + } + + public long getQuantity() { + return quantity; + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java new file mode 100644 index 000000000..0136b3d51 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java @@ -0,0 +1,45 @@ +package kitchenpos.deliveryorders.domain; + +import javax.persistence.CascadeType; +import javax.persistence.Embeddable; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import java.math.BigDecimal; +import java.util.List; + +@Embeddable +public class DeliveryOrderLineItems { + @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @JoinColumn( + name = "order_id", + nullable = false, + columnDefinition = "binary(16)", + foreignKey = @ForeignKey(name = "fk_order_line_item_to_orders") + ) + private List orderLineItems; + + protected DeliveryOrderLineItems() { + } + + public DeliveryOrderLineItems(List orderLineItems) { + validateDeliveryOrderLineItems(orderLineItems); + this.orderLineItems = orderLineItems; + } + + private void validateDeliveryOrderLineItems(List orderLineItems) { + if (orderLineItems.isEmpty()) { + throw new IllegalArgumentException(); + } + } + + public List getOrderLineItems() { + return orderLineItems; + } + + public BigDecimal getTotalDeliveryOrderLineItemsPrice() { + return orderLineItems.stream().map(DeliveryOrderLineItem::getPrice) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderRepository.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderRepository.java new file mode 100644 index 000000000..876cbf848 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderRepository.java @@ -0,0 +1,11 @@ +package kitchenpos.deliveryorders.domain; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface DeliveryOrderRepository { + DeliveryOrder save(DeliveryOrder deliveryOrder); + Optional findById(final UUID id); + List findAll(); +} diff --git a/src/main/java/kitchenpos/deliveryorders/domain/KitchenridersClient.java b/src/main/java/kitchenpos/deliveryorders/domain/KitchenridersClient.java index 0c8278791..bcbeba0e7 100644 --- a/src/main/java/kitchenpos/deliveryorders/domain/KitchenridersClient.java +++ b/src/main/java/kitchenpos/deliveryorders/domain/KitchenridersClient.java @@ -1,4 +1,4 @@ -package kitchenpos.deliveryorders.infra; +package kitchenpos.deliveryorders.domain; import java.math.BigDecimal; import java.util.UUID; diff --git a/src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java b/src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java new file mode 100644 index 000000000..c9a8981f5 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java @@ -0,0 +1,13 @@ +package kitchenpos.deliveryorders.domain; + +import kitchenpos.menus.tobe.domain.menu.Menu; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface MenuClient { + + Optional findById(UUID id); + List findAllByIdIn(List ids); +} diff --git a/src/main/java/kitchenpos/deliveryorders/infra/DefaultKitchenridersClient.java b/src/main/java/kitchenpos/deliveryorders/infra/DefaultKitchenridersClient.java index 31d6d8cee..d6eb810cc 100644 --- a/src/main/java/kitchenpos/deliveryorders/infra/DefaultKitchenridersClient.java +++ b/src/main/java/kitchenpos/deliveryorders/infra/DefaultKitchenridersClient.java @@ -1,5 +1,6 @@ package kitchenpos.deliveryorders.infra; +import kitchenpos.deliveryorders.domain.KitchenridersClient; import org.springframework.stereotype.Component; import java.math.BigDecimal; diff --git a/src/main/java/kitchenpos/deliveryorders/infra/JpaDeliveryOrderRepository.java b/src/main/java/kitchenpos/deliveryorders/infra/JpaDeliveryOrderRepository.java new file mode 100644 index 000000000..0fd585b94 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/infra/JpaDeliveryOrderRepository.java @@ -0,0 +1,10 @@ +package kitchenpos.deliveryorders.infra; + +import kitchenpos.deliveryorders.domain.DeliveryOrder; +import kitchenpos.deliveryorders.domain.DeliveryOrderRepository; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface JpaDeliveryOrderRepository extends DeliveryOrderRepository, JpaRepository { +} diff --git a/src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java b/src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java new file mode 100644 index 000000000..6b1de4592 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java @@ -0,0 +1,29 @@ +package kitchenpos.deliveryorders.infra; + +import kitchenpos.deliveryorders.domain.MenuClient; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Service +public class MenuClientImpl implements MenuClient { + private final MenuRepository menuRepository; + + public MenuClientImpl(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Override + public Optional findById(UUID id) { + return menuRepository.findById(id); + } + + @Override + public List findAllByIdIn(List ids) { + return menuRepository.findAllByIdIn(ids); + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderDto.java b/src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderDto.java new file mode 100644 index 000000000..0f35724d6 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderDto.java @@ -0,0 +1,43 @@ +package kitchenpos.deliveryorders.shared.dto; + +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.domain.OrderType; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +public class DeliveryOrderDto { + private UUID id; + private OrderType type; + private OrderStatus status; + + private LocalDateTime orderDateTime; + private String deliveryAddress; + + private List orderLineItems; + + public List getOrderLineItems() { + return orderLineItems; + } + + public String getDeliveryAddress() { + return deliveryAddress; + } + + public UUID getId() { + return id; + } + + public OrderType getType() { + return type; + } + + public OrderStatus getStatus() { + return status; + } + + public LocalDateTime getOrderDateTime() { + return orderDateTime; + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderLineItemDto.java b/src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderLineItemDto.java new file mode 100644 index 000000000..82772952e --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/shared/dto/DeliveryOrderLineItemDto.java @@ -0,0 +1,31 @@ +package kitchenpos.deliveryorders.shared.dto; + +import java.math.BigDecimal; +import java.util.UUID; + +public class DeliveryOrderLineItemDto { + private UUID menuId; + private long quantity; + private BigDecimal price; + + protected DeliveryOrderLineItemDto() { + } + + public DeliveryOrderLineItemDto(UUID menuId, long quantity, BigDecimal price) { + this.menuId = menuId; + this.quantity = quantity; + this.price = price; + } + + public UUID getMenuId() { + return menuId; + } + + public long getQuantity() { + return quantity; + } + + public BigDecimal getPrice() { + return price; + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/shared/dto/request/DeliveryOrderCreateRequest.java b/src/main/java/kitchenpos/deliveryorders/shared/dto/request/DeliveryOrderCreateRequest.java new file mode 100644 index 000000000..47121e862 --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/shared/dto/request/DeliveryOrderCreateRequest.java @@ -0,0 +1,24 @@ +package kitchenpos.deliveryorders.shared.dto.request; + +import kitchenpos.deliveryorders.shared.dto.DeliveryOrderLineItemDto; + +import java.util.List; + +public class DeliveryOrderCreateRequest { + private List orderLineItems; + + private String deliveryAddress; + + public DeliveryOrderCreateRequest(List orderLineItems, String deliveryAddress) { + this.orderLineItems = orderLineItems; + this.deliveryAddress = deliveryAddress; + } + + public List getOrderLineItems() { + return orderLineItems; + } + + public String getDeliveryAddress() { + return deliveryAddress; + } +} diff --git a/src/main/java/kitchenpos/deliveryorders/ui/DeliveryOrderRestController.java b/src/main/java/kitchenpos/deliveryorders/ui/DeliveryOrderRestController.java new file mode 100644 index 000000000..9174fcbbe --- /dev/null +++ b/src/main/java/kitchenpos/deliveryorders/ui/DeliveryOrderRestController.java @@ -0,0 +1,14 @@ +package kitchenpos.deliveryorders.ui; + +import kitchenpos.deliveryorders.application.DeliveryOrderService; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DeliveryOrderRestController { + + private final DeliveryOrderService deliveryOrderService; + + public DeliveryOrderRestController(DeliveryOrderService deliveryOrderService) { + this.deliveryOrderService = deliveryOrderService; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/OrderService.java b/src/main/java/kitchenpos/eatinorders/application/OrderService.java index 0b16edb94..c6c02013d 100644 --- a/src/main/java/kitchenpos/eatinorders/application/OrderService.java +++ b/src/main/java/kitchenpos/eatinorders/application/OrderService.java @@ -1,6 +1,6 @@ package kitchenpos.eatinorders.application; -import kitchenpos.deliveryorders.infra.KitchenridersClient; +import kitchenpos.deliveryorders.domain.KitchenridersClient; import kitchenpos.eatinorders.domain.*; import kitchenpos.menus.tobe.domain.menu.Menu; import kitchenpos.menus.tobe.domain.menu.MenuRepository; diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java b/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java new file mode 100644 index 000000000..576a3a147 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java @@ -0,0 +1,4 @@ +package kitchenpos.eatinorders.shared.dto; + +public class EatInOrderLineItemDto { +} diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java b/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java new file mode 100644 index 000000000..d8f028120 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java @@ -0,0 +1,11 @@ +package kitchenpos.eatinorders.shared.dto.request; + +import kitchenpos.eatinorders.shared.dto.EatInOrderLineItemDto; + +import java.util.List; + +public class EatInOrderCreateRequest { + List orderLineItems; + + +} diff --git a/src/main/java/kitchenpos/menus/shared/dto/request/MenuCreateRequest.java b/src/main/java/kitchenpos/menus/shared/dto/request/MenuCreateRequest.java index 87e1b217c..1e5e3ceaf 100644 --- a/src/main/java/kitchenpos/menus/shared/dto/request/MenuCreateRequest.java +++ b/src/main/java/kitchenpos/menus/shared/dto/request/MenuCreateRequest.java @@ -1,6 +1,8 @@ package kitchenpos.menus.shared.dto.request; import kitchenpos.menus.shared.dto.MenuProductDto; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuName; import java.math.BigDecimal; import java.util.List; @@ -41,4 +43,9 @@ public MenuCreateRequest(String name, BigDecimal price, UUID menuGroupId, List { - private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper objectMapper; - public ConvertUtil() { + static { + objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false); objectMapper.registerModule(new JavaTimeModule()); diff --git a/src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java b/src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java new file mode 100644 index 000000000..346e73ab6 --- /dev/null +++ b/src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java @@ -0,0 +1,195 @@ +package kitchenpos.takeoutorders.domain; + +import kitchenpos.deliveryorders.domain.KitchenridersClient; +import kitchenpos.eatinorders.domain.Order; +import kitchenpos.eatinorders.domain.OrderLineItem; +import kitchenpos.eatinorders.domain.OrderRepository; +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.domain.OrderTable; +import kitchenpos.eatinorders.domain.OrderTableRepository; +import kitchenpos.eatinorders.domain.OrderType; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +@Service +public class TakeOutOrderService { + + private final OrderRepository orderRepository; + private final MenuRepository menuRepository; + private final OrderTableRepository orderTableRepository; + private final KitchenridersClient kitchenridersClient; + + public TakeOutOrderService( + final OrderRepository orderRepository, + final MenuRepository menuRepository, + final OrderTableRepository orderTableRepository, + final KitchenridersClient kitchenridersClient + ) { + this.orderRepository = orderRepository; + this.menuRepository = menuRepository; + this.orderTableRepository = orderTableRepository; + this.kitchenridersClient = kitchenridersClient; + } + + @Transactional + public Order create(final Order request) { + final OrderType type = request.getType(); + if (Objects.isNull(type)) { + throw new IllegalArgumentException(); + } + final List orderLineItemRequests = request.getOrderLineItems(); + if (Objects.isNull(orderLineItemRequests) || orderLineItemRequests.isEmpty()) { + throw new IllegalArgumentException(); + } + final List menus = menuRepository.findAllByIdIn( + orderLineItemRequests.stream() + .map(OrderLineItem::getMenuId) + .collect(Collectors.toList()) + ); + if (menus.size() != orderLineItemRequests.size()) { + throw new IllegalArgumentException(); + } + final List orderLineItems = new ArrayList<>(); + for (final OrderLineItem orderLineItemRequest : orderLineItemRequests) { + final long quantity = orderLineItemRequest.getQuantity(); + if (type != OrderType.EAT_IN) { + if (quantity < 0) { + throw new IllegalArgumentException(); + } + } + final Menu menu = menuRepository.findById(orderLineItemRequest.getMenuId()) + .orElseThrow(NoSuchElementException::new); + if (!menu.isDisplayed()) { + throw new IllegalStateException(); + } + if (menu.getPrice().compareTo(orderLineItemRequest.getPrice()) != 0) { + throw new IllegalArgumentException(); + } + final OrderLineItem orderLineItem = new OrderLineItem(); + orderLineItem.setMenu(menu); + orderLineItem.setQuantity(quantity); + orderLineItems.add(orderLineItem); + } + Order order = new Order(); + order.setId(UUID.randomUUID()); + order.setType(type); + order.setStatus(OrderStatus.WAITING); + order.setOrderDateTime(LocalDateTime.now()); + order.setOrderLineItems(orderLineItems); + if (type == OrderType.DELIVERY) { + final String deliveryAddress = request.getDeliveryAddress(); + if (Objects.isNull(deliveryAddress) || deliveryAddress.isEmpty()) { + throw new IllegalArgumentException(); + } + order.setDeliveryAddress(deliveryAddress); + } + if (type == OrderType.EAT_IN) { + final OrderTable orderTable = orderTableRepository.findById(request.getOrderTableId()) + .orElseThrow(NoSuchElementException::new); + if (!orderTable.isOccupied()) { + throw new IllegalStateException(); + } + order.setOrderTable(orderTable); + } + return orderRepository.save(order); + } + + @Transactional + public Order accept(final UUID orderId) { + final Order order = orderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + if (order.getStatus() != OrderStatus.WAITING) { + throw new IllegalStateException(); + } + if (order.getType() == OrderType.DELIVERY) { + BigDecimal sum = BigDecimal.ZERO; + for (final OrderLineItem orderLineItem : order.getOrderLineItems()) { + sum = orderLineItem.getMenu() + .getPrice() + .multiply(BigDecimal.valueOf(orderLineItem.getQuantity())); + } + kitchenridersClient.requestDelivery(orderId, sum, order.getDeliveryAddress()); + } + order.setStatus(OrderStatus.ACCEPTED); + return order; + } + + @Transactional + public Order serve(final UUID orderId) { + final Order order = orderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + if (order.getStatus() != OrderStatus.ACCEPTED) { + throw new IllegalStateException(); + } + order.setStatus(OrderStatus.SERVED); + return order; + } + + @Transactional + public Order startDelivery(final UUID orderId) { + final Order order = orderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + if (order.getType() != OrderType.DELIVERY) { + throw new IllegalStateException(); + } + if (order.getStatus() != OrderStatus.SERVED) { + throw new IllegalStateException(); + } + order.setStatus(OrderStatus.DELIVERING); + return order; + } + + @Transactional + public Order completeDelivery(final UUID orderId) { + final Order order = orderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + if (order.getStatus() != OrderStatus.DELIVERING) { + throw new IllegalStateException(); + } + order.setStatus(OrderStatus.DELIVERED); + return order; + } + + @Transactional + public Order complete(final UUID orderId) { + final Order order = orderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + final OrderType type = order.getType(); + final OrderStatus status = order.getStatus(); + if (type == OrderType.DELIVERY) { + if (status != OrderStatus.DELIVERED) { + throw new IllegalStateException(); + } + } + if (type == OrderType.TAKEOUT || type == OrderType.EAT_IN) { + if (status != OrderStatus.SERVED) { + throw new IllegalStateException(); + } + } + order.setStatus(OrderStatus.COMPLETED); + if (type == OrderType.EAT_IN) { + final OrderTable orderTable = order.getOrderTable(); + if (!orderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) { + orderTable.setNumberOfGuests(0); + orderTable.setOccupied(false); + } + } + return order; + } + + @Transactional(readOnly = true) + public List findAll() { + return orderRepository.findAll(); + } +} diff --git a/src/test/java/kitchenpos/Fixtures.java b/src/test/java/kitchenpos/Fixtures.java index baf728be4..528b02fa7 100644 --- a/src/test/java/kitchenpos/Fixtures.java +++ b/src/test/java/kitchenpos/Fixtures.java @@ -1,7 +1,13 @@ package kitchenpos; import kitchenpos.common.domain.PurgomalumClient; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItem; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItemPrice; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItemQuantity; +import kitchenpos.deliveryorders.domain.MenuClient; +import kitchenpos.deliveryorders.infra.MenuClientImpl; import kitchenpos.eatinorders.domain.*; +import kitchenpos.menus.application.InMemoryMenuRepository; import kitchenpos.menus.tobe.domain.menu.Menu; import kitchenpos.menus.tobe.domain.menu.MenuName; import kitchenpos.menus.tobe.domain.menu.MenuPrice; @@ -36,6 +42,9 @@ public static Menu menu() { public static Menu menu(final long price, final MenuProduct... menuProducts) { return menu(price, false, menuProducts); } + public static Menu displayedMenu(final long price, final MenuProduct... menuProducts) { + return menu(price, true, menuProducts); + } public static Menu menu(final long price, final boolean displayed, final MenuProduct... menuProducts) { final Menu menu = Menu.of(new MenuName("후라이드+후라이드", purgomalumClient), new MenuPrice(BigDecimal.valueOf(price)), menuGroup(), displayed, new MenuProducts(Arrays.asList(menuProducts))); @@ -101,6 +110,10 @@ public static OrderLineItem orderLineItem() { return orderLineItem; } + public static DeliveryOrderLineItem deliveryOrderLineItem(Menu menu, MenuClient menuClient) { + return DeliveryOrderLineItem.of(menu.getId(), new DeliveryOrderLineItemQuantity(2L), new DeliveryOrderLineItemPrice(menu.getPrice()), menuClient); + } + public static OrderTable orderTable() { return orderTable(false, 0); } diff --git a/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java b/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java new file mode 100644 index 000000000..f0c4202a2 --- /dev/null +++ b/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java @@ -0,0 +1,184 @@ +package kitchenpos.deliveryorders.application; + +import kitchenpos.deliveryorders.domain.DeliveryOrder; +import kitchenpos.deliveryorders.domain.DeliveryOrderAddress; +import kitchenpos.deliveryorders.domain.DeliveryOrderLineItems; +import kitchenpos.deliveryorders.domain.DeliveryOrderRepository; +import kitchenpos.deliveryorders.domain.KitchenridersClient; +import kitchenpos.deliveryorders.domain.MenuClient; +import kitchenpos.deliveryorders.shared.dto.DeliveryOrderDto; +import kitchenpos.deliveryorders.shared.dto.DeliveryOrderLineItemDto; +import kitchenpos.deliveryorders.shared.dto.request.DeliveryOrderCreateRequest; +import kitchenpos.eatinorders.application.FakeKitchenridersClient; +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.domain.OrderType; +import kitchenpos.menus.application.InMemoryMenuRepository; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import kitchenpos.products.application.InMemoryProductRepository; +import kitchenpos.products.tobe.domain.Product; +import kitchenpos.products.tobe.domain.ProductRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +import static kitchenpos.Fixtures.deliveryOrderLineItem; +import static kitchenpos.Fixtures.displayedMenu; +import static kitchenpos.Fixtures.menu; +import static kitchenpos.Fixtures.menuProduct; +import static kitchenpos.Fixtures.product; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class DeliveryOrderServiceTest { + private DeliveryOrderRepository deliveryOrderRepository; + private MenuClient menuClient; + + private MenuRepository menuRepository; + private ProductRepository productRepository; + + private DeliveryOrderService deliveryOrderService; + private KitchenridersClient kitchenridersClient; + + Menu displayedMenu; + Menu hidedMenu; + Product product; + + + @BeforeEach + void setUp() { + deliveryOrderRepository = new InMemoryDeliveryOrderRepository(); + menuRepository = new InMemoryMenuRepository(); + productRepository = new InMemoryProductRepository(); + kitchenridersClient = new FakeKitchenridersClient(); + product = productRepository.save(product()); + menuClient = new InMemoryMenuClient(menuRepository); + deliveryOrderService = new DeliveryOrderService(deliveryOrderRepository, menuClient, kitchenridersClient); + displayedMenu = menuRepository.save(displayedMenu(1L, menuProduct(product, 1L))); + hidedMenu = menuRepository.save(menu(1L, menuProduct(product, 1L))); + } + + @DisplayName("배달 주문을 성공한다.") + @Test + void success_create_delivery_order() { + //given + DeliveryOrderCreateRequest request = createDeliveryOrderRequest(List.of(createDisplayedDeliveryOrderLineItemDto(displayedMenu.getPrice())), "서울"); + + //when + DeliveryOrderDto result = deliveryOrderService.create(request); + + //then + assertThat(result.getStatus()).isEqualTo(OrderStatus.WAITING); + assertThat(result.getType()).isEqualTo(OrderType.DELIVERY); + assertThat(result.getOrderDateTime()).isNotNull(); + assertThat(result.getDeliveryAddress()).isEqualTo(request.getDeliveryAddress()); + } + + @DisplayName("배달 주문을 성공하려면 메뉴가 노출상태여야 한다.") + @Test + void menu_of_delivery_order_should_be_isDisplayed() { + //given + DeliveryOrderCreateRequest request = createDeliveryOrderRequest(List.of(createHidedDeliveryOrderLineItemDto(displayedMenu.getPrice())), "서울"); + + //when + assertThatThrownBy(() -> deliveryOrderService.create(request)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("배달 주문은 주소가 필수값이다.") + @ParameterizedTest + @NullAndEmptySource + void delivery_order_should_contain_delivery_address(String deliveryAddress) { + //given + DeliveryOrderCreateRequest request = createDeliveryOrderRequest(List.of(createDisplayedDeliveryOrderLineItemDto(displayedMenu.getPrice())), deliveryAddress); + + //when + assertThatThrownBy(() -> deliveryOrderService.create(request)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("배달 주문은 주소가 필수값이다.") + @Test + void menu_price_of_delivery_order_and_order_line_item_price_should_be_same() { + //given + DeliveryOrderCreateRequest request = createDeliveryOrderRequest(List.of(createDisplayedDeliveryOrderLineItemDto(BigDecimal.TEN)), "서울"); + + //when + assertThatThrownBy(() -> deliveryOrderService.create(request)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("접수 대기 중인 주문만 접수할 수 있다.") + @Test + void only_waiting_order_can_be_accept() { + + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + deliveryOrderRepository.save(deliveryOrder); + + assertThatThrownBy(() -> deliveryOrderService.accept(deliveryOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("접수중인 주문만 서빙할 수 있다.") + @Test + void only_accepted_order_can_be_serve() { + + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + deliveryOrderRepository.save(deliveryOrder); + + assertThatThrownBy(() -> deliveryOrderService.serve(deliveryOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("서빙중인 주문만 배달할 수 있다.") + @Test + void only_served_order_can_be_delivery_start() { + + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + deliveryOrderRepository.save(deliveryOrder); + + assertThatThrownBy(() -> deliveryOrderService.startDelivery(deliveryOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("배달한 주문만 배달 완료할 수 있다.") + @Test + void only_delivery_started_order_can_be_complete_delivery() { + + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.SERVED, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + deliveryOrderRepository.save(deliveryOrder); + + assertThatThrownBy(() -> deliveryOrderService.completeDelivery(deliveryOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("배달한 주문만 배달 완료할 수 있다.") + @Test + void only_delivery_completed_order_can_be_complete() { + + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.SERVED, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + deliveryOrderRepository.save(deliveryOrder); + + assertThatThrownBy(() -> deliveryOrderService.complete(deliveryOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + private DeliveryOrderCreateRequest createDeliveryOrderRequest(List deliveryOrderLineItemDtos, String deliveryAddress) { + return new DeliveryOrderCreateRequest(deliveryOrderLineItemDtos, deliveryAddress); + } + + private DeliveryOrderLineItemDto createDisplayedDeliveryOrderLineItemDto(BigDecimal price) { + return new DeliveryOrderLineItemDto(displayedMenu.getId(), 2, price); + } + + private DeliveryOrderLineItemDto createHidedDeliveryOrderLineItemDto(BigDecimal price) { + return new DeliveryOrderLineItemDto(hidedMenu.getId(), 2, price); + } +} \ No newline at end of file diff --git a/src/test/java/kitchenpos/deliveryorders/application/InMemoryDeliveryOrderRepository.java b/src/test/java/kitchenpos/deliveryorders/application/InMemoryDeliveryOrderRepository.java new file mode 100644 index 000000000..f265d8b2c --- /dev/null +++ b/src/test/java/kitchenpos/deliveryorders/application/InMemoryDeliveryOrderRepository.java @@ -0,0 +1,31 @@ +package kitchenpos.deliveryorders.application; + +import kitchenpos.deliveryorders.domain.DeliveryOrder; +import kitchenpos.deliveryorders.domain.DeliveryOrderRepository; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +public class InMemoryDeliveryOrderRepository implements DeliveryOrderRepository { + private final Map orders = new HashMap<>(); + + @Override + public DeliveryOrder save(final DeliveryOrder deliveryOrder) { + orders.put(deliveryOrder.getId(), deliveryOrder); + return deliveryOrder; + } + + @Override + public Optional findById(final UUID id) { + return Optional.ofNullable(orders.get(id)); + } + + @Override + public List findAll() { + return new ArrayList<>(orders.values()); + } +} diff --git a/src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java b/src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java new file mode 100644 index 000000000..c702845ff --- /dev/null +++ b/src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java @@ -0,0 +1,28 @@ +package kitchenpos.deliveryorders.application; + +import kitchenpos.deliveryorders.domain.MenuClient; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public class InMemoryMenuClient implements MenuClient { + + private final MenuRepository menuRepository; + + public InMemoryMenuClient(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Override + public Optional findById(UUID id) { + return menuRepository.findById(id); + } + + @Override + public List findAllByIdIn(List ids) { + return menuRepository.findAllByIdIn(ids); + } +} diff --git a/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddressTest.java b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddressTest.java new file mode 100644 index 000000000..8783b5aeb --- /dev/null +++ b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderAddressTest.java @@ -0,0 +1,18 @@ +package kitchenpos.deliveryorders.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class DeliveryOrderAddressTest { + + @DisplayName("배달 주문의 주소는 필수값이다.") + @ParameterizedTest + @NullAndEmptySource + void delivery_address_of_delivery_order_should_be_exist(String deliveryAddress) { + assertThatThrownBy(() -> new DeliveryOrderAddress(deliveryAddress)) + .isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file diff --git a/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantityTest.java b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantityTest.java new file mode 100644 index 000000000..9026c5ab9 --- /dev/null +++ b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemQuantityTest.java @@ -0,0 +1,16 @@ +package kitchenpos.deliveryorders.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class DeliveryOrderLineItemQuantityTest { + + @DisplayName("배달 주문의 주문항목 수량은 0 이상이야 합니다.") + @Test + void deliveryOrderLineItemQuantity_should_be_greater_than_zero() { + Assertions.assertThatThrownBy(() -> new DeliveryOrderLineItemQuantity(-1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("배달 주문의 주문 항목 개수는 0이상이어야 합니다."); + } +} \ No newline at end of file diff --git a/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemTest.java b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemTest.java new file mode 100644 index 000000000..e123abb26 --- /dev/null +++ b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItemTest.java @@ -0,0 +1,68 @@ +package kitchenpos.deliveryorders.domain; + +import kitchenpos.deliveryorders.application.InMemoryMenuClient; +import kitchenpos.menus.application.InMemoryMenuRepository; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import kitchenpos.products.application.InMemoryProductRepository; +import kitchenpos.products.tobe.domain.Product; +import kitchenpos.products.tobe.domain.ProductRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.NoSuchElementException; +import java.util.UUID; + +import static kitchenpos.Fixtures.displayedMenu; +import static kitchenpos.Fixtures.menu; +import static kitchenpos.Fixtures.menuProduct; +import static kitchenpos.Fixtures.product; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class DeliveryOrderLineItemTest { + + private MenuRepository menuRepository; + private MenuClient menuClient; + private ProductRepository productRepository; + + Product product; + Menu displayedMenu; + Menu hidedMenu; + @BeforeEach + void setUp() { + menuRepository = new InMemoryMenuRepository(); + menuClient = new InMemoryMenuClient(menuRepository); + productRepository = new InMemoryProductRepository(); + product = productRepository.save(product()); + displayedMenu = menuRepository.save(displayedMenu(1L, menuProduct(product, 1L))); + hidedMenu = menuRepository.save(menu(1L, menuProduct(product, 1L))); + } + + @DisplayName("주문 항목의 메뉴는 필수로 존재하는 메뉴여야 한다.") + @Test + void menu_of_order_line_items_must_be_exist() { + + assertThatThrownBy(() -> DeliveryOrderLineItem.of(UUID.randomUUID(), new DeliveryOrderLineItemQuantity(1L), new DeliveryOrderLineItemPrice(BigDecimal.TEN), menuClient)) + .isInstanceOf(NoSuchElementException.class) + .hasMessageContaining("메뉴가 존재하지 않습니다."); + } + + @DisplayName("주문 항목의 메뉴는 노출 상태여야 한다.") + @Test + void menu_of_order_line_items_must_be_is_displayed() { + assertThatThrownBy(() -> DeliveryOrderLineItem.of(hidedMenu.getId(), new DeliveryOrderLineItemQuantity(1L), new DeliveryOrderLineItemPrice(BigDecimal.TEN), menuClient)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("주문 항목의 메뉴의 가격은 메뉴 가격과 같아야 한다.") + @Test + void menu_price_and_price_of_order_line_items_must_be_same() { + assertThatThrownBy(() -> DeliveryOrderLineItem.of(displayedMenu.getId(), new DeliveryOrderLineItemQuantity(1L), new DeliveryOrderLineItemPrice(BigDecimal.TEN), menuClient)) + .isInstanceOf(IllegalArgumentException.class); + } + +} \ No newline at end of file diff --git a/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderTest.java b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderTest.java new file mode 100644 index 000000000..5307c6366 --- /dev/null +++ b/src/test/java/kitchenpos/deliveryorders/domain/DeliveryOrderTest.java @@ -0,0 +1,9 @@ +package kitchenpos.deliveryorders.domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class DeliveryOrderTest { + +} \ No newline at end of file diff --git a/src/test/java/kitchenpos/eatinorders/application/FakeKitchenridersClient.java b/src/test/java/kitchenpos/eatinorders/application/FakeKitchenridersClient.java index 301e1377b..ea2acd856 100644 --- a/src/test/java/kitchenpos/eatinorders/application/FakeKitchenridersClient.java +++ b/src/test/java/kitchenpos/eatinorders/application/FakeKitchenridersClient.java @@ -1,6 +1,6 @@ package kitchenpos.eatinorders.application; -import kitchenpos.deliveryorders.infra.KitchenridersClient; +import kitchenpos.deliveryorders.domain.KitchenridersClient; import java.math.BigDecimal; import java.util.UUID; From a888d59a3379f23e52e323ef33ae0376f0501707 Mon Sep 17 00:00:00 2001 From: yuhwanwoo <6514687@naver.com> Date: Fri, 29 Sep 2023 11:18:34 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feature(order):=20=EB=A7=A4=EC=9E=A5=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/DeliveryOrderService.java | 5 - .../domain/DeliveryOrderLineItems.java | 1 - .../application/EatInOrderService.java | 105 +++ .../eatinorders/application/OrderService.java | 5 +- .../application/OrderTableService.java | 49 +- .../kitchenpos/eatinorders/domain/Order.java | 2 + .../eatinorders/domain/OrderRepository.java | 2 + .../eatinorders/domain/OrderTable.java | 59 -- .../infra/EatInMenuClientImpl.java | 30 + .../infra/JpaEatInOrderRepositoryImpl.java | 11 + .../JpaOrderTableRepository.java | 4 +- .../eatinorders/shared/dto/EatInOrderDto.java | 43 + .../shared/dto/EatInOrderLineItemDto.java | 27 + .../eatinorders/shared/dto/OrderTableDto.java | 28 + .../dto/request/EatInOrderCreateRequest.java | 15 +- ...OrderTableChangeNumberOfGuestsRequest.java | 13 + .../dto/request/OrderTableCreateRequest.java | 13 + .../tobe/domain/order/EatInMenuClient.java | 12 + .../tobe/domain/order/EatInOrder.java | 131 +++ .../tobe/domain/order/EatInOrderLineItem.java | 88 ++ .../domain/order/EatInOrderLineItemPrice.java | 36 + .../order/EatInOrderLineItemQuantity.java | 35 + .../domain/order/EatInOrderLineItems.java | 31 + .../domain/order/EatInOrderRepository.java | 18 + .../domain/ordertable/NumberOfGuests.java | 42 + .../tobe/domain/ordertable/OrderTable.java | 71 ++ .../domain/ordertable/OrderTableName.java | 42 + .../ordertable}/OrderTableRepository.java | 2 +- .../ui/OrderTableRestController.java | 8 +- .../domain/TakeOutOrderService.java | 7 +- src/test/java/kitchenpos/Fixtures.java | 31 +- .../application/DeliveryOrderServiceTest.java | 4 +- .../application/EatInOrderServiceTest.java | 158 ++++ .../application/InMemoryEatInMenuClient.java | 27 + .../InMemoryEatInOrderRepository.java | 40 + .../application/InMemoryOrderRepository.java | 2 +- .../InMemoryOrderTableRepository.java | 4 +- .../application/OrderServiceTest.java | 756 +++++++++--------- .../application/OrderTableServiceTest.java | 68 +- 39 files changed, 1510 insertions(+), 515 deletions(-) create mode 100644 src/main/java/kitchenpos/eatinorders/application/EatInOrderService.java delete mode 100644 src/main/java/kitchenpos/eatinorders/domain/OrderTable.java create mode 100644 src/main/java/kitchenpos/eatinorders/infra/EatInMenuClientImpl.java create mode 100644 src/main/java/kitchenpos/eatinorders/infra/JpaEatInOrderRepositoryImpl.java rename src/main/java/kitchenpos/eatinorders/{domain => infra}/JpaOrderTableRepository.java (52%) create mode 100644 src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderDto.java create mode 100644 src/main/java/kitchenpos/eatinorders/shared/dto/OrderTableDto.java create mode 100644 src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderTableChangeNumberOfGuestsRequest.java create mode 100644 src/main/java/kitchenpos/eatinorders/shared/dto/request/OrderTableCreateRequest.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInMenuClient.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItem.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemPrice.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemQuantity.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItems.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderRepository.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/NumberOfGuests.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTable.java create mode 100644 src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTableName.java rename src/main/java/kitchenpos/eatinorders/{domain => tobe/domain/ordertable}/OrderTableRepository.java (81%) create mode 100644 src/test/java/kitchenpos/eatinorders/application/EatInOrderServiceTest.java create mode 100644 src/test/java/kitchenpos/eatinorders/application/InMemoryEatInMenuClient.java create mode 100644 src/test/java/kitchenpos/eatinorders/application/InMemoryEatInOrderRepository.java diff --git a/src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java b/src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java index da59658cd..340e5b016 100644 --- a/src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java +++ b/src/main/java/kitchenpos/deliveryorders/application/DeliveryOrderService.java @@ -65,7 +65,6 @@ public DeliveryOrderDto accept(final UUID orderId) { DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) .orElseThrow(NoSuchElementException::new); deliveryOrder.accept(kitchenridersClient); - return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); } @@ -73,7 +72,6 @@ public DeliveryOrderDto accept(final UUID orderId) { public DeliveryOrderDto serve(final UUID orderId) { DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) .orElseThrow(NoSuchElementException::new); - deliveryOrder.serve(); return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); } @@ -82,7 +80,6 @@ public DeliveryOrderDto serve(final UUID orderId) { public DeliveryOrderDto startDelivery(final UUID orderId) { DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) .orElseThrow(NoSuchElementException::new); - deliveryOrder.startDelivery(); return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); } @@ -91,7 +88,6 @@ public DeliveryOrderDto startDelivery(final UUID orderId) { public DeliveryOrderDto completeDelivery(final UUID orderId) { DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) .orElseThrow(NoSuchElementException::new); - deliveryOrder.completeDelivery(); return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); } @@ -100,7 +96,6 @@ public DeliveryOrderDto completeDelivery(final UUID orderId) { public DeliveryOrderDto complete(final UUID orderId) { DeliveryOrder deliveryOrder = deliveryOrderRepository.findById(orderId) .orElseThrow(NoSuchElementException::new); - deliveryOrder.complete(); return ConvertUtil.convert(deliveryOrder, DeliveryOrderDto.class); } diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java index 0136b3d51..a5e3d432e 100644 --- a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrderLineItems.java @@ -4,7 +4,6 @@ import javax.persistence.Embeddable; import javax.persistence.ForeignKey; import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import java.math.BigDecimal; import java.util.List; diff --git a/src/main/java/kitchenpos/eatinorders/application/EatInOrderService.java b/src/main/java/kitchenpos/eatinorders/application/EatInOrderService.java new file mode 100644 index 000000000..846cdabfc --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/EatInOrderService.java @@ -0,0 +1,105 @@ +package kitchenpos.eatinorders.application; + +import kitchenpos.eatinorders.tobe.domain.order.EatInMenuClient; +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.shared.dto.EatInOrderDto; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItems; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderRepository; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; +import kitchenpos.eatinorders.shared.dto.EatInOrderLineItemDto; +import kitchenpos.eatinorders.shared.dto.request.EatInOrderCreateRequest; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrder; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItem; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItemPrice; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItemQuantity; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import kitchenpos.shared.util.ConvertUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +@Service +public class EatInOrderService { + private final EatInOrderRepository eatInOrderRepository; + private final MenuRepository menuRepository; + private final OrderTableRepository orderTableRepository; + private final EatInMenuClient eatInMenuClient; + + public EatInOrderService(EatInOrderRepository eatInOrderRepository, MenuRepository menuRepository, OrderTableRepository orderTableRepository, EatInMenuClient eatInMenuClient) { + this.eatInOrderRepository = eatInOrderRepository; + this.menuRepository = menuRepository; + this.orderTableRepository = orderTableRepository; + this.eatInMenuClient = eatInMenuClient; + } + + @Transactional + public EatInOrderDto create(final EatInOrderCreateRequest request) { + List orderLineItemRequests = request.getOrderLineItems(); + if (Objects.isNull(orderLineItemRequests) || orderLineItemRequests.isEmpty()) { + throw new IllegalArgumentException(); + } + + List orderLineItems = request.getOrderLineItems().stream() + .map(eatInOrderLineItemDto -> EatInOrderLineItem.of( + eatInOrderLineItemDto.getMenuId(), + new EatInOrderLineItemQuantity(eatInOrderLineItemDto.getQuantity()), + new EatInOrderLineItemPrice(eatInOrderLineItemDto.getPrice()), + eatInMenuClient + )) + .collect(Collectors.toList()); + + OrderTable orderTable = orderTableRepository.findById(request.getOrderTableId()) + .orElseThrow(NoSuchElementException::new); + + EatInOrder eatInOrder = EatInOrder.of( + new EatInOrderLineItems(orderLineItems), + orderTable, + eatInMenuClient + ); + + return ConvertUtil.convert(eatInOrderRepository.save(eatInOrder), EatInOrderDto.class); + } + + @Transactional + public EatInOrderDto accept(UUID orderId) { + EatInOrder eatInOrder = eatInOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + eatInOrder.accept(); + return ConvertUtil.convert(eatInOrder, EatInOrderDto.class); + } + + @Transactional + public EatInOrderDto serve(UUID orderId) { + EatInOrder eatInOrder = eatInOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + eatInOrder.serve(); + return ConvertUtil.convert(eatInOrder, EatInOrderDto.class); + } + + @Transactional + public EatInOrderDto complete(UUID orderId) { + EatInOrder eatInOrder = eatInOrderRepository.findById(orderId) + .orElseThrow(NoSuchElementException::new); + eatInOrder.complete(); + + OrderTable orderTable = orderTableRepository.findById(eatInOrder.getOrderTable().getId()) + .orElseThrow(NoSuchElementException::new); + if (!eatInOrderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) { + orderTable.clear(); + } + return ConvertUtil.convert(eatInOrder, EatInOrderDto.class); + } + + + @Transactional + public List findAll() { + return ConvertUtil.convertList(eatInOrderRepository.findAll(), EatInOrderDto.class); + } + +} diff --git a/src/main/java/kitchenpos/eatinorders/application/OrderService.java b/src/main/java/kitchenpos/eatinorders/application/OrderService.java index c6c02013d..49b911692 100644 --- a/src/main/java/kitchenpos/eatinorders/application/OrderService.java +++ b/src/main/java/kitchenpos/eatinorders/application/OrderService.java @@ -2,6 +2,8 @@ import kitchenpos.deliveryorders.domain.KitchenridersClient; import kitchenpos.eatinorders.domain.*; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; import kitchenpos.menus.tobe.domain.menu.Menu; import kitchenpos.menus.tobe.domain.menu.MenuRepository; import org.springframework.stereotype.Service; @@ -170,8 +172,7 @@ public Order complete(final UUID orderId) { if (type == OrderType.EAT_IN) { final OrderTable orderTable = order.getOrderTable(); if (!orderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) { - orderTable.setNumberOfGuests(0); - orderTable.setOccupied(false); + orderTable.clear(); } } return order; diff --git a/src/main/java/kitchenpos/eatinorders/application/OrderTableService.java b/src/main/java/kitchenpos/eatinorders/application/OrderTableService.java index 1df7e345f..f727483db 100644 --- a/src/main/java/kitchenpos/eatinorders/application/OrderTableService.java +++ b/src/main/java/kitchenpos/eatinorders/application/OrderTableService.java @@ -2,8 +2,13 @@ import kitchenpos.eatinorders.domain.OrderRepository; import kitchenpos.eatinorders.domain.OrderStatus; -import kitchenpos.eatinorders.domain.OrderTable; -import kitchenpos.eatinorders.domain.OrderTableRepository; +import kitchenpos.eatinorders.shared.dto.request.EatInOrderTableChangeNumberOfGuestsRequest; +import kitchenpos.eatinorders.shared.dto.request.OrderTableCreateRequest; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderRepository; +import kitchenpos.eatinorders.tobe.domain.ordertable.NumberOfGuests; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableName; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,24 +20,20 @@ @Service public class OrderTableService { private final OrderTableRepository orderTableRepository; - private final OrderRepository orderRepository; + private final EatInOrderRepository eatInOrderRepository; - public OrderTableService(final OrderTableRepository orderTableRepository, final OrderRepository orderRepository) { + public OrderTableService(OrderTableRepository orderTableRepository, EatInOrderRepository eatInOrderRepository) { this.orderTableRepository = orderTableRepository; - this.orderRepository = orderRepository; + this.eatInOrderRepository = eatInOrderRepository; } @Transactional - public OrderTable create(final OrderTable request) { - final String name = request.getName(); - if (Objects.isNull(name) || name.isEmpty()) { - throw new IllegalArgumentException(); - } - final OrderTable orderTable = new OrderTable(); - orderTable.setId(UUID.randomUUID()); - orderTable.setName(name); - orderTable.setNumberOfGuests(0); - orderTable.setOccupied(false); + public OrderTable create(final OrderTableCreateRequest request) { + final OrderTable orderTable = OrderTable.of( + new OrderTableName(request.getName()), + new NumberOfGuests(0), + false + ); return orderTableRepository.save(orderTable); } @@ -40,7 +41,7 @@ public OrderTable create(final OrderTable request) { public OrderTable sit(final UUID orderTableId) { final OrderTable orderTable = orderTableRepository.findById(orderTableId) .orElseThrow(NoSuchElementException::new); - orderTable.setOccupied(true); + orderTable.sit(); return orderTable; } @@ -48,26 +49,18 @@ public OrderTable sit(final UUID orderTableId) { public OrderTable clear(final UUID orderTableId) { final OrderTable orderTable = orderTableRepository.findById(orderTableId) .orElseThrow(NoSuchElementException::new); - if (orderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) { + if (eatInOrderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) { throw new IllegalStateException(); } - orderTable.setNumberOfGuests(0); - orderTable.setOccupied(false); + orderTable.clear(); return orderTable; } @Transactional - public OrderTable changeNumberOfGuests(final UUID orderTableId, final OrderTable request) { - final int numberOfGuests = request.getNumberOfGuests(); - if (numberOfGuests < 0) { - throw new IllegalArgumentException(); - } + public OrderTable changeNumberOfGuests(final UUID orderTableId, final EatInOrderTableChangeNumberOfGuestsRequest request) { final OrderTable orderTable = orderTableRepository.findById(orderTableId) .orElseThrow(NoSuchElementException::new); - if (!orderTable.isOccupied()) { - throw new IllegalStateException(); - } - orderTable.setNumberOfGuests(numberOfGuests); + orderTable.changeNumberOfGuests(request.getNumberOfGuests()); return orderTable; } diff --git a/src/main/java/kitchenpos/eatinorders/domain/Order.java b/src/main/java/kitchenpos/eatinorders/domain/Order.java index c6e630c90..10116c100 100644 --- a/src/main/java/kitchenpos/eatinorders/domain/Order.java +++ b/src/main/java/kitchenpos/eatinorders/domain/Order.java @@ -1,5 +1,7 @@ package kitchenpos.eatinorders.domain; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; + import javax.persistence.*; import java.time.LocalDateTime; import java.util.List; diff --git a/src/main/java/kitchenpos/eatinorders/domain/OrderRepository.java b/src/main/java/kitchenpos/eatinorders/domain/OrderRepository.java index f98d45c15..e299e592b 100644 --- a/src/main/java/kitchenpos/eatinorders/domain/OrderRepository.java +++ b/src/main/java/kitchenpos/eatinorders/domain/OrderRepository.java @@ -1,5 +1,7 @@ package kitchenpos.eatinorders.domain; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; + import java.util.List; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/kitchenpos/eatinorders/domain/OrderTable.java b/src/main/java/kitchenpos/eatinorders/domain/OrderTable.java deleted file mode 100644 index 9e1dc5519..000000000 --- a/src/main/java/kitchenpos/eatinorders/domain/OrderTable.java +++ /dev/null @@ -1,59 +0,0 @@ -package kitchenpos.eatinorders.domain; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import java.util.UUID; - -@Table(name = "order_table") -@Entity -public class OrderTable { - @Column(name = "id", columnDefinition = "binary(16)") - @Id - private UUID id; - - @Column(name = "name", nullable = false) - private String name; - - @Column(name = "number_of_guests", nullable = false) - private int numberOfGuests; - - @Column(name = "occupied", nullable = false) - private boolean occupied; - - public OrderTable() { - } - - public UUID getId() { - return id; - } - - public void setId(final UUID id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - public int getNumberOfGuests() { - return numberOfGuests; - } - - public void setNumberOfGuests(final int numberOfGuests) { - this.numberOfGuests = numberOfGuests; - } - - public boolean isOccupied() { - return occupied; - } - - public void setOccupied(final boolean occupied) { - this.occupied = occupied; - } -} diff --git a/src/main/java/kitchenpos/eatinorders/infra/EatInMenuClientImpl.java b/src/main/java/kitchenpos/eatinorders/infra/EatInMenuClientImpl.java new file mode 100644 index 000000000..9e5a7e7d1 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/infra/EatInMenuClientImpl.java @@ -0,0 +1,30 @@ +package kitchenpos.eatinorders.infra; + +import kitchenpos.eatinorders.tobe.domain.order.EatInMenuClient; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Service +public class EatInMenuClientImpl implements EatInMenuClient { + + private final MenuRepository menuRepository; + + public EatInMenuClientImpl(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Override + public Optional findById(UUID id) { + return menuRepository.findById(id); + } + + @Override + public List findAllByIdIn(List ids) { + return menuRepository.findAllByIdIn(ids); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/infra/JpaEatInOrderRepositoryImpl.java b/src/main/java/kitchenpos/eatinorders/infra/JpaEatInOrderRepositoryImpl.java new file mode 100644 index 000000000..fdde6f81b --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/infra/JpaEatInOrderRepositoryImpl.java @@ -0,0 +1,11 @@ +package kitchenpos.eatinorders.infra; + +import kitchenpos.eatinorders.tobe.domain.order.EatInOrder; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderRepository; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface JpaEatInOrderRepositoryImpl extends EatInOrderRepository, JpaRepository { + +} diff --git a/src/main/java/kitchenpos/eatinorders/domain/JpaOrderTableRepository.java b/src/main/java/kitchenpos/eatinorders/infra/JpaOrderTableRepository.java similarity index 52% rename from src/main/java/kitchenpos/eatinorders/domain/JpaOrderTableRepository.java rename to src/main/java/kitchenpos/eatinorders/infra/JpaOrderTableRepository.java index 84c0d3c6f..f549aa270 100644 --- a/src/main/java/kitchenpos/eatinorders/domain/JpaOrderTableRepository.java +++ b/src/main/java/kitchenpos/eatinorders/infra/JpaOrderTableRepository.java @@ -1,5 +1,7 @@ -package kitchenpos.eatinorders.domain; +package kitchenpos.eatinorders.infra; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; import org.springframework.data.jpa.repository.JpaRepository; import java.util.UUID; diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderDto.java b/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderDto.java new file mode 100644 index 000000000..69df7fb6b --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderDto.java @@ -0,0 +1,43 @@ +package kitchenpos.eatinorders.shared.dto; + +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.domain.OrderType; +import kitchenpos.eatinorders.shared.dto.EatInOrderLineItemDto; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +public class EatInOrderDto { + private UUID id; + private OrderType type; + private OrderStatus status; + private LocalDateTime orderDateTime; + private List orderLineItems; + + private OrderTableDto orderTable; + + public OrderTableDto getOrderTable() { + return orderTable; + } + + public UUID getId() { + return id; + } + + public OrderType getType() { + return type; + } + + public OrderStatus getStatus() { + return status; + } + + public LocalDateTime getOrderDateTime() { + return orderDateTime; + } + + public List getOrderLineItems() { + return orderLineItems; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java b/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java index 576a3a147..a482f8fc3 100644 --- a/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/EatInOrderLineItemDto.java @@ -1,4 +1,31 @@ package kitchenpos.eatinorders.shared.dto; +import java.math.BigDecimal; +import java.util.UUID; + public class EatInOrderLineItemDto { + private UUID menuId; + private long quantity; + private BigDecimal price; + + protected EatInOrderLineItemDto() { + } + + public EatInOrderLineItemDto(UUID menuId, long quantity, BigDecimal price) { + this.menuId = menuId; + this.quantity = quantity; + this.price = price; + } + + public UUID getMenuId() { + return menuId; + } + + public long getQuantity() { + return quantity; + } + + public BigDecimal getPrice() { + return price; + } } diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/OrderTableDto.java b/src/main/java/kitchenpos/eatinorders/shared/dto/OrderTableDto.java new file mode 100644 index 000000000..bbf31cf1b --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/OrderTableDto.java @@ -0,0 +1,28 @@ +package kitchenpos.eatinorders.shared.dto; + +import java.util.UUID; + +public class OrderTableDto { + private UUID id; + private String name; + private int numberOfGuests; + private boolean occupied; + protected OrderTableDto() { + } + + public UUID getId() { + return id; + } + + public String getName() { + return name; + } + + public int getNumberOfGuests() { + return numberOfGuests; + } + + public boolean isOccupied() { + return occupied; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java b/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java index d8f028120..9bbc27a9e 100644 --- a/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderCreateRequest.java @@ -3,9 +3,22 @@ import kitchenpos.eatinorders.shared.dto.EatInOrderLineItemDto; import java.util.List; +import java.util.UUID; public class EatInOrderCreateRequest { - List orderLineItems; + private List orderLineItems; + private UUID orderTableId; + public EatInOrderCreateRequest(List orderLineItems, UUID orderTableId) { + this.orderLineItems = orderLineItems; + this.orderTableId = orderTableId; + } + public List getOrderLineItems() { + return orderLineItems; + } + + public UUID getOrderTableId() { + return orderTableId; + } } diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderTableChangeNumberOfGuestsRequest.java b/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderTableChangeNumberOfGuestsRequest.java new file mode 100644 index 000000000..5e00a0c70 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/request/EatInOrderTableChangeNumberOfGuestsRequest.java @@ -0,0 +1,13 @@ +package kitchenpos.eatinorders.shared.dto.request; + +public class EatInOrderTableChangeNumberOfGuestsRequest { + private int numberOfGuests; + + public int getNumberOfGuests() { + return numberOfGuests; + } + + public EatInOrderTableChangeNumberOfGuestsRequest(int numberOfGuests) { + this.numberOfGuests = numberOfGuests; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/shared/dto/request/OrderTableCreateRequest.java b/src/main/java/kitchenpos/eatinorders/shared/dto/request/OrderTableCreateRequest.java new file mode 100644 index 000000000..b72716039 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/shared/dto/request/OrderTableCreateRequest.java @@ -0,0 +1,13 @@ +package kitchenpos.eatinorders.shared.dto.request; + +public class OrderTableCreateRequest { + private String name; + + public OrderTableCreateRequest(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInMenuClient.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInMenuClient.java new file mode 100644 index 000000000..b09af2818 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInMenuClient.java @@ -0,0 +1,12 @@ +package kitchenpos.eatinorders.tobe.domain.order; + +import kitchenpos.menus.tobe.domain.menu.Menu; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface EatInMenuClient { + Optional findById(UUID id); + List findAllByIdIn(List ids); +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java new file mode 100644 index 000000000..53e3b8828 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java @@ -0,0 +1,131 @@ +package kitchenpos.eatinorders.tobe.domain.order; + +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.domain.OrderType; +import kitchenpos.menus.tobe.domain.menu.Menu; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Table(name = "eat_in_orders") +@Entity +public class EatInOrder { + @Column(name = "id", columnDefinition = "binary(16)") + @Id + private UUID id; + + @Column(name = "type", nullable = false) + @Enumerated(EnumType.STRING) + private OrderType type; + + @Column(name = "status", nullable = false) + @Enumerated(EnumType.STRING) + private OrderStatus status; + + @Column(name = "order_date_time", nullable = false) + private LocalDateTime orderDateTime; + + @Embedded + private EatInOrderLineItems orderLineItems; + + @ManyToOne + @JoinColumn( + name = "order_table_id", + columnDefinition = "binary(16)", + foreignKey = @ForeignKey(name = "fk_orders_to_order_table") + ) + private OrderTable orderTable; + + protected EatInOrder() { + } + + public EatInOrder(UUID id, OrderType type, OrderStatus status, LocalDateTime orderDateTime, EatInOrderLineItems orderLineItems, OrderTable orderTable) { + this.id = id; + this.type = type; + this.status = status; + this.orderDateTime = orderDateTime; + this.orderLineItems = orderLineItems; + this.orderTable = orderTable; + } + + public static EatInOrder of(EatInOrderLineItems orderLineItems, OrderTable orderTable, EatInMenuClient eatInMenuClient) { + validateEatInOrder(orderLineItems, eatInMenuClient); + validateOrderTable(orderTable); + return new EatInOrder(UUID.randomUUID(), OrderType.EAT_IN, OrderStatus.WAITING, LocalDateTime.now(), orderLineItems, orderTable); + } + + private static void validateOrderTable(OrderTable orderTable) { + if (!orderTable.isOccupied()) { + throw new IllegalStateException(); + } + } + + private static void validateEatInOrder(EatInOrderLineItems orderLineItems, EatInMenuClient eatInMenuClient) { + List menus = eatInMenuClient.findAllByIdIn( + orderLineItems.getOrderLineItems().stream() + .map(EatInOrderLineItem::getMenuId) + .collect(Collectors.toList()) + ); + if (menus.size() != orderLineItems.getOrderLineItems().size()) { + throw new IllegalArgumentException(); + } + } + + public void accept() { + if (status != OrderStatus.WAITING) { + throw new IllegalStateException(); + } + this.status = OrderStatus.ACCEPTED; + } + + public void serve() { + if (status != OrderStatus.ACCEPTED) { + throw new IllegalStateException(); + } + this.status = OrderStatus.SERVED; + } + + public void complete() { + if (status != OrderStatus.ACCEPTED) { + throw new IllegalStateException(); + } + this.status = OrderStatus.COMPLETED; + } + + public UUID getId() { + return id; + } + + public OrderType getType() { + return type; + } + + public OrderStatus getStatus() { + return status; + } + + public LocalDateTime getOrderDateTime() { + return orderDateTime; + } + + public List getOrderLineItems() { + return orderLineItems.getOrderLineItems(); + } + + public OrderTable getOrderTable() { + return orderTable; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItem.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItem.java new file mode 100644 index 000000000..d60f69abb --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItem.java @@ -0,0 +1,88 @@ +package kitchenpos.eatinorders.tobe.domain.order; + +import kitchenpos.menus.tobe.domain.menu.Menu; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.math.BigDecimal; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.UUID; + +@Table(name = "eat_in_order_line_item") +@Entity +public class EatInOrderLineItem { + @Column(name = "seq") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + private Long seq; + + private UUID menuId; + + @Embedded + private EatInOrderLineItemQuantity quantity; + + @Embedded + private EatInOrderLineItemPrice price; + + protected EatInOrderLineItem() { + } + + public EatInOrderLineItem(UUID menuId, EatInOrderLineItemQuantity quantity, EatInOrderLineItemPrice price) { + this.menuId = menuId; + this.quantity = quantity; + this.price = price; + } + + public static EatInOrderLineItem of(UUID menuId, EatInOrderLineItemQuantity quantity, EatInOrderLineItemPrice price, EatInMenuClient eatInMenuClient) { + validateEatInOrderLineItem(menuId, price, eatInMenuClient); + return new EatInOrderLineItem(menuId, quantity, price); + } + + private static void validateEatInOrderLineItem(UUID menuId, EatInOrderLineItemPrice price, EatInMenuClient eatInMenuClient) { + Menu menu = eatInMenuClient.findById(menuId) + .orElseThrow(() -> new NoSuchElementException("메뉴가 존재하지 않습니다. menuId: " + menuId)); + + if (!menu.isDisplayed()) { + throw new IllegalStateException(); + } + + if (menu.getPrice().compareTo(price.getEatInOrderLineItemPrice()) != 0) { + throw new IllegalArgumentException(); + } + } + + public Long getSeq() { + return seq; + } + + public UUID getMenuId() { + return menuId; + } + + public long getQuantity() { + return quantity.getQuantity(); + } + + public BigDecimal getPrice() { + return price.getEatInOrderLineItemPrice(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EatInOrderLineItem that = (EatInOrderLineItem) o; + return Objects.equals(seq, that.seq); + } + + @Override + public int hashCode() { + return Objects.hash(seq); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemPrice.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemPrice.java new file mode 100644 index 000000000..9d5601dfe --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemPrice.java @@ -0,0 +1,36 @@ +package kitchenpos.eatinorders.tobe.domain.order; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.math.BigDecimal; +import java.util.Objects; + +@Embeddable +public class EatInOrderLineItemPrice { + @Column(name = "price", nullable = false) + private BigDecimal eatInOrderLineItemPrice; + + protected EatInOrderLineItemPrice() { + } + + public EatInOrderLineItemPrice(BigDecimal eatInOrderLineItemPrice) { + this.eatInOrderLineItemPrice = eatInOrderLineItemPrice; + } + + public BigDecimal getEatInOrderLineItemPrice() { + return eatInOrderLineItemPrice; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EatInOrderLineItemPrice that = (EatInOrderLineItemPrice) o; + return Objects.equals(eatInOrderLineItemPrice, that.eatInOrderLineItemPrice); + } + + @Override + public int hashCode() { + return Objects.hash(eatInOrderLineItemPrice); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemQuantity.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemQuantity.java new file mode 100644 index 000000000..2d1af56f0 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItemQuantity.java @@ -0,0 +1,35 @@ +package kitchenpos.eatinorders.tobe.domain.order; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.util.Objects; + +@Embeddable +public class EatInOrderLineItemQuantity { + @Column(name = "quantity") + private long quantity; + + protected EatInOrderLineItemQuantity() { + } + + public EatInOrderLineItemQuantity(long quantity) { + this.quantity = quantity; + } + + public long getQuantity() { + return quantity; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EatInOrderLineItemQuantity that = (EatInOrderLineItemQuantity) o; + return quantity == that.quantity; + } + + @Override + public int hashCode() { + return Objects.hash(quantity); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItems.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItems.java new file mode 100644 index 000000000..5009c435c --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderLineItems.java @@ -0,0 +1,31 @@ +package kitchenpos.eatinorders.tobe.domain.order; + +import javax.persistence.CascadeType; +import javax.persistence.Embeddable; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import java.util.List; + +@Embeddable +public class EatInOrderLineItems { + @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @JoinColumn( + name = "order_id", + nullable = false, + columnDefinition = "binary(16)", + foreignKey = @ForeignKey(name = "fk_order_line_item_to_orders") + ) + private List orderLineItems; + + protected EatInOrderLineItems() { + } + + public EatInOrderLineItems(List orderLineItems) { + this.orderLineItems = orderLineItems; + } + + public List getOrderLineItems() { + return orderLineItems; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderRepository.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderRepository.java new file mode 100644 index 000000000..fd5200dd2 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrderRepository.java @@ -0,0 +1,18 @@ +package kitchenpos.eatinorders.tobe.domain.order; + +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface EatInOrderRepository { + EatInOrder save(EatInOrder order); + + Optional findById(UUID id); + + List findAll(); + + boolean existsByOrderTableAndStatusNot(OrderTable orderTable, OrderStatus status); +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/NumberOfGuests.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/NumberOfGuests.java new file mode 100644 index 000000000..b09ba93be --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/NumberOfGuests.java @@ -0,0 +1,42 @@ +package kitchenpos.eatinorders.tobe.domain.ordertable; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.util.Objects; + +@Embeddable +public class NumberOfGuests { + @Column(name = "number_of_guests", nullable = false) + private int numberOfGuests; + + protected NumberOfGuests() { + } + + public NumberOfGuests(int numberOfGuests) { + validateNumberOfGuests(numberOfGuests); + this.numberOfGuests = numberOfGuests; + } + + private void validateNumberOfGuests(int numberOfGuests) { + if (numberOfGuests < 0) { + throw new IllegalArgumentException(); + } + } + + public int getNumberOfGuests() { + return numberOfGuests; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NumberOfGuests that = (NumberOfGuests) o; + return numberOfGuests == that.numberOfGuests; + } + + @Override + public int hashCode() { + return Objects.hash(numberOfGuests); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTable.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTable.java new file mode 100644 index 000000000..0ad3d5ce8 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTable.java @@ -0,0 +1,71 @@ +package kitchenpos.eatinorders.tobe.domain.ordertable; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.UUID; + +@Table(name = "order_table") +@Entity +public class OrderTable { + @Column(name = "id", columnDefinition = "binary(16)") + @Id + private UUID id; + + @Embedded + private OrderTableName name; + + @Embedded + private NumberOfGuests numberOfGuests; + + @Column(name = "occupied", nullable = false) + private boolean occupied; + + protected OrderTable() { + } + + public OrderTable(UUID id, OrderTableName name, NumberOfGuests numberOfGuests, boolean occupied) { + this.id = id; + this.name = name; + this.numberOfGuests = numberOfGuests; + this.occupied = occupied; + } + + public static OrderTable of(OrderTableName name, NumberOfGuests numberOfGuests, boolean occupied) { + return new OrderTable(UUID.randomUUID(), name, numberOfGuests, occupied); + } + + public UUID getId() { + return id; + } + + public String getName() { + return name.getName(); + } + + public int getNumberOfGuests() { + return numberOfGuests.getNumberOfGuests(); + } + + public boolean isOccupied() { + return occupied; + } + + public void clear() { + numberOfGuests = new NumberOfGuests(0); + occupied = false; + } + + public void sit() { + occupied = true; + } + + public void changeNumberOfGuests(int numberOfGuests) { + if (!isOccupied()) { + throw new IllegalStateException(); + } + this.numberOfGuests = new NumberOfGuests(numberOfGuests); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTableName.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTableName.java new file mode 100644 index 000000000..7e23254e5 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTableName.java @@ -0,0 +1,42 @@ +package kitchenpos.eatinorders.tobe.domain.ordertable; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.util.Objects; + +@Embeddable +public class OrderTableName { + @Column(name = "name", nullable = false) + private String name; + + protected OrderTableName() { + } + + public OrderTableName(String name) { + validateOrderTableName(name); + this.name = name; + } + + private void validateOrderTableName(String name) { + if (Objects.isNull(name) || name.isEmpty()) { + throw new IllegalArgumentException(); + } + } + + public String getName() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OrderTableName that = (OrderTableName) o; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/domain/OrderTableRepository.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTableRepository.java similarity index 81% rename from src/main/java/kitchenpos/eatinorders/domain/OrderTableRepository.java rename to src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTableRepository.java index 1e9047d43..a1f0c3625 100644 --- a/src/main/java/kitchenpos/eatinorders/domain/OrderTableRepository.java +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/ordertable/OrderTableRepository.java @@ -1,4 +1,4 @@ -package kitchenpos.eatinorders.domain; +package kitchenpos.eatinorders.tobe.domain.ordertable; import java.util.List; import java.util.Optional; diff --git a/src/main/java/kitchenpos/eatinorders/ui/OrderTableRestController.java b/src/main/java/kitchenpos/eatinorders/ui/OrderTableRestController.java index 120c28d1d..a3983dbf8 100644 --- a/src/main/java/kitchenpos/eatinorders/ui/OrderTableRestController.java +++ b/src/main/java/kitchenpos/eatinorders/ui/OrderTableRestController.java @@ -1,7 +1,9 @@ package kitchenpos.eatinorders.ui; import kitchenpos.eatinorders.application.OrderTableService; -import kitchenpos.eatinorders.domain.OrderTable; +import kitchenpos.eatinorders.shared.dto.request.EatInOrderTableChangeNumberOfGuestsRequest; +import kitchenpos.eatinorders.shared.dto.request.OrderTableCreateRequest; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -19,7 +21,7 @@ public OrderTableRestController(final OrderTableService orderTableService) { } @PostMapping - public ResponseEntity create(@RequestBody final OrderTable request) { + public ResponseEntity create(@RequestBody final OrderTableCreateRequest request) { final OrderTable response = orderTableService.create(request); return ResponseEntity.created(URI.create("/api/order-tables/" + response.getId())) .body(response); @@ -38,7 +40,7 @@ public ResponseEntity clear(@PathVariable final UUID orderTableId) { @PutMapping("/{orderTableId}/number-of-guests") public ResponseEntity changeNumberOfGuests( @PathVariable final UUID orderTableId, - @RequestBody final OrderTable request + @RequestBody final EatInOrderTableChangeNumberOfGuestsRequest request ) { return ResponseEntity.ok(orderTableService.changeNumberOfGuests(orderTableId, request)); } diff --git a/src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java b/src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java index 346e73ab6..1e5a68318 100644 --- a/src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java +++ b/src/main/java/kitchenpos/takeoutorders/domain/TakeOutOrderService.java @@ -5,8 +5,8 @@ import kitchenpos.eatinorders.domain.OrderLineItem; import kitchenpos.eatinorders.domain.OrderRepository; import kitchenpos.eatinorders.domain.OrderStatus; -import kitchenpos.eatinorders.domain.OrderTable; -import kitchenpos.eatinorders.domain.OrderTableRepository; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; import kitchenpos.eatinorders.domain.OrderType; import kitchenpos.menus.tobe.domain.menu.Menu; import kitchenpos.menus.tobe.domain.menu.MenuRepository; @@ -181,8 +181,7 @@ public Order complete(final UUID orderId) { if (type == OrderType.EAT_IN) { final OrderTable orderTable = order.getOrderTable(); if (!orderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) { - orderTable.setNumberOfGuests(0); - orderTable.setOccupied(false); + orderTable.clear(); } } return order; diff --git a/src/test/java/kitchenpos/Fixtures.java b/src/test/java/kitchenpos/Fixtures.java index 528b02fa7..22c22dc0d 100644 --- a/src/test/java/kitchenpos/Fixtures.java +++ b/src/test/java/kitchenpos/Fixtures.java @@ -5,16 +5,22 @@ import kitchenpos.deliveryorders.domain.DeliveryOrderLineItemPrice; import kitchenpos.deliveryorders.domain.DeliveryOrderLineItemQuantity; import kitchenpos.deliveryorders.domain.MenuClient; -import kitchenpos.deliveryorders.infra.MenuClientImpl; import kitchenpos.eatinorders.domain.*; -import kitchenpos.menus.application.InMemoryMenuRepository; +import kitchenpos.eatinorders.tobe.domain.order.EatInMenuClient; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrder; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItem; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItemPrice; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItemQuantity; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItems; +import kitchenpos.eatinorders.tobe.domain.ordertable.NumberOfGuests; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableName; import kitchenpos.menus.tobe.domain.menu.Menu; import kitchenpos.menus.tobe.domain.menu.MenuName; import kitchenpos.menus.tobe.domain.menu.MenuPrice; import kitchenpos.menus.tobe.domain.menu.MenuProductPrice; import kitchenpos.menus.tobe.domain.menu.MenuProductQuantity; import kitchenpos.menus.tobe.domain.menu.MenuProducts; -import kitchenpos.menus.tobe.domain.menu.ProductClient; import kitchenpos.menus.tobe.domain.menugroup.MenuGroup; import kitchenpos.menus.tobe.domain.menu.MenuProduct; import kitchenpos.menus.tobe.domain.menugroup.MenuGroupName; @@ -103,6 +109,10 @@ public static Order order(final OrderStatus status, final OrderTable orderTable) return order; } + public static EatInOrder eatInOrder(final OrderStatus status, final OrderTable orderTable, final Menu menu) { + return new EatInOrder(UUID.randomUUID(), OrderType.EAT_IN, status, LocalDateTime.now(), new EatInOrderLineItems(Arrays.asList(new EatInOrderLineItem(menu.getId(), new EatInOrderLineItemQuantity(1L), new EatInOrderLineItemPrice(BigDecimal.TEN)))), orderTable); + } + public static OrderLineItem orderLineItem() { final OrderLineItem orderLineItem = new OrderLineItem(); orderLineItem.setSeq(new Random().nextLong()); @@ -114,17 +124,20 @@ public static DeliveryOrderLineItem deliveryOrderLineItem(Menu menu, MenuClient return DeliveryOrderLineItem.of(menu.getId(), new DeliveryOrderLineItemQuantity(2L), new DeliveryOrderLineItemPrice(menu.getPrice()), menuClient); } + public static EatInOrderLineItem eatInOrderLineItem(Menu menu, EatInMenuClient menuClient) { + return EatInOrderLineItem.of(menu.getId(), new EatInOrderLineItemQuantity(2L), new EatInOrderLineItemPrice(menu.getPrice()), menuClient); + } + public static OrderTable orderTable() { return orderTable(false, 0); } + public static OrderTable occupiedOrderTable() { + return orderTable(true, 0); + } + public static OrderTable orderTable(final boolean occupied, final int numberOfGuests) { - final OrderTable orderTable = new OrderTable(); - orderTable.setId(UUID.randomUUID()); - orderTable.setName("1번"); - orderTable.setNumberOfGuests(numberOfGuests); - orderTable.setOccupied(occupied); - return orderTable; + return new OrderTable(UUID.randomUUID(), new OrderTableName("1번"), new NumberOfGuests(numberOfGuests), occupied); } public static Product product() { diff --git a/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java b/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java index f0c4202a2..437d4312c 100644 --- a/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java +++ b/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java @@ -104,7 +104,7 @@ void delivery_order_should_contain_delivery_address(String deliveryAddress) { .isInstanceOf(IllegalArgumentException.class); } - @DisplayName("배달 주문은 주소가 필수값이다.") + @DisplayName("배달 주문 메뉴 가격은 주문항목 가격과 같아야 한다.") @Test void menu_price_of_delivery_order_and_order_line_item_price_should_be_same() { //given @@ -159,7 +159,7 @@ void only_delivery_started_order_can_be_complete_delivery() { .isInstanceOf(IllegalStateException.class); } - @DisplayName("배달한 주문만 배달 완료할 수 있다.") + @DisplayName("배달한 주문만 완료할 수 있다.") @Test void only_delivery_completed_order_can_be_complete() { diff --git a/src/test/java/kitchenpos/eatinorders/application/EatInOrderServiceTest.java b/src/test/java/kitchenpos/eatinorders/application/EatInOrderServiceTest.java new file mode 100644 index 000000000..cd6c3e6c5 --- /dev/null +++ b/src/test/java/kitchenpos/eatinorders/application/EatInOrderServiceTest.java @@ -0,0 +1,158 @@ +package kitchenpos.eatinorders.application; + +import kitchenpos.deliveryorders.domain.KitchenridersClient; +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.domain.OrderType; +import kitchenpos.eatinorders.shared.dto.EatInOrderLineItemDto; +import kitchenpos.eatinorders.shared.dto.request.EatInOrderCreateRequest; +import kitchenpos.eatinorders.shared.dto.EatInOrderDto; +import kitchenpos.eatinorders.tobe.domain.order.EatInMenuClient; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrder; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItem; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItems; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderRepository; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; +import kitchenpos.menus.application.InMemoryMenuRepository; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import kitchenpos.products.application.InMemoryProductRepository; +import kitchenpos.products.tobe.domain.Product; +import kitchenpos.products.tobe.domain.ProductRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static kitchenpos.Fixtures.displayedMenu; +import static kitchenpos.Fixtures.eatInOrderLineItem; +import static kitchenpos.Fixtures.menu; +import static kitchenpos.Fixtures.menuProduct; +import static kitchenpos.Fixtures.occupiedOrderTable; +import static kitchenpos.Fixtures.product; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class DeliveryOrderServiceTest { + private EatInOrderRepository eatInOrderRepository; + private EatInMenuClient menuClient; + + private MenuRepository menuRepository; + private ProductRepository productRepository; + + private EatInOrderService eatInOrderService; + private KitchenridersClient kitchenridersClient; + private OrderTableRepository orderTableRepository; + + Menu displayedMenu; + Menu hidedMenu; + Product product; + OrderTable orderTable; + + + @BeforeEach + void setUp() { + eatInOrderRepository = new InMemoryEatInOrderRepository(); + menuRepository = new InMemoryMenuRepository(); + productRepository = new InMemoryProductRepository(); + orderTableRepository = new InMemoryOrderTableRepository(); + kitchenridersClient = new FakeKitchenridersClient(); + product = productRepository.save(product()); + orderTable = orderTableRepository.save(occupiedOrderTable()); + menuClient = new InMemoryEatInMenuClient(menuRepository); + eatInOrderService = new EatInOrderService(eatInOrderRepository, menuRepository, orderTableRepository, menuClient); + displayedMenu = menuRepository.save(displayedMenu(1L, menuProduct(product, 1L))); + hidedMenu = menuRepository.save(menu(1L, menuProduct(product, 1L))); + } + + @DisplayName("매장 주문을 성공한다.") + @Test + void success_create_eat_in_order() { + //given + EatInOrderCreateRequest request = createEatInOrderRequest(List.of(createDisplayedEatInOrderLineItemDto(displayedMenu.getPrice())), orderTable.getId()); + + //when + EatInOrderDto result = eatInOrderService.create(request); + + //then + assertThat(result.getStatus()).isEqualTo(OrderStatus.WAITING); + assertThat(result.getType()).isEqualTo(OrderType.EAT_IN); + assertThat(result.getOrderDateTime()).isNotNull(); + assertThat(result.getOrderTable()).isNotNull(); + } + + @DisplayName("매장 주문을 성공하려면 메뉴가 노출상태여야 한다.") + @Test + void menu_of_eat_in_order_should_be_isDisplayed() { + //given + EatInOrderCreateRequest request = createEatInOrderRequest(List.of(createHidedEatInOrderLineItemDto(displayedMenu.getPrice())), orderTable.getId()); + + //when + assertThatThrownBy(() -> eatInOrderService.create(request)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("매장 주문 메뉴 가격은 주문항목 가격과 같아야 한다.") + @Test + void menu_price_of_eat_in_order_and_order_line_item_price_should_be_same() { + //given + EatInOrderCreateRequest request = createEatInOrderRequest(List.of(createDisplayedEatInOrderLineItemDto(BigDecimal.TEN)), orderTable.getId()); + + //when + assertThatThrownBy(() -> eatInOrderService.create(request)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("접수 대기 중인 주문만 접수할 수 있다.") + @Test + void only_waiting_order_can_be_accept() { + + EatInOrder eatInOrder = new EatInOrder(UUID.randomUUID(), OrderType.EAT_IN, OrderStatus.COMPLETED, LocalDateTime.now(), new EatInOrderLineItems(Arrays.asList(eatInOrderLineItem(displayedMenu, menuClient))), orderTable); + + eatInOrderRepository.save(eatInOrder); + + assertThatThrownBy(() -> eatInOrderService.accept(eatInOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("접수중인 주문만 서빙할 수 있다.") + @Test + void only_accepted_order_can_be_serve() { + + EatInOrder eatInOrder = new EatInOrder(UUID.randomUUID(), OrderType.EAT_IN, OrderStatus.COMPLETED, LocalDateTime.now(), new EatInOrderLineItems(Arrays.asList(eatInOrderLineItem(displayedMenu, menuClient))), orderTable); + + eatInOrderRepository.save(eatInOrder); + + assertThatThrownBy(() -> eatInOrderService.serve(eatInOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("배달한 주문만 배달 완료할 수 있다.") + @Test + void only_delivery_completed_order_can_be_complete() { + + EatInOrder eatInOrder = new EatInOrder(UUID.randomUUID(), OrderType.EAT_IN, OrderStatus.COMPLETED, LocalDateTime.now(), new EatInOrderLineItems(Arrays.asList(eatInOrderLineItem(displayedMenu, menuClient))), orderTable); + + eatInOrderRepository.save(eatInOrder); + + assertThatThrownBy(() -> eatInOrderService.complete(eatInOrder.getId())) + .isInstanceOf(IllegalStateException.class); + } + + private EatInOrderCreateRequest createEatInOrderRequest(List eatInOrderLineItemDtos, UUID orderTableId) { + return new EatInOrderCreateRequest(eatInOrderLineItemDtos, orderTableId); + } + + private EatInOrderLineItemDto createDisplayedEatInOrderLineItemDto(BigDecimal price) { + return new EatInOrderLineItemDto(displayedMenu.getId(), 2, price); + } + + private EatInOrderLineItemDto createHidedEatInOrderLineItemDto(BigDecimal price) { + return new EatInOrderLineItemDto(hidedMenu.getId(), 2, price); + } +} \ No newline at end of file diff --git a/src/test/java/kitchenpos/eatinorders/application/InMemoryEatInMenuClient.java b/src/test/java/kitchenpos/eatinorders/application/InMemoryEatInMenuClient.java new file mode 100644 index 000000000..8c749df25 --- /dev/null +++ b/src/test/java/kitchenpos/eatinorders/application/InMemoryEatInMenuClient.java @@ -0,0 +1,27 @@ +package kitchenpos.eatinorders.application; + +import kitchenpos.eatinorders.tobe.domain.order.EatInMenuClient; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public class InMemoryEatInMenuClient implements EatInMenuClient { + private final MenuRepository menuRepository; + + public InMemoryEatInMenuClient(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Override + public Optional findById(UUID id) { + return menuRepository.findById(id); + } + + @Override + public List findAllByIdIn(List ids) { + return menuRepository.findAllByIdIn(ids); + } +} diff --git a/src/test/java/kitchenpos/eatinorders/application/InMemoryEatInOrderRepository.java b/src/test/java/kitchenpos/eatinorders/application/InMemoryEatInOrderRepository.java new file mode 100644 index 000000000..572c7bf71 --- /dev/null +++ b/src/test/java/kitchenpos/eatinorders/application/InMemoryEatInOrderRepository.java @@ -0,0 +1,40 @@ +package kitchenpos.eatinorders.application; + +import kitchenpos.eatinorders.domain.OrderStatus; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrder; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderRepository; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +public class InMemoryEatInOrderRepository implements EatInOrderRepository { + private final Map orders = new HashMap<>(); + + @Override + public EatInOrder save(final EatInOrder order) { + orders.put(order.getId(), order); + return order; + } + + @Override + public Optional findById(final UUID id) { + return Optional.ofNullable(orders.get(id)); + } + + @Override + public List findAll() { + return new ArrayList<>(orders.values()); + } + + @Override + public boolean existsByOrderTableAndStatusNot(final OrderTable orderTable, final OrderStatus status) { + return orders.values() + .stream() + .anyMatch(order -> order.getOrderTable().equals(orderTable) && order.getStatus() != status); + } +} diff --git a/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderRepository.java b/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderRepository.java index 38d22969c..a1daacf26 100644 --- a/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderRepository.java +++ b/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderRepository.java @@ -3,7 +3,7 @@ import kitchenpos.eatinorders.domain.Order; import kitchenpos.eatinorders.domain.OrderRepository; import kitchenpos.eatinorders.domain.OrderStatus; -import kitchenpos.eatinorders.domain.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; import java.util.*; diff --git a/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderTableRepository.java b/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderTableRepository.java index 1aa4febce..b4626ea91 100644 --- a/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderTableRepository.java +++ b/src/test/java/kitchenpos/eatinorders/application/InMemoryOrderTableRepository.java @@ -1,7 +1,7 @@ package kitchenpos.eatinorders.application; -import kitchenpos.eatinorders.domain.OrderTable; -import kitchenpos.eatinorders.domain.OrderTableRepository; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; import java.util.*; diff --git a/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java b/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java index 61ee2ab29..4618817bf 100644 --- a/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java +++ b/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java @@ -1,377 +1,379 @@ -package kitchenpos.eatinorders.application; - -import kitchenpos.eatinorders.domain.*; -import kitchenpos.menus.application.InMemoryMenuRepository; -import kitchenpos.menus.tobe.domain.menu.MenuRepository; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.*; - -import java.math.BigDecimal; -import java.util.*; - -import static kitchenpos.Fixtures.*; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -class OrderServiceTest { - private OrderRepository orderRepository; - private MenuRepository menuRepository; - private OrderTableRepository orderTableRepository; - private FakeKitchenridersClient kitchenridersClient; - private OrderService orderService; - - @BeforeEach - void setUp() { - orderRepository = new InMemoryOrderRepository(); - menuRepository = new InMemoryMenuRepository(); - orderTableRepository = new InMemoryOrderTableRepository(); - kitchenridersClient = new FakeKitchenridersClient(); - orderService = new OrderService(orderRepository, menuRepository, orderTableRepository, kitchenridersClient); - } - - @DisplayName("1개 이상의 등록된 메뉴로 배달 주문을 등록할 수 있다.") - @Test - void createDeliveryOrder() { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final Order expected = createOrderRequest( - OrderType.DELIVERY, "서울시 송파구 위례성대로 2", createOrderLineItemRequest(menuId, 19_000L, 3L) - ); - final Order actual = orderService.create(expected); - assertThat(actual).isNotNull(); - assertAll( - () -> assertThat(actual.getId()).isNotNull(), - () -> assertThat(actual.getType()).isEqualTo(expected.getType()), - () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.WAITING), - () -> assertThat(actual.getOrderDateTime()).isNotNull(), - () -> assertThat(actual.getOrderLineItems()).hasSize(1), - () -> assertThat(actual.getDeliveryAddress()).isEqualTo(expected.getDeliveryAddress()) - ); - } - - @DisplayName("1개 이상의 등록된 메뉴로 포장 주문을 등록할 수 있다.") - @Test - void createTakeoutOrder() { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final Order expected = createOrderRequest(OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 19_000L, 3L)); - final Order actual = orderService.create(expected); - assertThat(actual).isNotNull(); - assertAll( - () -> assertThat(actual.getId()).isNotNull(), - () -> assertThat(actual.getType()).isEqualTo(expected.getType()), - () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.WAITING), - () -> assertThat(actual.getOrderDateTime()).isNotNull(), - () -> assertThat(actual.getOrderLineItems()).hasSize(1) - ); - } - - @DisplayName("1개 이상의 등록된 메뉴로 매장 주문을 등록할 수 있다.") - @Test - void createEatInOrder() { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final UUID orderTableId = orderTableRepository.save(orderTable(true, 4)).getId(); - final Order expected = createOrderRequest(OrderType.EAT_IN, orderTableId, createOrderLineItemRequest(menuId, 19_000L, 3L)); - final Order actual = orderService.create(expected); - assertThat(actual).isNotNull(); - assertAll( - () -> assertThat(actual.getId()).isNotNull(), - () -> assertThat(actual.getType()).isEqualTo(expected.getType()), - () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.WAITING), - () -> assertThat(actual.getOrderDateTime()).isNotNull(), - () -> assertThat(actual.getOrderLineItems()).hasSize(1), - () -> assertThat(actual.getOrderTable().getId()).isEqualTo(expected.getOrderTableId()) - ); - } - - @DisplayName("주문 유형이 올바르지 않으면 등록할 수 없다.") - @NullSource - @ParameterizedTest - void create(final OrderType type) { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final Order expected = createOrderRequest(type, createOrderLineItemRequest(menuId, 19_000L, 3L)); - assertThatThrownBy(() -> orderService.create(expected)) - .isInstanceOf(IllegalArgumentException.class); - } - - @DisplayName("메뉴가 없으면 등록할 수 없다.") - @MethodSource("orderLineItems") - @ParameterizedTest - void create(final List orderLineItems) { - final Order expected = createOrderRequest(OrderType.TAKEOUT, orderLineItems); - assertThatThrownBy(() -> orderService.create(expected)) - .isInstanceOf(IllegalArgumentException.class); - } - - private static List orderLineItems() { - return Arrays.asList( - null, - Arguments.of(Collections.emptyList()), - Arguments.of(Arrays.asList(createOrderLineItemRequest(INVALID_ID, 19_000L, 3L))) - ); - } - - @DisplayName("매장 주문은 주문 항목의 수량이 0 미만일 수 있다.") - @ValueSource(longs = -1L) - @ParameterizedTest - void createEatInOrder(final long quantity) { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final UUID orderTableId = orderTableRepository.save(orderTable(true, 4)).getId(); - final Order expected = createOrderRequest( - OrderType.EAT_IN, orderTableId, createOrderLineItemRequest(menuId, 19_000L, quantity) - ); - assertDoesNotThrow(() -> orderService.create(expected)); - } - - @DisplayName("매장 주문을 제외한 주문의 경우 주문 항목의 수량은 0 이상이어야 한다.") - @ValueSource(longs = -1L) - @ParameterizedTest - void createWithoutEatInOrder(final long quantity) { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final Order expected = createOrderRequest( - OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 19_000L, quantity) - ); - assertThatThrownBy(() -> orderService.create(expected)) - .isInstanceOf(IllegalArgumentException.class); - } - - @DisplayName("배달 주소가 올바르지 않으면 배달 주문을 등록할 수 없다.") - @NullAndEmptySource - @ParameterizedTest - void create(final String deliveryAddress) { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final Order expected = createOrderRequest( - OrderType.DELIVERY, deliveryAddress, createOrderLineItemRequest(menuId, 19_000L, 3L) - ); - assertThatThrownBy(() -> orderService.create(expected)) - .isInstanceOf(IllegalArgumentException.class); - } - - @DisplayName("빈 테이블에는 매장 주문을 등록할 수 없다.") - @Test - void createEmptyTableEatInOrder() { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final UUID orderTableId = orderTableRepository.save(orderTable(false, 0)).getId(); - final Order expected = createOrderRequest( - OrderType.EAT_IN, orderTableId, createOrderLineItemRequest(menuId, 19_000L, 3L) - ); - assertThatThrownBy(() -> orderService.create(expected)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("숨겨진 메뉴는 주문할 수 없다.") - @Test - void createNotDisplayedMenuOrder() { - final UUID menuId = menuRepository.save(menu(19_000L, false, menuProduct())).getId(); - final Order expected = createOrderRequest(OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 19_000L, 3L)); - assertThatThrownBy(() -> orderService.create(expected)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("주문한 메뉴의 가격은 실제 메뉴 가격과 일치해야 한다.") - @Test - void createNotMatchedMenuPriceOrder() { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); - final Order expected = createOrderRequest(OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 16_000L, 3L)); - assertThatThrownBy(() -> orderService.create(expected)) - .isInstanceOf(IllegalArgumentException.class); - } - - @DisplayName("주문을 접수한다.") - @Test - void accept() { - final UUID orderId = orderRepository.save(order(OrderStatus.WAITING, orderTable(true, 4))).getId(); - final Order actual = orderService.accept(orderId); - assertThat(actual.getStatus()).isEqualTo(OrderStatus.ACCEPTED); - } - - @DisplayName("접수 대기 중인 주문만 접수할 수 있다.") - @EnumSource(value = OrderStatus.class, names = "WAITING", mode = EnumSource.Mode.EXCLUDE) - @ParameterizedTest - void accept(final OrderStatus status) { - final UUID orderId = orderRepository.save(order(status, orderTable(true, 4))).getId(); - assertThatThrownBy(() -> orderService.accept(orderId)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("배달 주문을 접수되면 배달 대행사를 호출한다.") - @Test - void acceptDeliveryOrder() { - final UUID orderId = orderRepository.save(order(OrderStatus.WAITING, "서울시 송파구 위례성대로 2")).getId(); - final Order actual = orderService.accept(orderId); - assertAll( - () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.ACCEPTED), - () -> assertThat(kitchenridersClient.getOrderId()).isEqualTo(orderId), - () -> assertThat(kitchenridersClient.getDeliveryAddress()).isEqualTo("서울시 송파구 위례성대로 2") - ); - } - - @DisplayName("주문을 서빙한다.") - @Test - void serve() { - final UUID orderId = orderRepository.save(order(OrderStatus.ACCEPTED)).getId(); - final Order actual = orderService.serve(orderId); - assertThat(actual.getStatus()).isEqualTo(OrderStatus.SERVED); - } - - @DisplayName("접수된 주문만 서빙할 수 있다.") - @EnumSource(value = OrderStatus.class, names = "ACCEPTED", mode = EnumSource.Mode.EXCLUDE) - @ParameterizedTest - void serve(final OrderStatus status) { - final UUID orderId = orderRepository.save(order(status)).getId(); - assertThatThrownBy(() -> orderService.serve(orderId)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("주문을 배달한다.") - @Test - void startDelivery() { - final UUID orderId = orderRepository.save(order(OrderStatus.SERVED, "서울시 송파구 위례성대로 2")).getId(); - final Order actual = orderService.startDelivery(orderId); - assertThat(actual.getStatus()).isEqualTo(OrderStatus.DELIVERING); - } - - @DisplayName("배달 주문만 배달할 수 있다.") - @Test - void startDeliveryWithoutDeliveryOrder() { - final UUID orderId = orderRepository.save(order(OrderStatus.SERVED)).getId(); - assertThatThrownBy(() -> orderService.startDelivery(orderId)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("서빙된 주문만 배달할 수 있다.") - @EnumSource(value = OrderStatus.class, names = "SERVED", mode = EnumSource.Mode.EXCLUDE) - @ParameterizedTest - void startDelivery(final OrderStatus status) { - final UUID orderId = orderRepository.save(order(status, "서울시 송파구 위례성대로 2")).getId(); - assertThatThrownBy(() -> orderService.startDelivery(orderId)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("주문을 배달 완료한다.") - @Test - void completeDelivery() { - final UUID orderId = orderRepository.save(order(OrderStatus.DELIVERING, "서울시 송파구 위례성대로 2")).getId(); - final Order actual = orderService.completeDelivery(orderId); - assertThat(actual.getStatus()).isEqualTo(OrderStatus.DELIVERED); - } - - @DisplayName("배달 중인 주문만 배달 완료할 수 있다.") - @EnumSource(value = OrderStatus.class, names = "DELIVERING", mode = EnumSource.Mode.EXCLUDE) - @ParameterizedTest - void completeDelivery(final OrderStatus status) { - final UUID orderId = orderRepository.save(order(status, "서울시 송파구 위례성대로 2")).getId(); - assertThatThrownBy(() -> orderService.completeDelivery(orderId)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("주문을 완료한다.") - @Test - void complete() { - final Order expected = orderRepository.save(order(OrderStatus.DELIVERED, "서울시 송파구 위례성대로 2")); - final Order actual = orderService.complete(expected.getId()); - assertThat(actual.getStatus()).isEqualTo(OrderStatus.COMPLETED); - } - - @DisplayName("배달 주문의 경우 배달 완료된 주문만 완료할 수 있다.") - @EnumSource(value = OrderStatus.class, names = "DELIVERED", mode = EnumSource.Mode.EXCLUDE) - @ParameterizedTest - void completeDeliveryOrder(final OrderStatus status) { - final UUID orderId = orderRepository.save(order(status, "서울시 송파구 위례성대로 2")).getId(); - assertThatThrownBy(() -> orderService.complete(orderId)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("포장 및 매장 주문의 경우 서빙된 주문만 완료할 수 있다.") - @EnumSource(value = OrderStatus.class, names = "SERVED", mode = EnumSource.Mode.EXCLUDE) - @ParameterizedTest - void completeTakeoutAndEatInOrder(final OrderStatus status) { - final UUID orderId = orderRepository.save(order(status)).getId(); - assertThatThrownBy(() -> orderService.complete(orderId)) - .isInstanceOf(IllegalStateException.class); - } - - @DisplayName("주문 테이블의 모든 매장 주문이 완료되면 빈 테이블로 설정한다.") - @Test - void completeEatInOrder() { - final OrderTable orderTable = orderTableRepository.save(orderTable(true, 4)); - final Order expected = orderRepository.save(order(OrderStatus.SERVED, orderTable)); - final Order actual = orderService.complete(expected.getId()); - assertAll( - () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.COMPLETED), - () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().isOccupied()).isFalse(), - () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().getNumberOfGuests()).isEqualTo(0) - ); - } - - @DisplayName("완료되지 않은 매장 주문이 있는 주문 테이블은 빈 테이블로 설정하지 않는다.") - @Test - void completeNotTable() { - final OrderTable orderTable = orderTableRepository.save(orderTable(true, 4)); - orderRepository.save(order(OrderStatus.ACCEPTED, orderTable)); - final Order expected = orderRepository.save(order(OrderStatus.SERVED, orderTable)); - final Order actual = orderService.complete(expected.getId()); - assertAll( - () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.COMPLETED), - () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().isOccupied()).isTrue(), - () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().getNumberOfGuests()).isEqualTo(4) - ); - } - - @DisplayName("주문의 목록을 조회할 수 있다.") - @Test - void findAll() { - final OrderTable orderTable = orderTableRepository.save(orderTable(true, 4)); - orderRepository.save(order(OrderStatus.SERVED, orderTable)); - orderRepository.save(order(OrderStatus.DELIVERED, "서울시 송파구 위례성대로 2")); - final List actual = orderService.findAll(); - assertThat(actual).hasSize(2); - } - - private Order createOrderRequest( - final OrderType type, - final String deliveryAddress, - final OrderLineItem... orderLineItems - ) { - final Order order = new Order(); - order.setType(type); - order.setDeliveryAddress(deliveryAddress); - order.setOrderLineItems(Arrays.asList(orderLineItems)); - return order; - } - - private Order createOrderRequest(final OrderType orderType, final OrderLineItem... orderLineItems) { - return createOrderRequest(orderType, Arrays.asList(orderLineItems)); - } - - private Order createOrderRequest(final OrderType orderType, final List orderLineItems) { - final Order order = new Order(); - order.setType(orderType); - order.setOrderLineItems(orderLineItems); - return order; - } - - private Order createOrderRequest( - final OrderType type, - final UUID orderTableId, - final OrderLineItem... orderLineItems - ) { - final Order order = new Order(); - order.setType(type); - order.setOrderTableId(orderTableId); - order.setOrderLineItems(Arrays.asList(orderLineItems)); - return order; - } - - private static OrderLineItem createOrderLineItemRequest(final UUID menuId, final long price, final long quantity) { - final OrderLineItem orderLineItem = new OrderLineItem(); - orderLineItem.setSeq(new Random().nextLong()); - orderLineItem.setMenuId(menuId); - orderLineItem.setPrice(BigDecimal.valueOf(price)); - orderLineItem.setQuantity(quantity); - return orderLineItem; - } -} +//package kitchenpos.eatinorders.application; +// +//import kitchenpos.eatinorders.domain.*; +//import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +//import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; +//import kitchenpos.menus.application.InMemoryMenuRepository; +//import kitchenpos.menus.tobe.domain.menu.MenuRepository; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.DisplayName; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.*; +// +//import java.math.BigDecimal; +//import java.util.*; +// +//import static kitchenpos.Fixtures.*; +//import static org.assertj.core.api.Assertions.assertThat; +//import static org.assertj.core.api.Assertions.assertThatThrownBy; +//import static org.junit.jupiter.api.Assertions.assertAll; +//import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +// +//class OrderServiceTest { +// private OrderRepository orderRepository; +// private MenuRepository menuRepository; +// private OrderTableRepository orderTableRepository; +// private FakeKitchenridersClient kitchenridersClient; +// private OrderService orderService; +// +// @BeforeEach +// void setUp() { +// orderRepository = new InMemoryOrderRepository(); +// menuRepository = new InMemoryMenuRepository(); +// orderTableRepository = new InMemoryOrderTableRepository(); +// kitchenridersClient = new FakeKitchenridersClient(); +// orderService = new OrderService(orderRepository, menuRepository, orderTableRepository, kitchenridersClient); +// } +// +// @DisplayName("1개 이상의 등록된 메뉴로 배달 주문을 등록할 수 있다.") +// @Test +// void createDeliveryOrder() { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final Order expected = createOrderRequest( +// OrderType.DELIVERY, "서울시 송파구 위례성대로 2", createOrderLineItemRequest(menuId, 19_000L, 3L) +// ); +// final Order actual = orderService.create(expected); +// assertThat(actual).isNotNull(); +// assertAll( +// () -> assertThat(actual.getId()).isNotNull(), +// () -> assertThat(actual.getType()).isEqualTo(expected.getType()), +// () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.WAITING), +// () -> assertThat(actual.getOrderDateTime()).isNotNull(), +// () -> assertThat(actual.getOrderLineItems()).hasSize(1), +// () -> assertThat(actual.getDeliveryAddress()).isEqualTo(expected.getDeliveryAddress()) +// ); +// } +// +// @DisplayName("1개 이상의 등록된 메뉴로 포장 주문을 등록할 수 있다.") +// @Test +// void createTakeoutOrder() { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final Order expected = createOrderRequest(OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 19_000L, 3L)); +// final Order actual = orderService.create(expected); +// assertThat(actual).isNotNull(); +// assertAll( +// () -> assertThat(actual.getId()).isNotNull(), +// () -> assertThat(actual.getType()).isEqualTo(expected.getType()), +// () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.WAITING), +// () -> assertThat(actual.getOrderDateTime()).isNotNull(), +// () -> assertThat(actual.getOrderLineItems()).hasSize(1) +// ); +// } +// +// @DisplayName("1개 이상의 등록된 메뉴로 매장 주문을 등록할 수 있다.") +// @Test +// void createEatInOrder() { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final UUID orderTableId = orderTableRepository.save(orderTable(true, 4)).getId(); +// final Order expected = createOrderRequest(OrderType.EAT_IN, orderTableId, createOrderLineItemRequest(menuId, 19_000L, 3L)); +// final Order actual = orderService.create(expected); +// assertThat(actual).isNotNull(); +// assertAll( +// () -> assertThat(actual.getId()).isNotNull(), +// () -> assertThat(actual.getType()).isEqualTo(expected.getType()), +// () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.WAITING), +// () -> assertThat(actual.getOrderDateTime()).isNotNull(), +// () -> assertThat(actual.getOrderLineItems()).hasSize(1), +// () -> assertThat(actual.getOrderTable().getId()).isEqualTo(expected.getOrderTableId()) +// ); +// } +// +// @DisplayName("주문 유형이 올바르지 않으면 등록할 수 없다.") +// @NullSource +// @ParameterizedTest +// void create(final OrderType type) { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final Order expected = createOrderRequest(type, createOrderLineItemRequest(menuId, 19_000L, 3L)); +// assertThatThrownBy(() -> orderService.create(expected)) +// .isInstanceOf(IllegalArgumentException.class); +// } +// +// @DisplayName("메뉴가 없으면 등록할 수 없다.") +// @MethodSource("orderLineItems") +// @ParameterizedTest +// void create(final List orderLineItems) { +// final Order expected = createOrderRequest(OrderType.TAKEOUT, orderLineItems); +// assertThatThrownBy(() -> orderService.create(expected)) +// .isInstanceOf(IllegalArgumentException.class); +// } +// +// private static List orderLineItems() { +// return Arrays.asList( +// null, +// Arguments.of(Collections.emptyList()), +// Arguments.of(Arrays.asList(createOrderLineItemRequest(INVALID_ID, 19_000L, 3L))) +// ); +// } +// +// @DisplayName("매장 주문은 주문 항목의 수량이 0 미만일 수 있다.") +// @ValueSource(longs = -1L) +// @ParameterizedTest +// void createEatInOrder(final long quantity) { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final UUID orderTableId = orderTableRepository.save(orderTable(true, 4)).getId(); +// final Order expected = createOrderRequest( +// OrderType.EAT_IN, orderTableId, createOrderLineItemRequest(menuId, 19_000L, quantity) +// ); +// assertDoesNotThrow(() -> orderService.create(expected)); +// } +// +// @DisplayName("매장 주문을 제외한 주문의 경우 주문 항목의 수량은 0 이상이어야 한다.") +// @ValueSource(longs = -1L) +// @ParameterizedTest +// void createWithoutEatInOrder(final long quantity) { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final Order expected = createOrderRequest( +// OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 19_000L, quantity) +// ); +// assertThatThrownBy(() -> orderService.create(expected)) +// .isInstanceOf(IllegalArgumentException.class); +// } +// +// @DisplayName("배달 주소가 올바르지 않으면 배달 주문을 등록할 수 없다.") +// @NullAndEmptySource +// @ParameterizedTest +// void create(final String deliveryAddress) { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final Order expected = createOrderRequest( +// OrderType.DELIVERY, deliveryAddress, createOrderLineItemRequest(menuId, 19_000L, 3L) +// ); +// assertThatThrownBy(() -> orderService.create(expected)) +// .isInstanceOf(IllegalArgumentException.class); +// } +// +// @DisplayName("빈 테이블에는 매장 주문을 등록할 수 없다.") +// @Test +// void createEmptyTableEatInOrder() { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final UUID orderTableId = orderTableRepository.save(orderTable(false, 0)).getId(); +// final Order expected = createOrderRequest( +// OrderType.EAT_IN, orderTableId, createOrderLineItemRequest(menuId, 19_000L, 3L) +// ); +// assertThatThrownBy(() -> orderService.create(expected)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("숨겨진 메뉴는 주문할 수 없다.") +// @Test +// void createNotDisplayedMenuOrder() { +// final UUID menuId = menuRepository.save(menu(19_000L, false, menuProduct())).getId(); +// final Order expected = createOrderRequest(OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 19_000L, 3L)); +// assertThatThrownBy(() -> orderService.create(expected)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("주문한 메뉴의 가격은 실제 메뉴 가격과 일치해야 한다.") +// @Test +// void createNotMatchedMenuPriceOrder() { +// final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct())).getId(); +// final Order expected = createOrderRequest(OrderType.TAKEOUT, createOrderLineItemRequest(menuId, 16_000L, 3L)); +// assertThatThrownBy(() -> orderService.create(expected)) +// .isInstanceOf(IllegalArgumentException.class); +// } +// +// @DisplayName("주문을 접수한다.") +// @Test +// void accept() { +// final UUID orderId = orderRepository.save(order(OrderStatus.WAITING, orderTable(true, 4))).getId(); +// final Order actual = orderService.accept(orderId); +// assertThat(actual.getStatus()).isEqualTo(OrderStatus.ACCEPTED); +// } +// +// @DisplayName("접수 대기 중인 주문만 접수할 수 있다.") +// @EnumSource(value = OrderStatus.class, names = "WAITING", mode = EnumSource.Mode.EXCLUDE) +// @ParameterizedTest +// void accept(final OrderStatus status) { +// final UUID orderId = orderRepository.save(order(status, orderTable(true, 4))).getId(); +// assertThatThrownBy(() -> orderService.accept(orderId)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("배달 주문을 접수되면 배달 대행사를 호출한다.") +// @Test +// void acceptDeliveryOrder() { +// final UUID orderId = orderRepository.save(order(OrderStatus.WAITING, "서울시 송파구 위례성대로 2")).getId(); +// final Order actual = orderService.accept(orderId); +// assertAll( +// () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.ACCEPTED), +// () -> assertThat(kitchenridersClient.getOrderId()).isEqualTo(orderId), +// () -> assertThat(kitchenridersClient.getDeliveryAddress()).isEqualTo("서울시 송파구 위례성대로 2") +// ); +// } +// +// @DisplayName("주문을 서빙한다.") +// @Test +// void serve() { +// final UUID orderId = orderRepository.save(order(OrderStatus.ACCEPTED)).getId(); +// final Order actual = orderService.serve(orderId); +// assertThat(actual.getStatus()).isEqualTo(OrderStatus.SERVED); +// } +// +// @DisplayName("접수된 주문만 서빙할 수 있다.") +// @EnumSource(value = OrderStatus.class, names = "ACCEPTED", mode = EnumSource.Mode.EXCLUDE) +// @ParameterizedTest +// void serve(final OrderStatus status) { +// final UUID orderId = orderRepository.save(order(status)).getId(); +// assertThatThrownBy(() -> orderService.serve(orderId)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("주문을 배달한다.") +// @Test +// void startDelivery() { +// final UUID orderId = orderRepository.save(order(OrderStatus.SERVED, "서울시 송파구 위례성대로 2")).getId(); +// final Order actual = orderService.startDelivery(orderId); +// assertThat(actual.getStatus()).isEqualTo(OrderStatus.DELIVERING); +// } +// +// @DisplayName("배달 주문만 배달할 수 있다.") +// @Test +// void startDeliveryWithoutDeliveryOrder() { +// final UUID orderId = orderRepository.save(order(OrderStatus.SERVED)).getId(); +// assertThatThrownBy(() -> orderService.startDelivery(orderId)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("서빙된 주문만 배달할 수 있다.") +// @EnumSource(value = OrderStatus.class, names = "SERVED", mode = EnumSource.Mode.EXCLUDE) +// @ParameterizedTest +// void startDelivery(final OrderStatus status) { +// final UUID orderId = orderRepository.save(order(status, "서울시 송파구 위례성대로 2")).getId(); +// assertThatThrownBy(() -> orderService.startDelivery(orderId)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("주문을 배달 완료한다.") +// @Test +// void completeDelivery() { +// final UUID orderId = orderRepository.save(order(OrderStatus.DELIVERING, "서울시 송파구 위례성대로 2")).getId(); +// final Order actual = orderService.completeDelivery(orderId); +// assertThat(actual.getStatus()).isEqualTo(OrderStatus.DELIVERED); +// } +// +// @DisplayName("배달 중인 주문만 배달 완료할 수 있다.") +// @EnumSource(value = OrderStatus.class, names = "DELIVERING", mode = EnumSource.Mode.EXCLUDE) +// @ParameterizedTest +// void completeDelivery(final OrderStatus status) { +// final UUID orderId = orderRepository.save(order(status, "서울시 송파구 위례성대로 2")).getId(); +// assertThatThrownBy(() -> orderService.completeDelivery(orderId)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("주문을 완료한다.") +// @Test +// void complete() { +// final Order expected = orderRepository.save(order(OrderStatus.DELIVERED, "서울시 송파구 위례성대로 2")); +// final Order actual = orderService.complete(expected.getId()); +// assertThat(actual.getStatus()).isEqualTo(OrderStatus.COMPLETED); +// } +// +// @DisplayName("배달 주문의 경우 배달 완료된 주문만 완료할 수 있다.") +// @EnumSource(value = OrderStatus.class, names = "DELIVERED", mode = EnumSource.Mode.EXCLUDE) +// @ParameterizedTest +// void completeDeliveryOrder(final OrderStatus status) { +// final UUID orderId = orderRepository.save(order(status, "서울시 송파구 위례성대로 2")).getId(); +// assertThatThrownBy(() -> orderService.complete(orderId)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("포장 및 매장 주문의 경우 서빙된 주문만 완료할 수 있다.") +// @EnumSource(value = OrderStatus.class, names = "SERVED", mode = EnumSource.Mode.EXCLUDE) +// @ParameterizedTest +// void completeTakeoutAndEatInOrder(final OrderStatus status) { +// final UUID orderId = orderRepository.save(order(status)).getId(); +// assertThatThrownBy(() -> orderService.complete(orderId)) +// .isInstanceOf(IllegalStateException.class); +// } +// +// @DisplayName("주문 테이블의 모든 매장 주문이 완료되면 빈 테이블로 설정한다.") +// @Test +// void completeEatInOrder() { +// final OrderTable orderTable = orderTableRepository.save(orderTable(true, 4)); +// final Order expected = orderRepository.save(order(OrderStatus.SERVED, orderTable)); +// final Order actual = orderService.complete(expected.getId()); +// assertAll( +// () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.COMPLETED), +// () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().isOccupied()).isFalse(), +// () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().getNumberOfGuests()).isEqualTo(0) +// ); +// } +// +// @DisplayName("완료되지 않은 매장 주문이 있는 주문 테이블은 빈 테이블로 설정하지 않는다.") +// @Test +// void completeNotTable() { +// final OrderTable orderTable = orderTableRepository.save(orderTable(true, 4)); +// orderRepository.save(order(OrderStatus.ACCEPTED, orderTable)); +// final Order expected = orderRepository.save(order(OrderStatus.SERVED, orderTable)); +// final Order actual = orderService.complete(expected.getId()); +// assertAll( +// () -> assertThat(actual.getStatus()).isEqualTo(OrderStatus.COMPLETED), +// () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().isOccupied()).isTrue(), +// () -> assertThat(orderTableRepository.findById(orderTable.getId()).get().getNumberOfGuests()).isEqualTo(4) +// ); +// } +// +// @DisplayName("주문의 목록을 조회할 수 있다.") +// @Test +// void findAll() { +// final OrderTable orderTable = orderTableRepository.save(orderTable(true, 4)); +// orderRepository.save(order(OrderStatus.SERVED, orderTable)); +// orderRepository.save(order(OrderStatus.DELIVERED, "서울시 송파구 위례성대로 2")); +// final List actual = orderService.findAll(); +// assertThat(actual).hasSize(2); +// } +// +// private Order createOrderRequest( +// final OrderType type, +// final String deliveryAddress, +// final OrderLineItem... orderLineItems +// ) { +// final Order order = new Order(); +// order.setType(type); +// order.setDeliveryAddress(deliveryAddress); +// order.setOrderLineItems(Arrays.asList(orderLineItems)); +// return order; +// } +// +// private Order createOrderRequest(final OrderType orderType, final OrderLineItem... orderLineItems) { +// return createOrderRequest(orderType, Arrays.asList(orderLineItems)); +// } +// +// private Order createOrderRequest(final OrderType orderType, final List orderLineItems) { +// final Order order = new Order(); +// order.setType(orderType); +// order.setOrderLineItems(orderLineItems); +// return order; +// } +// +// private Order createOrderRequest( +// final OrderType type, +// final UUID orderTableId, +// final OrderLineItem... orderLineItems +// ) { +// final Order order = new Order(); +// order.setType(type); +// order.setOrderTableId(orderTableId); +// order.setOrderLineItems(Arrays.asList(orderLineItems)); +// return order; +// } +// +// private static OrderLineItem createOrderLineItemRequest(final UUID menuId, final long price, final long quantity) { +// final OrderLineItem orderLineItem = new OrderLineItem(); +// orderLineItem.setSeq(new Random().nextLong()); +// orderLineItem.setMenuId(menuId); +// orderLineItem.setPrice(BigDecimal.valueOf(price)); +// orderLineItem.setQuantity(quantity); +// return orderLineItem; +// } +//} diff --git a/src/test/java/kitchenpos/eatinorders/application/OrderTableServiceTest.java b/src/test/java/kitchenpos/eatinorders/application/OrderTableServiceTest.java index 01551a8d4..91fad8907 100644 --- a/src/test/java/kitchenpos/eatinorders/application/OrderTableServiceTest.java +++ b/src/test/java/kitchenpos/eatinorders/application/OrderTableServiceTest.java @@ -1,9 +1,25 @@ package kitchenpos.eatinorders.application; +import kitchenpos.deliveryorders.application.InMemoryMenuClient; +import kitchenpos.deliveryorders.domain.MenuClient; import kitchenpos.eatinorders.domain.OrderRepository; import kitchenpos.eatinorders.domain.OrderStatus; -import kitchenpos.eatinorders.domain.OrderTable; -import kitchenpos.eatinorders.domain.OrderTableRepository; +import kitchenpos.eatinorders.shared.dto.request.EatInOrderTableChangeNumberOfGuestsRequest; +import kitchenpos.eatinorders.shared.dto.request.OrderTableCreateRequest; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrder; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItem; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderLineItems; +import kitchenpos.eatinorders.tobe.domain.order.EatInOrderRepository; +import kitchenpos.eatinorders.tobe.domain.ordertable.NumberOfGuests; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTable; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableName; +import kitchenpos.eatinorders.tobe.domain.ordertable.OrderTableRepository; +import kitchenpos.menus.application.InMemoryMenuRepository; +import kitchenpos.menus.tobe.domain.menu.Menu; +import kitchenpos.menus.tobe.domain.menu.MenuRepository; +import kitchenpos.products.application.InMemoryProductRepository; +import kitchenpos.products.tobe.domain.Product; +import kitchenpos.products.tobe.domain.ProductRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -11,31 +27,49 @@ import org.junit.jupiter.params.provider.NullAndEmptySource; import org.junit.jupiter.params.provider.ValueSource; +import java.util.Arrays; import java.util.List; import java.util.UUID; +import static kitchenpos.Fixtures.displayedMenu; +import static kitchenpos.Fixtures.eatInOrder; +import static kitchenpos.Fixtures.menuProduct; import static kitchenpos.Fixtures.order; +import static kitchenpos.Fixtures.orderLineItem; import static kitchenpos.Fixtures.orderTable; +import static kitchenpos.Fixtures.product; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; class OrderTableServiceTest { private OrderTableRepository orderTableRepository; - private OrderRepository orderRepository; + + private EatInOrderRepository eatInOrderRepository; private OrderTableService orderTableService; + private MenuRepository menuRepository; + private MenuClient menuClient; + private ProductRepository productRepository; + Product product; + Menu displayedMenu; @BeforeEach void setUp() { orderTableRepository = new InMemoryOrderTableRepository(); - orderRepository = new InMemoryOrderRepository(); - orderTableService = new OrderTableService(orderTableRepository, orderRepository); + eatInOrderRepository = new InMemoryEatInOrderRepository(); + + productRepository = new InMemoryProductRepository(); + orderTableService = new OrderTableService(orderTableRepository, eatInOrderRepository); + product = productRepository.save(product()); + menuRepository = new InMemoryMenuRepository(); + menuClient = new InMemoryMenuClient(menuRepository); + displayedMenu = menuRepository.save(displayedMenu(1L, menuProduct(product, 1L))); } @DisplayName("주문 테이블을 등록할 수 있다.") @Test void create() { - final OrderTable expected = createOrderTableRequest("1번"); + final OrderTableCreateRequest expected = createOrderTableRequest("1번"); final OrderTable actual = orderTableService.create(expected); assertThat(actual).isNotNull(); assertAll( @@ -50,7 +84,7 @@ void create() { @NullAndEmptySource @ParameterizedTest void create(final String name) { - final OrderTable expected = createOrderTableRequest(name); + final OrderTableCreateRequest expected = createOrderTableRequest(name); assertThatThrownBy(() -> orderTableService.create(expected)) .isInstanceOf(IllegalArgumentException.class); } @@ -79,7 +113,7 @@ void clear() { void clearWithUncompletedOrders() { final OrderTable orderTable = orderTableRepository.save(orderTable(true, 4)); final UUID orderTableId = orderTable.getId(); - orderRepository.save(order(OrderStatus.ACCEPTED, orderTable)); + eatInOrderRepository.save(eatInOrder(OrderStatus.ACCEPTED, orderTable, displayedMenu)); assertThatThrownBy(() -> orderTableService.clear(orderTableId)) .isInstanceOf(IllegalStateException.class); } @@ -88,7 +122,7 @@ void clearWithUncompletedOrders() { @Test void changeNumberOfGuests() { final UUID orderTableId = orderTableRepository.save(orderTable(true, 0)).getId(); - final OrderTable expected = changeNumberOfGuestsRequest(4); + final EatInOrderTableChangeNumberOfGuestsRequest expected = changeNumberOfGuestsRequest(4); final OrderTable actual = orderTableService.changeNumberOfGuests(orderTableId, expected); assertThat(actual.getNumberOfGuests()).isEqualTo(4); } @@ -98,7 +132,7 @@ void changeNumberOfGuests() { @ParameterizedTest void changeNumberOfGuests(final int numberOfGuests) { final UUID orderTableId = orderTableRepository.save(orderTable(true, 0)).getId(); - final OrderTable expected = changeNumberOfGuestsRequest(numberOfGuests); + final EatInOrderTableChangeNumberOfGuestsRequest expected = changeNumberOfGuestsRequest(numberOfGuests); assertThatThrownBy(() -> orderTableService.changeNumberOfGuests(orderTableId, expected)) .isInstanceOf(IllegalArgumentException.class); } @@ -107,7 +141,7 @@ void changeNumberOfGuests(final int numberOfGuests) { @Test void changeNumberOfGuestsInEmptyTable() { final UUID orderTableId = orderTableRepository.save(orderTable(false, 0)).getId(); - final OrderTable expected = changeNumberOfGuestsRequest(4); + final EatInOrderTableChangeNumberOfGuestsRequest expected = changeNumberOfGuestsRequest(4); assertThatThrownBy(() -> orderTableService.changeNumberOfGuests(orderTableId, expected)) .isInstanceOf(IllegalStateException.class); } @@ -120,15 +154,11 @@ void findAll() { assertThat(actual).hasSize(1); } - private OrderTable createOrderTableRequest(final String name) { - final OrderTable orderTable = new OrderTable(); - orderTable.setName(name); - return orderTable; + private OrderTableCreateRequest createOrderTableRequest(final String name) { + return new OrderTableCreateRequest(name); } - private OrderTable changeNumberOfGuestsRequest(final int numberOfGuests) { - final OrderTable orderTable = new OrderTable(); - orderTable.setNumberOfGuests(numberOfGuests); - return orderTable; + private EatInOrderTableChangeNumberOfGuestsRequest changeNumberOfGuestsRequest(final int numberOfGuests) { + return new EatInOrderTableChangeNumberOfGuestsRequest(numberOfGuests); } } From f4da63b4afe75b859afafef5092572cacc253fc7 Mon Sep 17 00:00:00 2001 From: hwanwoo Date: Tue, 3 Oct 2023 21:36:38 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feature(refactoring):=20order=20Type=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deliveryorders/domain/DeliveryOrder.java | 19 ++----------------- .../application/DeliveryOrderServiceTest.java | 11 +++++------ 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java index b79cd7df5..64083a3ca 100644 --- a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java @@ -23,10 +23,6 @@ public class DeliveryOrder { @Id private UUID id; - @Column(name = "type", nullable = false) - @Enumerated(EnumType.STRING) - private OrderType type; - @Column(name = "status", nullable = false) @Enumerated(EnumType.STRING) private OrderStatus status; @@ -43,9 +39,8 @@ public class DeliveryOrder { protected DeliveryOrder() { } - public DeliveryOrder(UUID id, OrderType type, OrderStatus status, LocalDateTime orderDateTime, DeliveryOrderLineItems orderLineItems, DeliveryOrderAddress deliveryAddress) { + public DeliveryOrder(UUID id, OrderStatus status, LocalDateTime orderDateTime, DeliveryOrderLineItems orderLineItems, DeliveryOrderAddress deliveryAddress) { this.id = id; - this.type = type; this.status = status; this.orderDateTime = orderDateTime; this.orderLineItems = orderLineItems; @@ -54,7 +49,7 @@ public DeliveryOrder(UUID id, OrderType type, OrderStatus status, LocalDateTime public static DeliveryOrder of(DeliveryOrderLineItems orderLineItems, DeliveryOrderAddress orderAddress, MenuClient menuClient) { validateDeliveryOrder(orderLineItems, menuClient); - return new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.WAITING, LocalDateTime.now(), orderLineItems, orderAddress); + return new DeliveryOrder(UUID.randomUUID(), OrderStatus.WAITING, LocalDateTime.now(), orderLineItems, orderAddress); } private static void validateDeliveryOrder(DeliveryOrderLineItems orderLineItems, MenuClient menuClient) { @@ -72,10 +67,6 @@ public UUID getId() { return id; } - public OrderType getType() { - return type; - } - public OrderStatus getStatus() { return status; } @@ -109,9 +100,6 @@ public void serve() { } public void startDelivery() { - if (type != OrderType.DELIVERY) { - throw new IllegalStateException(); - } if (status != OrderStatus.SERVED) { throw new IllegalStateException(); } @@ -126,9 +114,6 @@ public void completeDelivery() { } public void complete() { - if (type != OrderType.DELIVERY) { - throw new IllegalStateException(); - } if (status != OrderStatus.DELIVERED) { throw new IllegalStateException(); } diff --git a/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java b/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java index 437d4312c..e57c1810e 100644 --- a/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java +++ b/src/test/java/kitchenpos/deliveryorders/application/DeliveryOrderServiceTest.java @@ -76,7 +76,6 @@ void success_create_delivery_order() { //then assertThat(result.getStatus()).isEqualTo(OrderStatus.WAITING); - assertThat(result.getType()).isEqualTo(OrderType.DELIVERY); assertThat(result.getOrderDateTime()).isNotNull(); assertThat(result.getDeliveryAddress()).isEqualTo(request.getDeliveryAddress()); } @@ -119,7 +118,7 @@ void menu_price_of_delivery_order_and_order_line_item_price_should_be_same() { @Test void only_waiting_order_can_be_accept() { - DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); deliveryOrderRepository.save(deliveryOrder); assertThatThrownBy(() -> deliveryOrderService.accept(deliveryOrder.getId())) @@ -130,7 +129,7 @@ void only_waiting_order_can_be_accept() { @Test void only_accepted_order_can_be_serve() { - DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); deliveryOrderRepository.save(deliveryOrder); assertThatThrownBy(() -> deliveryOrderService.serve(deliveryOrder.getId())) @@ -141,7 +140,7 @@ void only_accepted_order_can_be_serve() { @Test void only_served_order_can_be_delivery_start() { - DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderStatus.DELIVERING, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); deliveryOrderRepository.save(deliveryOrder); assertThatThrownBy(() -> deliveryOrderService.startDelivery(deliveryOrder.getId())) @@ -152,7 +151,7 @@ void only_served_order_can_be_delivery_start() { @Test void only_delivery_started_order_can_be_complete_delivery() { - DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.SERVED, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderStatus.SERVED, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); deliveryOrderRepository.save(deliveryOrder); assertThatThrownBy(() -> deliveryOrderService.completeDelivery(deliveryOrder.getId())) @@ -163,7 +162,7 @@ void only_delivery_started_order_can_be_complete_delivery() { @Test void only_delivery_completed_order_can_be_complete() { - DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderType.DELIVERY, OrderStatus.SERVED, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); + DeliveryOrder deliveryOrder = new DeliveryOrder(UUID.randomUUID(), OrderStatus.SERVED, LocalDateTime.now(), new DeliveryOrderLineItems(List.of(deliveryOrderLineItem(displayedMenu, menuClient))), new DeliveryOrderAddress("서울")); deliveryOrderRepository.save(deliveryOrder); assertThatThrownBy(() -> deliveryOrderService.complete(deliveryOrder.getId())) From 33e3f30771e0cbd842f978c919321093d3a4fc38 Mon Sep 17 00:00:00 2001 From: hwanwoo Date: Wed, 4 Oct 2023 07:33:41 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feature(refactoring):=20order=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=EC=8B=9C=20=EC=83=81=ED=83=9C=20=EC=A1=B0=EA=B1=B4=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kitchenpos/deliveryorders/domain/DeliveryOrder.java | 6 ++---- .../java/kitchenpos/deliveryorders/domain/MenuClient.java | 2 +- .../kitchenpos/deliveryorders/infra/MenuClientImpl.java | 4 ++-- .../eatinorders/tobe/domain/order/EatInOrder.java | 2 +- .../deliveryorders/application/InMemoryMenuClient.java | 4 ++-- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java index 64083a3ca..c9f04ffc6 100644 --- a/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java +++ b/src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java @@ -1,8 +1,6 @@ package kitchenpos.deliveryorders.domain; import kitchenpos.eatinorders.domain.OrderStatus; -import kitchenpos.eatinorders.domain.OrderType; -import kitchenpos.menus.tobe.domain.menu.Menu; import javax.persistence.Column; import javax.persistence.Embedded; @@ -53,12 +51,12 @@ public static DeliveryOrder of(DeliveryOrderLineItems orderLineItems, DeliveryOr } private static void validateDeliveryOrder(DeliveryOrderLineItems orderLineItems, MenuClient menuClient) { - List menus = menuClient.findAllByIdIn( + int menusSize = menuClient.countAllByIdIn( orderLineItems.getOrderLineItems().stream() .map(DeliveryOrderLineItem::getMenuId) .collect(Collectors.toList()) ); - if (menus.size() != orderLineItems.getOrderLineItems().size()) { + if (menusSize != orderLineItems.getOrderLineItems().size()) { throw new IllegalArgumentException(); } } diff --git a/src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java b/src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java index c9a8981f5..bfffab741 100644 --- a/src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java +++ b/src/main/java/kitchenpos/deliveryorders/domain/MenuClient.java @@ -9,5 +9,5 @@ public interface MenuClient { Optional findById(UUID id); - List findAllByIdIn(List ids); + int countAllByIdIn(List ids); } diff --git a/src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java b/src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java index 6b1de4592..a61fc46a5 100644 --- a/src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java +++ b/src/main/java/kitchenpos/deliveryorders/infra/MenuClientImpl.java @@ -23,7 +23,7 @@ public Optional findById(UUID id) { } @Override - public List findAllByIdIn(List ids) { - return menuRepository.findAllByIdIn(ids); + public int countAllByIdIn(List ids) { + return menuRepository.findAllByIdIn(ids).size(); } } diff --git a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java index 53e3b8828..2974e88d0 100644 --- a/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java +++ b/src/main/java/kitchenpos/eatinorders/tobe/domain/order/EatInOrder.java @@ -99,7 +99,7 @@ public void serve() { } public void complete() { - if (status != OrderStatus.ACCEPTED) { + if (status != OrderStatus.SERVED) { throw new IllegalStateException(); } this.status = OrderStatus.COMPLETED; diff --git a/src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java b/src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java index c702845ff..d77e2fa46 100644 --- a/src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java +++ b/src/test/java/kitchenpos/deliveryorders/application/InMemoryMenuClient.java @@ -22,7 +22,7 @@ public Optional findById(UUID id) { } @Override - public List findAllByIdIn(List ids) { - return menuRepository.findAllByIdIn(ids); + public int countAllByIdIn(List ids) { + return menuRepository.findAllByIdIn(ids).size(); } } From b21163d19ceab84768bcc60d0ad10f5036f10657 Mon Sep 17 00:00:00 2001 From: hwanwoo Date: Wed, 4 Oct 2023 07:48:53 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feature(refactoring):=20=EB=AA=A8=EB=8D=B8?= =?UTF-8?q?=EB=A7=81=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 63 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6b52cee78..5b167b855 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ docker compose -p kitchenpos up -d | 한글명 | 영문명 | 설명 | | --- | --- | --- | +| 매장 주문 | eat in order | 매장에서 안에서의 주문 | | 방문한 손님 수 | number of guests | 식기가 필요한 사람 수. 필수 사항은 아니며 주문은 0명으로 등록할 수 있다. | | 빈 테이블 | empty table | 주문을 등록할 수 없는 주문 테이블 | | 서빙 | served | 조리가 완료되어 음식이 나갈 수 있는 단계 | @@ -134,18 +135,19 @@ docker compose -p kitchenpos up -d ### 배달 주문 -| 한글명 | 영문명 | 설명 | -| --- | --- |------------------------------------------------| -| 배달 | delivering | 배달원이 매장을 방문하여 배달 음식의 픽업을 완료하고 배달을 시작하는 단계 | +| 한글명 | 영문명 | 설명 | +|--------|----------------|------------------------------------------------| +| 배달 주문 | delivery order | 배달을 위한 주문 | +| 배달 | delivering | 배달원이 매장을 방문하여 배달 음식의 픽업을 완료하고 배달을 시작하는 단계 | | 배달 대행사 | delivery agency | 준비한 음식을 고객에게 직접 배달하는 서비스 | -| 배달 완료 | delivered | 배달원이 주문한 음식을 고객에게 배달 완료한 단계 | -| 서빙 | served | 조리가 완료되어 음식이 나갈 수 있는 단계 | -| 완료 | completed | 배달이 완료된 후 주문을 마무리 하는 단계 | -| 접수 | accepted | 주문을 받고 음식을 조리하는 단계 | -| 접수 대기 | waiting | 주문이 생성되어 매장으로 전달된 단계 | -| 주문 | order | 집이나 직장 등 고객이 선택한 주소로 음식을 배달한다. | -| 주문 상태 | order status | 주문이 생성되면 매장에서 주문을 접수하고 고객이 음식을 받기까지의 단계를 표시한다. | -| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 | +| 배달 완료 | delivered | 배달원이 주문한 음식을 고객에게 배달 완료한 단계 | +| 서빙 | served | 조리가 완료되어 음식이 나갈 수 있는 단계 | +| 완료 | completed | 배달이 완료된 후 주문을 마무리 하는 단계 | +| 접수 | accepted | 주문을 받고 음식을 조리하는 단계 | +| 접수 대기 | waiting | 주문이 생성되어 매장으로 전달된 단계 | +| 주문 | order | 집이나 직장 등 고객이 선택한 주소로 음식을 배달한다. | +| 주문 상태 | order status | 주문이 생성되면 매장에서 주문을 접수하고 고객이 음식을 받기까지의 단계를 표시한다. | +| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 | ### 포장 주문 @@ -181,27 +183,42 @@ docker compose -p kitchenpos up -d ### 매장 주문 - `OrderTable`은 식별자와 이름, `NumberOfGuests`를 가진다. -- `OrderTable`의 추가 `Order`는 `OrderTable`에 계속 쌓이며 모든 `Order`가 완료되면 `EmptyTable`이 된다. +- `OrderTable`의 추가 `Order`는 `OrderTable`에 계속 쌓이며 모든 `EatInOrder`가 완료되면 `EmptyTable`이 된다. - `EmptyTable`인 경우 `NumberOfGuests`는 0이며 변경할 수 없다. -- `Order`는 식별자와 `OrderStatus`, 주문 시간, `OrderLineItems`를 가진다. -- 메뉴가 노출되고 있으며 판매되는 메뉴 가격과 일치하면 `Order`가 생성된다. -- `Order`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 계산 완료 순서로 진행된다. +- `EatInOrder`는 식별자와 `OrderStatus`, 주문 시간, `OrderLineItems`를 가진다. +- `Menu`가 `Display Menu`되고 있으며 판매되는 메뉴 가격과 일치하면 `EatInOrder`가 생성된다. +- `EatInOrder`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 계산 완료 순서로 진행된다. +- `EatInOrder`가 생성되면 `OrderStatus`는 `Waiting` 상태이다. +- `Accepted` 가 되려면 전 주문은 `Waiting` 상태여야 한다. +- `Served` 가 되려면 전 주문은 `Accepted` 상태여야 한다. +- `Completed` 가 되려면 전 주문은 `Served` 상태여야 한다. - `OrderLineItem`는 가격과 수량을 가진다. -- `OrderLineItem`의 수량은 기존 `Order`를 취소하거나 변경해도 수정되지 않기 때문에 0보다 적을 수 있다. +- `OrderLineItem`의 수량은 기존 `EatInOrder`를 취소하거나 변경해도 수정되지 않기 때문에 0보다 적을 수 있다. +- `` ### 배달 주문 -- `Order`는 식별자와 `OrderStatus`, 주문 시간, 배달 주소, `OrderLineItems`를 가진다. -- 메뉴가 노출되고 있으며 판매되는 메뉴 가격과 일치하면 `Order`가 생성된다. -- `Order`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 배달 ➜ 배달 완료 ➜ 계산 완료 순서로 진행된다. -- `Order`가 접수되면 `DeliveryAgency`가 호출된다. +- `Delivery Order`는 식별자와 `OrderStatus`, 주문 시간, 배달 주소, `OrderLineItems`를 가진다. +- 메뉴가 노출되고 있으며 판매되는 메뉴 가격과 일치하면 `Delivery Order`가 생성된다. +- `Delivery Order`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 배달 ➜ 배달 완료 ➜ 계산 완료 순서로 진행된다. +- `Delivery Order`가 생성되면 `OrderStatus`는 `Waiting` 상태이다. +- `Delivery Order`가 접수되면 `DeliveryAgency`가 호출된다. +- `Accepted` 가 되려면 전 주문은 `Waiting` 상태여야 한다. +- `Served` 가 되려면 전 주문은 `Accepted` 상태여야 한다. +- `Delivering` 가 되려면 전 주문은 `Served` 상태여야 한다. +- `Delivered` 가 되려면 전 주문은 `Delivering` 상태여야 한다. +- `Completed` 가 되려면 전 주문은 `Delivered` 상태여야 한다. - `OrderLineItem`는 가격과 수량을 가진다. - `OrderLineItem`의 수량은 1보다 커야 한다. ### 포장 주문 -- `Order`는 식별자와 `OrderStatus`, 주문 시간, `OrderLineItems`를 가진다. -- 메뉴가 노출되고 있으며 판매되는 메뉴 가격과 일치하면 `Order`가 생성된다. -- `Order`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 계산 완료 순서로 진행된다. +- `Take Out Order`는 식별자와 `OrderStatus`, 주문 시간, `OrderLineItems`를 가진다. +- 메뉴가 노출되고 있으며 판매되는 메뉴 가격과 일치하면 `Take Out Order`가 생성된다. +- `Take Out Order`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 계산 완료 순서로 진행된다. +- `Take Out Order`가 생성되면 `OrderStatus`는 `Waiting` 상태이다. +- `Accepted` 가 되려면 전 주문은 `Waiting` 상태여야 한다. +- `Served` 가 되려면 전 주문은 `Accepted` 상태여야 한다. +- `Completed` 가 되려면 전 주문은 `Served` 상태여야 한다. - `OrderLineItem`는 가격과 수량을 가진다. - `OrderLineItem`의 수량은 1보다 커야 한다.