Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

step3 (매장 식사 주문) #246

Open
wants to merge 7 commits into
base: yuhwanwoo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 | 주문에 속하는 수량이 있는 메뉴 |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지속적인 용어사전 업데이트 👍 👍
모델링도 구현하신 것에 맞게 업데이트도 해보면 어떨까요?


### 포장 주문

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
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<DeliveryOrderLineItemDto> orderLineItemRequests = request.getOrderLineItems();

if (Objects.isNull(orderLineItemRequests) || orderLineItemRequests.isEmpty()) {
throw new IllegalArgumentException();
}

List<DeliveryOrderLineItem> 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<DeliveryOrderDto> findAll() {
return ConvertUtil.convertList(deliveryOrderRepository.findAll(), DeliveryOrderDto.class);
}
}
137 changes: 137 additions & 0 deletions src/main/java/kitchenpos/deliveryorders/domain/DeliveryOrder.java
Original file line number Diff line number Diff line change
@@ -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;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

각각의 주문별로 바운디드 컨텍스트로 나누고 각각의 Table 도 분리해주신 것으로 보여져요. 😄
그렇다면 OrderType 을 제거해보는 것은 어떤가요?


@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<Menu> 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<DeliveryOrderLineItem> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading