diff --git a/README.md b/README.md index 93e61acce..f0d1b5f45 100644 --- a/README.md +++ b/README.md @@ -127,18 +127,19 @@ docker compose -p kitchenpos up -d ### 매장 주문 -| 한글명 | 영문명 | 설명 | -|----------|------------------|----------------------------------------------------| +| 한글명 | 영문명 | 설명 | +|---------|------------------|----------------------------------------------------| | 방문한 손님 수 | number of guests | 식기가 필요한 사람 수. 필수 사항은 아니며 주문은 0명으로 등록할 수 있다. | -| 빈 테이블 | empty table | 주문을 등록할 수 없는 주문 테이블 | -| 서빙 | served | 조리가 완료되어 음식이 나갈 수 있는 단계 | -| 완료 | completed | 고객이 모든 식사를 마치고 결제를 완료한 단계 | -| 접수 | accepted | 주문을 받고 음식을 조리하는 단계 | -| 접수 대기 | waiting | 주문이 생성되어 매장으로 전달된 단계 | -| 주문 | order | 매장에서 식사하는 고객 대상. 손님들이 매장에서 먹을 수 있도록 조리된 음식을 가져다준다. | -| 주문 상태 | order status | 주문이 생성되면 매장에서 주문을 접수하고 고객이 음식을 받기까지의 단계를 표시한다. | -| 주문 테이블 | order table | 매장에서 주문이 발생하는 영역 | -| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 | +| 빈 테이블 | empty table | 주문을 등록할 수 없는 주문 테이블 | +| 서빙완료 | served | 조리가 완료되어 음식이 나갈 수 있는 단계 | +| 매장주문완료 | completed | 고객이 모든 식사를 마치고 결제를 완료한 단계 | +| 접수완료 | accepted | 주문을 받고 음식을 조리하는 단계 | +| 접수 대기 | waiting | 주문이 생성되어 매장으로 전달된 단계 | +| 주문 | eatInOrder | 매장에서 식사하는 고객 대상. 손님들이 매장에서 먹을 수 있도록 조리된 음식을 가져다준다. | +| 주문 상태 | order status | 주문이 생성되면 매장에서 주문을 접수하고 고객이 음식을 받기까지의 단계를 표시한다. | +| 주문 테이블 | order table | 매장에서 주문이 발생하는 영역 | +| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 | + ### 배달 주문 @@ -194,11 +195,12 @@ docker compose -p kitchenpos up -d - `OrderTable`은 식별자와 이름, `NumberOfGuests`를 가진다. - `OrderTable`의 추가 `Order`는 `OrderTable`에 계속 쌓이며 모든 `Order`가 완료되면 `EmptyTable`이 된다. - `EmptyTable`인 경우 `NumberOfGuests`는 0이며 변경할 수 없다. -- `Order`는 식별자와 `OrderStatus`, 주문 시간, `OrderLineItems`를 가진다. -- 메뉴가 노출되고 있으며 판매되는 메뉴 가격과 일치하면 `Order`가 생성된다. -- `Order`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 계산 완료 순서로 진행된다. +- `EatInOrder`는 식별자와 `OrderStatus`, 주문 시간, `OrderLineItems`를 가진다. +- 메뉴가 노출되고 있으며 판매되는 메뉴 가격과 일치하면 `EatInOrder`가 생성된다. +- `EatInOrder`는 접수 대기 ➜ 접수 ➜ 서빙 ➜ 계산 완료 순서로 진행된다. - `OrderLineItem`는 가격과 수량을 가진다. -- `OrderLineItem`의 수량은 기존 `Order`를 취소하거나 변경해도 수정되지 않기 때문에 0보다 적을 수 있다. +- `OrderLineItem`의 수량은 기존 `EatInOrder`를 취소하거나 변경해도 수정되지 않기 때문에 0보다 적을 수 있다. + ### 배달 주문 diff --git a/src/main/java/kitchenpos/eatinorders/adapter/eatinorder/out/JpaEatinOrderRepository.java b/src/main/java/kitchenpos/eatinorders/adapter/eatinorder/out/JpaEatinOrderRepository.java new file mode 100644 index 000000000..90379b923 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/adapter/eatinorder/out/JpaEatinOrderRepository.java @@ -0,0 +1,11 @@ +package kitchenpos.eatinorders.adapter.eatinorder.out; + +import java.util.UUID; +import kitchenpos.eatinorders.application.eatinorder.port.out.EatinOrderRepository; +import kitchenpos.eatinorders.domain.eatinorder.EatinOrder; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface JpaEatinOrderRepository extends EatinOrderRepository, + JpaRepository { + +} diff --git a/src/main/java/kitchenpos/eatinorders/adapter/eatinorder/out/ValidMenuAdapter.java b/src/main/java/kitchenpos/eatinorders/adapter/eatinorder/out/ValidMenuAdapter.java new file mode 100644 index 000000000..6f69ab9f3 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/adapter/eatinorder/out/ValidMenuAdapter.java @@ -0,0 +1,26 @@ +package kitchenpos.eatinorders.adapter.eatinorder.out; + +import java.util.List; +import java.util.UUID; +import kitchenpos.eatinorders.application.eatinorder.port.out.ValidMenuPort; +import kitchenpos.menu.application.menu.port.in.MenuFindUseCase; + +public class ValidMenuAdapter implements ValidMenuPort { + + private final MenuFindUseCase menuFindUseCase; + + public ValidMenuAdapter(final MenuFindUseCase menuFindUseCase) { + this.menuFindUseCase = menuFindUseCase; + } + + @Override + public void checkValidMenu(final List menuIds) { + if (menuIds.size() != menuFindUseCase.findAll() + .stream() + .filter(menu -> menuIds.contains(menu.getId())) + .count()) { + + throw new IllegalStateException(String.format("menu is not exist. ids: %s", menuIds)); + } + } +} diff --git a/src/main/java/kitchenpos/eatinorders/adapter/ordertable/out/JpaOrderTableRepository.java b/src/main/java/kitchenpos/eatinorders/adapter/ordertable/out/JpaOrderTableRepository.java new file mode 100644 index 000000000..1bc34ed6e --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/adapter/ordertable/out/JpaOrderTableRepository.java @@ -0,0 +1,11 @@ +package kitchenpos.eatinorders.adapter.ordertable.out; + +import java.util.UUID; +import kitchenpos.eatinorders.application.ordertable.port.out.OrderTableNewRepository; +import kitchenpos.eatinorders.domain.ordertable.OrderTableNew; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface JpaOrderTableRepository extends OrderTableNewRepository, + JpaRepository { + +} diff --git a/src/main/java/kitchenpos/eatinorders/application/eatinorder/DefaultEatinOrderService.java b/src/main/java/kitchenpos/eatinorders/application/eatinorder/DefaultEatinOrderService.java new file mode 100644 index 000000000..357966dee --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/eatinorder/DefaultEatinOrderService.java @@ -0,0 +1,68 @@ +package kitchenpos.eatinorders.application.eatinorder; + +import java.util.UUID; +import java.util.stream.Collectors; +import kitchenpos.eatinorders.application.eatinorder.port.in.EatinOrderDTO; +import kitchenpos.eatinorders.application.eatinorder.port.in.EatinOrderInitCommand; +import kitchenpos.eatinorders.application.eatinorder.port.in.EatinOrderUseCase; +import kitchenpos.eatinorders.application.eatinorder.port.out.EatinOrderRepository; +import kitchenpos.eatinorders.application.eatinorder.port.out.ValidMenuPort; +import kitchenpos.eatinorders.application.exception.NotExistEatinOrderException; +import kitchenpos.eatinorders.application.ordertable.port.out.OrderTableNewRepository; +import kitchenpos.eatinorders.domain.eatinorder.EatinOrder; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.transaction.annotation.Transactional; + +public class DefaultEatinOrderService implements EatinOrderUseCase { + + private final EatinOrderRepository eatinOrderRepository; + private final OrderTableNewRepository orderTableRepository; + private final ValidMenuPort menuFindPort; + + public DefaultEatinOrderService(final EatinOrderRepository eatinOrderRepository, + final OrderTableNewRepository orderTableRepository, final ValidMenuPort menuFindPort) { + + this.eatinOrderRepository = eatinOrderRepository; + this.orderTableRepository = orderTableRepository; + this.menuFindPort = menuFindPort; + } + + @Override + public EatinOrderDTO init(final EatinOrderInitCommand command) { + final EatinOrder eatinOrder = eatinOrderRepository.save( + EatinOrder.create(command.getOrderTableId(), + command.getOrderLineItemMenuIds(), + command.getOrderLineItemCommands() + .stream() + .map(item -> Pair.of(item.getMenuId(), item.getQuantity())) + .collect(Collectors.toUnmodifiableList()), + orderTableRepository, menuFindPort)); + + return new EatinOrderDTO(eatinOrder); + } + + @Override + public void accept(final UUID id) { + final EatinOrder order = eatinOrderRepository.findById(id) + .orElseThrow(() -> new NotExistEatinOrderException(id)); + + order.acceptOrder(); + } + + @Override + public void serve(final UUID id) { + final EatinOrder order = eatinOrderRepository.findById(id) + .orElseThrow(() -> new NotExistEatinOrderException(id)); + + order.serveOrder(); + } + + @Transactional + @Override + public void complete(final UUID id) { + final EatinOrder order = eatinOrderRepository.findById(id) + .orElseThrow(() -> new NotExistEatinOrderException(id)); + + order.completeOrder(orderTableRepository); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderDTO.java b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderDTO.java new file mode 100644 index 000000000..652325d52 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderDTO.java @@ -0,0 +1,22 @@ +package kitchenpos.eatinorders.application.eatinorder.port.in; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import kitchenpos.eatinorders.domain.eatinorder.EatinOrder; + +public final class EatinOrderDTO { + + private final UUID id; + private final List orderLineItems; + private final UUID orderTableId; + + public EatinOrderDTO(final EatinOrder order) { + this.id = order.getId(); + this.orderLineItems = order.getOrderLineItems() + .stream() + .map(OrderLineItemDTO::new) + .collect(Collectors.toUnmodifiableList()); + this.orderTableId = order.getOrderTableId(); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderInitCommand.java b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderInitCommand.java new file mode 100644 index 000000000..945386e62 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderInitCommand.java @@ -0,0 +1,51 @@ +package kitchenpos.eatinorders.application.eatinorder.port.in; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +public final class EatinOrderInitCommand { + + private final UUID orderTableId; + private final List orderLineItemCommands; + + public EatinOrderInitCommand(final UUID orderTableId, + final List orderLineItemCommands) { + + this.orderTableId = orderTableId; + this.orderLineItemCommands = orderLineItemCommands; + } + + public UUID getOrderTableId() { + return orderTableId; + } + + public List getOrderLineItemCommands() { + return orderLineItemCommands; + } + + public List getOrderLineItemMenuIds() { + return orderLineItemCommands.stream() + .map(OrderLineItemCommand::getMenuId) + .collect(Collectors.toUnmodifiableList()); + } + + public static final class OrderLineItemCommand { + + private final UUID menuId; + private final int quantity; + + public OrderLineItemCommand(final UUID menuId, final int quantity) { + this.menuId = menuId; + this.quantity = quantity; + } + + public UUID getMenuId() { + return menuId; + } + + public int getQuantity() { + return quantity; + } + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderUseCase.java b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderUseCase.java new file mode 100644 index 000000000..6a81d68da --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/EatinOrderUseCase.java @@ -0,0 +1,34 @@ +package kitchenpos.eatinorders.application.eatinorder.port.in; + +import java.util.UUID; +import kitchenpos.eatinorders.application.exception.InvalidAcceptStatusException; +import kitchenpos.eatinorders.application.exception.InvalidCompleteStatusException; +import kitchenpos.eatinorders.application.exception.InvalidServeStatusException; +import kitchenpos.eatinorders.application.exception.NotExistOrderTableException; + +public interface EatinOrderUseCase { + + /** + * @throws NotExistOrderTableException orderTableId에 해당하는 table이 없을 때 + * @throws IllegalStateException orderLineItem에 있는 menu가 없는 menu일 때 + */ + EatinOrderDTO init(final EatinOrderInitCommand command); + + /** + * @throws NotExistOrderTableException orderTableId에 해당하는 table이 없을 때 + * @throws InvalidAcceptStatusException accept를 할 수 없는 상태일 때 + */ + void accept(final UUID id); + + /** + * @throws NotExistOrderTableException orderTableId에 해당하는 table이 없을 때 + * @throws InvalidServeStatusException serve를 할 수 없는 상태일 때 + */ + void serve(final UUID id); + + /** + * @throws NotExistOrderTableException orderTableId에 해당하는 table이 없을 때 + * @throws InvalidCompleteStatusException complete를 할 수 없는 상태일 때 + */ + void complete(final UUID id); +} diff --git a/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/OrderLineItemDTO.java b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/OrderLineItemDTO.java new file mode 100644 index 000000000..94a68268d --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/in/OrderLineItemDTO.java @@ -0,0 +1,17 @@ +package kitchenpos.eatinorders.application.eatinorder.port.in; + +import java.util.UUID; +import kitchenpos.eatinorders.domain.eatinorder.OrderLineItemNew; + +public final class OrderLineItemDTO { + + private final UUID id; + private final UUID menuId; + private final int quantity; + + public OrderLineItemDTO(final OrderLineItemNew orderLineItem) { + this.id = orderLineItem.getId(); + this.menuId = orderLineItem.getMenuId(); + this.quantity = orderLineItem.getQuantity(); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/out/EatinOrderRepository.java b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/out/EatinOrderRepository.java new file mode 100644 index 000000000..939341b03 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/out/EatinOrderRepository.java @@ -0,0 +1,12 @@ +package kitchenpos.eatinorders.application.eatinorder.port.out; + +import java.util.Optional; +import java.util.UUID; +import kitchenpos.eatinorders.domain.eatinorder.EatinOrder; + +public interface EatinOrderRepository { + + EatinOrder save(final EatinOrder eatinOrder); + + Optional findById(final UUID id); +} diff --git a/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/out/ValidMenuPort.java b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/out/ValidMenuPort.java new file mode 100644 index 000000000..8b752355e --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/eatinorder/port/out/ValidMenuPort.java @@ -0,0 +1,12 @@ +package kitchenpos.eatinorders.application.eatinorder.port.out; + +import java.util.List; +import java.util.UUID; + +public interface ValidMenuPort { + + /** + * @throws IllegalStateException orderLineItem에 있는 menu가 없는 menu일 때 + */ + void checkValidMenu(final List menuIds); +} diff --git a/src/main/java/kitchenpos/eatinorders/application/exception/InvalidAcceptStatusException.java b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidAcceptStatusException.java new file mode 100644 index 000000000..4ac2539b9 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidAcceptStatusException.java @@ -0,0 +1,11 @@ +package kitchenpos.eatinorders.application.exception; + +import java.util.UUID; +import kitchenpos.eatinorders.domain.eatinorder.Status; + +public class InvalidAcceptStatusException extends InvalidEatinOrderStatusException { + + public InvalidAcceptStatusException(final UUID id, final Status currentStatus) { + super(id, currentStatus); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/exception/InvalidCompleteStatusException.java b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidCompleteStatusException.java new file mode 100644 index 000000000..f150f5c4a --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidCompleteStatusException.java @@ -0,0 +1,11 @@ +package kitchenpos.eatinorders.application.exception; + +import java.util.UUID; +import kitchenpos.eatinorders.domain.eatinorder.Status; + +public class InvalidCompleteStatusException extends InvalidEatinOrderStatusException { + + public InvalidCompleteStatusException(final UUID id, final Status currentStatus) { + super(id, currentStatus); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/exception/InvalidEatinOrderStatusException.java b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidEatinOrderStatusException.java new file mode 100644 index 000000000..5c8b8f85d --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidEatinOrderStatusException.java @@ -0,0 +1,12 @@ +package kitchenpos.eatinorders.application.exception; + +import java.util.UUID; +import kitchenpos.eatinorders.domain.eatinorder.Status; + +public class InvalidEatinOrderStatusException extends RuntimeException { + + public InvalidEatinOrderStatusException(final UUID id, final Status currentStatus) { + super(String.format("invalid eatin order status. id: %s, currentStatus: %s", id, + currentStatus)); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/exception/InvalidServeStatusException.java b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidServeStatusException.java new file mode 100644 index 000000000..c96e115ab --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/exception/InvalidServeStatusException.java @@ -0,0 +1,11 @@ +package kitchenpos.eatinorders.application.exception; + +import java.util.UUID; +import kitchenpos.eatinorders.domain.eatinorder.Status; + +public class InvalidServeStatusException extends InvalidEatinOrderStatusException { + + public InvalidServeStatusException(final UUID id, final Status currentStatus) { + super(id, currentStatus); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/exception/NotExistEatinOrderException.java b/src/main/java/kitchenpos/eatinorders/application/exception/NotExistEatinOrderException.java new file mode 100644 index 000000000..15c054610 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/exception/NotExistEatinOrderException.java @@ -0,0 +1,22 @@ +package kitchenpos.eatinorders.application.exception; + +import com.google.common.base.MoreObjects; +import java.util.UUID; + +public final class NotExistEatinOrderException extends RuntimeException { + + private final UUID id; + + public NotExistEatinOrderException(final UUID id) { + super(String.format("not exist order. id: %s", id)); + + this.id = id; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .toString(); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/exception/NotExistOrderTableException.java b/src/main/java/kitchenpos/eatinorders/application/exception/NotExistOrderTableException.java new file mode 100644 index 000000000..4ab2d3bc4 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/exception/NotExistOrderTableException.java @@ -0,0 +1,22 @@ +package kitchenpos.eatinorders.application.exception; + +import com.google.common.base.MoreObjects; +import java.util.UUID; + +public final class NotExistOrderTableException extends RuntimeException { + + private final UUID id; + + public NotExistOrderTableException(final UUID id) { + super(String.format("not exist orderTable. id: %s", id)); + + this.id = id; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .toString(); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/ordertable/DefaultOrderTableCreationService.java b/src/main/java/kitchenpos/eatinorders/application/ordertable/DefaultOrderTableCreationService.java new file mode 100644 index 000000000..4a50c6991 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/ordertable/DefaultOrderTableCreationService.java @@ -0,0 +1,38 @@ +package kitchenpos.eatinorders.application.ordertable; + +import static kitchenpos.support.ParameterValidateUtils.checkNotNull; + +import java.util.UUID; +import kitchenpos.eatinorders.application.exception.NotExistOrderTableException; +import kitchenpos.eatinorders.application.ordertable.port.in.OrderTableCreationUseCase; +import kitchenpos.eatinorders.application.ordertable.port.out.OrderTableNewRepository; +import kitchenpos.eatinorders.domain.ordertable.OrderTableNew; +import kitchenpos.support.vo.Name; + +public class DefaultOrderTableCreationService implements OrderTableCreationUseCase { + + private final OrderTableNewRepository repository; + + public DefaultOrderTableCreationService(final OrderTableNewRepository repository) { + this.repository = repository; + } + + @Override + public UUID create(final Name name) { + checkNotNull(name, "name"); + + final OrderTableNew orderTable = repository.save(OrderTableNew.create(name)); + + return orderTable.getId(); + } + + @Override + public void clear(final UUID id) { + checkNotNull(id, "id"); + + final OrderTableNew orderTable = repository.findById(id) + .orElseThrow(() -> new NotExistOrderTableException(id)); + + orderTable.clear(); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/ordertable/DefaultOrderTableSitService.java b/src/main/java/kitchenpos/eatinorders/application/ordertable/DefaultOrderTableSitService.java new file mode 100644 index 000000000..de7fbc842 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/ordertable/DefaultOrderTableSitService.java @@ -0,0 +1,38 @@ +package kitchenpos.eatinorders.application.ordertable; + +import static kitchenpos.support.ParameterValidateUtils.checkNotNull; + +import java.util.UUID; +import kitchenpos.eatinorders.application.exception.NotExistOrderTableException; +import kitchenpos.eatinorders.application.ordertable.port.in.OrderTableSitUseCase; +import kitchenpos.eatinorders.application.ordertable.port.out.OrderTableNewRepository; +import kitchenpos.eatinorders.domain.ordertable.OrderTableNew; + +public class DefaultOrderTableSitService implements OrderTableSitUseCase { + + private final OrderTableNewRepository repository; + + public DefaultOrderTableSitService(final OrderTableNewRepository repository) { + this.repository = repository; + } + + @Override + public void sit(final UUID id, final int numberOfGuests) { + checkNotNull(id, "id"); + + final OrderTableNew orderTable = repository.findById(id) + .orElseThrow(() -> new NotExistOrderTableException(id)); + + orderTable.sit(numberOfGuests); + } + + @Override + public void changeGuests(final UUID id, final int numberOfGuests) { + checkNotNull(id, "id"); + + final OrderTableNew orderTable = repository.findById(id) + .orElseThrow(() -> new NotExistOrderTableException(id)); + + orderTable.changeNumberOfGuests(numberOfGuests); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/application/ordertable/port/in/OrderTableCreationUseCase.java b/src/main/java/kitchenpos/eatinorders/application/ordertable/port/in/OrderTableCreationUseCase.java new file mode 100644 index 000000000..1faf43d47 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/ordertable/port/in/OrderTableCreationUseCase.java @@ -0,0 +1,15 @@ +package kitchenpos.eatinorders.application.ordertable.port.in; + +import java.util.UUID; +import kitchenpos.eatinorders.application.exception.NotExistOrderTableException; +import kitchenpos.support.vo.Name; + +public interface OrderTableCreationUseCase { + + UUID create(final Name name); + + /** + * @throws NotExistOrderTableException id에 해당하는 orderTable이 없을 때 + */ + void clear(final UUID id); +} diff --git a/src/main/java/kitchenpos/eatinorders/application/ordertable/port/in/OrderTableSitUseCase.java b/src/main/java/kitchenpos/eatinorders/application/ordertable/port/in/OrderTableSitUseCase.java new file mode 100644 index 000000000..a58e668e4 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/ordertable/port/in/OrderTableSitUseCase.java @@ -0,0 +1,21 @@ +package kitchenpos.eatinorders.application.ordertable.port.in; + +import java.util.UUID; +import kitchenpos.eatinorders.application.exception.NotExistOrderTableException; + +public interface OrderTableSitUseCase { + + /** + * @throws NotExistOrderTableException id에 해당하는 orderTable이 없을 때 + * @throws IllegalArgumentException numberOfGuests가 음수일 때 + * @throws IllegalStateException orderTable이 점유된 상태가 아닐 때 + */ + void sit(final UUID id, final int numberOfGuests); + + /** + * @throws NotExistOrderTableException id에 해당하는 orderTable이 없을 때 + * @throws IllegalArgumentException numberOfGuests가 음수일 때 + * @throws IllegalStateException orderTable이 점유된 상태가 아닐 때 + */ + void changeGuests(final UUID id, final int numberOfGuests); +} diff --git a/src/main/java/kitchenpos/eatinorders/application/ordertable/port/out/OrderTableNewRepository.java b/src/main/java/kitchenpos/eatinorders/application/ordertable/port/out/OrderTableNewRepository.java new file mode 100644 index 000000000..9a909b4f9 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/application/ordertable/port/out/OrderTableNewRepository.java @@ -0,0 +1,12 @@ +package kitchenpos.eatinorders.application.ordertable.port.out; + +import java.util.Optional; +import java.util.UUID; +import kitchenpos.eatinorders.domain.ordertable.OrderTableNew; + +public interface OrderTableNewRepository { + + OrderTableNew save(final OrderTableNew orderTable); + + Optional findById(final UUID id); +} diff --git a/src/main/java/kitchenpos/eatinorders/config/EatinOrderInfraConfig.java b/src/main/java/kitchenpos/eatinorders/config/EatinOrderInfraConfig.java new file mode 100644 index 000000000..251518278 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/config/EatinOrderInfraConfig.java @@ -0,0 +1,16 @@ +package kitchenpos.eatinorders.config; + +import kitchenpos.eatinorders.adapter.eatinorder.out.ValidMenuAdapter; +import kitchenpos.eatinorders.application.eatinorder.port.out.ValidMenuPort; +import kitchenpos.menu.application.menu.port.in.MenuFindUseCase; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class EatinOrderInfraConfig { + + @Bean + public ValidMenuPort validMenuPort(final MenuFindUseCase menuFindUseCase) { + return new ValidMenuAdapter(menuFindUseCase); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/config/EatinOrderServiceConfig.java b/src/main/java/kitchenpos/eatinorders/config/EatinOrderServiceConfig.java new file mode 100644 index 000000000..58ed40357 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/config/EatinOrderServiceConfig.java @@ -0,0 +1,22 @@ +package kitchenpos.eatinorders.config; + +import kitchenpos.eatinorders.application.eatinorder.DefaultEatinOrderService; +import kitchenpos.eatinorders.application.eatinorder.port.in.EatinOrderUseCase; +import kitchenpos.eatinorders.application.eatinorder.port.out.EatinOrderRepository; +import kitchenpos.eatinorders.application.eatinorder.port.out.ValidMenuPort; +import kitchenpos.eatinorders.application.ordertable.port.out.OrderTableNewRepository; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class EatinOrderServiceConfig { + + @Bean + public EatinOrderUseCase eatinOrderUseCase(final EatinOrderRepository eatinOrderRepository, + final OrderTableNewRepository orderTableRepository, + final ValidMenuPort validMenuPort) { + + return new DefaultEatinOrderService(eatinOrderRepository, + orderTableRepository, validMenuPort); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/config/OrderTableServiceConfig.java b/src/main/java/kitchenpos/eatinorders/config/OrderTableServiceConfig.java new file mode 100644 index 000000000..ee0e5fbcf --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/config/OrderTableServiceConfig.java @@ -0,0 +1,26 @@ +package kitchenpos.eatinorders.config; + +import kitchenpos.eatinorders.application.ordertable.DefaultOrderTableCreationService; +import kitchenpos.eatinorders.application.ordertable.DefaultOrderTableSitService; +import kitchenpos.eatinorders.application.ordertable.port.in.OrderTableCreationUseCase; +import kitchenpos.eatinorders.application.ordertable.port.in.OrderTableSitUseCase; +import kitchenpos.eatinorders.application.ordertable.port.out.OrderTableNewRepository; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OrderTableServiceConfig { + + @Bean + public OrderTableCreationUseCase orderTableCreationUseCase( + final OrderTableNewRepository repository) { + + return new DefaultOrderTableCreationService(repository); + } + + @Bean + public OrderTableSitUseCase orderTableSitUseCase(final OrderTableNewRepository repository) { + + return new DefaultOrderTableSitService(repository); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/domain/eatinorder/EatinOrder.java b/src/main/java/kitchenpos/eatinorders/domain/eatinorder/EatinOrder.java new file mode 100644 index 000000000..afe6e5992 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/domain/eatinorder/EatinOrder.java @@ -0,0 +1,143 @@ +package kitchenpos.eatinorders.domain.eatinorder; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import javax.persistence.CascadeType; +import javax.persistence.Column; +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.OneToMany; +import javax.persistence.Table; +import kitchenpos.eatinorders.application.eatinorder.port.out.ValidMenuPort; +import kitchenpos.eatinorders.application.exception.InvalidAcceptStatusException; +import kitchenpos.eatinorders.application.exception.InvalidCompleteStatusException; +import kitchenpos.eatinorders.application.exception.InvalidServeStatusException; +import kitchenpos.eatinorders.application.exception.NotExistOrderTableException; +import kitchenpos.eatinorders.application.ordertable.port.out.OrderTableNewRepository; +import kitchenpos.eatinorders.domain.ordertable.OrderTableNew; +import org.apache.commons.lang3.tuple.Pair; + +@Table(name = "eatin_order") +@Entity +public class EatinOrder { + + @Column(name = "id", columnDefinition = "binary(16)") + @Id + private UUID id; + + @Column(name = "status", nullable = false) + @Enumerated(EnumType.STRING) + private Status status; + + @Column(name = "order_date_time", nullable = false) + private LocalDateTime orderDateTime; + + @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; + + @ManyToOne + @JoinColumn( + name = "order_table_new_id", + columnDefinition = "binary(16)", + foreignKey = @ForeignKey(name = "fk_orders_to_order_table") + ) + private OrderTableNew orderTable; + + protected EatinOrder() { + } + + private EatinOrder(final UUID id, final Status status, final LocalDateTime orderDateTime, + final List orderLineItems, final OrderTableNew orderTable) { + + this.id = id; + this.status = status; + this.orderDateTime = orderDateTime; + this.orderLineItems = orderLineItems; + this.orderTable = orderTable; + } + + /** + * @throws NotExistOrderTableException orderTableId에 해당하는 table이 없을 때 + * @throws IllegalStateException orderLineItem에 있는 menu가 없는 menu일 때 + */ + public static EatinOrder create(final UUID orderTableId, + final List orderLindItemMenuIds, + final List> orderLineItemMenuAndQuantities, + final OrderTableNewRepository orderTableRepository, + final ValidMenuPort validMenuPort) { + + final OrderTableNew orderTable = orderTableRepository.findById(orderTableId) + .orElseThrow(() -> new NotExistOrderTableException(orderTableId)); + + validMenuPort.checkValidMenu(orderLindItemMenuIds); + + final List orderLineItems = + orderLineItemMenuAndQuantities.stream() + .map(item -> OrderLineItemNew.create(item.getLeft(), item.getRight())) + .collect(Collectors.toUnmodifiableList()); + + return new EatinOrder(UUID.randomUUID(), + Status.WAITING, LocalDateTime.now(), orderLineItems, orderTable); + } + + /** + * @throws InvalidAcceptStatusException accept를 할 수 없는 상태일 때 + */ + public void acceptOrder() { + if (status != Status.WAITING) { + throw new InvalidAcceptStatusException(id, status); + } + + status = Status.ACCEPTED; + } + + /** + * @throws InvalidServeStatusException serve를 할 수 없는 상태일 때 + */ + public void serveOrder() { + if (status != Status.ACCEPTED) { + throw new InvalidServeStatusException(id, status); + } + + status = Status.SERVED; + } + + /** + * @throws InvalidCompleteStatusException complete를 할 수 없는 상태일 때 + */ + public void completeOrder(final OrderTableNewRepository orderTableRepository) { + if (status != Status.SERVED) { + throw new InvalidCompleteStatusException(id, status); + } + + status = Status.COMPLETED; + + orderTable.clear(); + orderTableRepository.save(orderTable); + } + + public UUID getId() { + return id; + } + + public List getOrderLineItems() { + return orderLineItems; + } + + public UUID getOrderTableId() { + return orderTable.getId(); + } +} diff --git a/src/main/java/kitchenpos/eatinorders/domain/eatinorder/OrderLineItemNew.java b/src/main/java/kitchenpos/eatinorders/domain/eatinorder/OrderLineItemNew.java new file mode 100644 index 000000000..a2aace412 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/domain/eatinorder/OrderLineItemNew.java @@ -0,0 +1,45 @@ +package kitchenpos.eatinorders.domain.eatinorder; + +import java.util.UUID; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Table(name = "order_line_item_new") +@Entity +public class OrderLineItemNew { + + @Column(name = "id", columnDefinition = "binary(16)") + @Id + private UUID id; + + private UUID menuId; + + private int quantity; + + protected OrderLineItemNew() { + } + + private OrderLineItemNew(final UUID id, final UUID menuId, final int quantity) { + this.id = id; + this.menuId = menuId; + this.quantity = quantity; + } + + static OrderLineItemNew create(final UUID menuId, final int quantity) { + return new OrderLineItemNew(UUID.randomUUID(), menuId, quantity); + } + + public UUID getId() { + return id; + } + + public UUID getMenuId() { + return menuId; + } + + public int getQuantity() { + return quantity; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/domain/eatinorder/Status.java b/src/main/java/kitchenpos/eatinorders/domain/eatinorder/Status.java new file mode 100644 index 000000000..295b95147 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/domain/eatinorder/Status.java @@ -0,0 +1,5 @@ +package kitchenpos.eatinorders.domain.eatinorder; + +public enum Status { + WAITING, ACCEPTED, SERVED, COMPLETED +} diff --git a/src/main/java/kitchenpos/eatinorders/domain/ordertable/OrderTableNew.java b/src/main/java/kitchenpos/eatinorders/domain/ordertable/OrderTableNew.java new file mode 100644 index 000000000..b2562ff71 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/domain/ordertable/OrderTableNew.java @@ -0,0 +1,78 @@ +package kitchenpos.eatinorders.domain.ordertable; + +import java.util.UUID; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import kitchenpos.support.vo.Name; + +@Table(name = "order_table_new") +@Entity +public class OrderTableNew { + + @Column(name = "id", columnDefinition = "binary(16)") + @Id + private UUID id; + + @Column(name = "name", nullable = false) + private Name name; + + @Column(name = "number_of_guests", nullable = false) + private int numberOfGuests; + + @Column(name = "occustatuspied", nullable = false) + private Status status; + + protected OrderTableNew() { + } + + private OrderTableNew(final UUID id, final Name name, final int numberOfGuests, + final Status status) { + + this.id = id; + this.name = name; + this.numberOfGuests = numberOfGuests; + this.status = status; + } + + public static OrderTableNew create(final Name name) { + + return new OrderTableNew(UUID.randomUUID(), name, 0, Status.EMPTY); + } + + /** + * @throws IllegalArgumentException numberOfGuests가 음수일 때 + * @throws IllegalStateException orderTable이 점유된 상태가 아닐 때 + */ + public void sit(final int numberOfGuests) { + status = Status.NOT_EMPTY; + changeNumberOfGuests(numberOfGuests); + } + + /** + * @throws IllegalArgumentException numberOfGuests가 음수일 때 + * @throws IllegalStateException orderTable이 점유된 상태가 아닐 때 + */ + public void changeNumberOfGuests(final int numberOfGuests) { + if (numberOfGuests < 0) { + throw new IllegalArgumentException("number Of Guests can not be less than zero"); + } + + if (status != Status.NOT_EMPTY) { + throw new IllegalStateException( + "orderTable is not empty. can not change numberOfGuests."); + } + + this.numberOfGuests = numberOfGuests; + } + + public void clear() { + status = Status.EMPTY; + numberOfGuests = 0; + } + + public UUID getId() { + return id; + } +} diff --git a/src/main/java/kitchenpos/eatinorders/domain/ordertable/Status.java b/src/main/java/kitchenpos/eatinorders/domain/ordertable/Status.java new file mode 100644 index 000000000..f008e4706 --- /dev/null +++ b/src/main/java/kitchenpos/eatinorders/domain/ordertable/Status.java @@ -0,0 +1,5 @@ +package kitchenpos.eatinorders.domain.ordertable; + +public enum Status { + EMPTY, NOT_EMPTY +} diff --git a/src/main/java/kitchenpos/product/adapter/out/JpaProductNewRepository.java b/src/main/java/kitchenpos/product/adapter/out/JpaProductNewRepository.java index 3bdddcc90..bd76e6d8f 100644 --- a/src/main/java/kitchenpos/product/adapter/out/JpaProductNewRepository.java +++ b/src/main/java/kitchenpos/product/adapter/out/JpaProductNewRepository.java @@ -1,11 +1,11 @@ package kitchenpos.product.adapter.out; import java.util.UUID; - -import org.springframework.data.jpa.repository.JpaRepository; - import kitchenpos.product.application.port.out.ProductNewRepository; import kitchenpos.product.domain.ProductNew; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface JpaProductNewRepository extends ProductNewRepository, + JpaRepository { -public interface JpaProductNewRepository extends ProductNewRepository, JpaRepository { }