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

3단계 - 리팩터링(매장 식사 주문) #240

Open
wants to merge 4 commits into
base: saerang
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package kitchenpos.eatinorders.tobe.application;

import kitchenpos.eatinorders.domain.OrderStatus;
import kitchenpos.eatinorders.tobe.application.dto.TobeOrderCreateRequest;
import kitchenpos.eatinorders.tobe.application.dto.TobeOrderCreateResponse;
import kitchenpos.eatinorders.tobe.application.dto.TobeOrderLineItemRequest;
import kitchenpos.eatinorders.tobe.application.dto.TobeOrderResponse;
import kitchenpos.eatinorders.tobe.domain.OrderMenu;
import kitchenpos.eatinorders.tobe.domain.TobeMenuClient;
import kitchenpos.eatinorders.tobe.domain.TobeOrder;
import kitchenpos.eatinorders.tobe.domain.TobeOrderLineItem;
import kitchenpos.eatinorders.tobe.domain.TobeOrderLineItems;
import kitchenpos.eatinorders.tobe.domain.TobeOrderRepository;
import kitchenpos.eatinorders.tobe.domain.TobeOrderTableRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class TobeOrderService {
private final TobeOrderRepository orderRepository;
private final TobeMenuClient tobeMenuClient;
private final TobeOrderTableRepository orderTableRepository;

public TobeOrderService(
final TobeOrderRepository orderRepository,
final TobeMenuClient tobeMenuClient,
final TobeOrderTableRepository orderTableRepository
) {
this.orderRepository = orderRepository;
this.tobeMenuClient = tobeMenuClient;
this.orderTableRepository = orderTableRepository;
}

@Transactional
public TobeOrderCreateResponse create(final TobeOrderCreateRequest request) {
TobeOrderLineItems tobeOrderLineItems = getTobeOrderLineItem(request.getOrderLineItems());
final TobeOrderTable orderTable = orderTableRepository.findById(request.getOrderTableId())
.orElseThrow(NoSuchElementException::new);
orderTable.validateCreateOrder();

TobeOrder order = new TobeOrder(UUID.randomUUID(), OrderStatus.WAITING, LocalDateTime.now(), orderTable.getId(),
tobeOrderLineItems);
TobeOrder savedOrder = orderRepository.save(order);
return TobeOrderCreateResponse.from(savedOrder);
}

private TobeOrderLineItems getTobeOrderLineItem(final List<TobeOrderLineItemRequest> requests) {
if (Objects.isNull(requests) || requests.isEmpty()) {
throw new IllegalArgumentException();
}

List<TobeOrderLineItem> tobeOrderLineItems = requests.stream().map(it -> {
final OrderMenu orderMenu = tobeMenuClient.getOrderMenu(it.getMenuId());
if (!orderMenu.isDisplayed()) {
throw new IllegalStateException();
}
if (orderMenu.getMenuPrice().compareTo(it.getPrice()) != 0) {
throw new IllegalArgumentException();
}
return new TobeOrderLineItem(it.getQuantity(), orderMenu.getId(), orderMenu.getMenuPrice());
}).collect(Collectors.toList());

return new TobeOrderLineItems(tobeOrderLineItems);
}

@Transactional
public TobeOrderResponse accept(final UUID orderId) {
final TobeOrder order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);
order.accept();

return TobeOrderResponse.from(order);
}

@Transactional
public TobeOrderResponse serve(final UUID orderId) {
final TobeOrder order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);

order.served();

return TobeOrderResponse.from(order);
}

@Transactional
public TobeOrderResponse complete(final UUID orderId) {
final TobeOrder order = orderRepository.findById(orderId)
.orElseThrow(NoSuchElementException::new);
order.completed();

TobeOrderTable orderTable = orderTableRepository.findById(order.getOrderTableId()).orElseThrow();
if (!orderRepository.existsByOrderTableAndStatusNot(orderTable, OrderStatus.COMPLETED)) {
orderTable.setNumberOfGuests(0);
orderTable.setOccupied(false);
}
return TobeOrderResponse.from(order);
}

@Transactional(readOnly = true)
public List<TobeOrderResponse> findAll() {
return orderRepository.findAll().stream().map(TobeOrderResponse::from).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package kitchenpos.eatinorders.tobe.application;

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 TobeOrderTable {
@Column(name = "id", columnDefinition = "binary(16)")
Comment on lines +8 to +12

Choose a reason for hiding this comment

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

orderTable은 따로 리팩터링 하지 않은 이유가 있으신가요?
패키지도 신경써보면 좋을 것 같아요. application layer로 보이네요.

@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;

protected TobeOrderTable() {
}

public TobeOrderTable(final UUID id, final String name, final int numberOfGuests, final boolean occupied) {
this.id = id;
this.name = name;
this.numberOfGuests = numberOfGuests;
this.occupied = occupied;
}

public void validateCreateOrder() {
if (!this.occupied) {
throw new IllegalStateException();
}
}

public UUID getId() {
return id;
}

public void setId(final UUID id) {
this.id = id;
}
Comment on lines +44 to +47

Choose a reason for hiding this comment

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

setter는 제거해 보면 좋을 것 같습니다.


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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package kitchenpos.eatinorders.tobe.application.dto;

import kitchenpos.eatinorders.domain.OrderStatus;
import kitchenpos.eatinorders.tobe.domain.TobeOrderLineItem;
import kitchenpos.eatinorders.tobe.domain.TobeOrderLineItems;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

public class TobeOrderCreateRequest {
private final UUID id;
private final OrderStatus status;
private final LocalDateTime orderDateTime;
private final List<TobeOrderLineItemRequest> orderLineItems;
private final UUID orderTableId;

public TobeOrderCreateRequest(final UUID id, final OrderStatus status, final LocalDateTime orderDateTime,
final List<TobeOrderLineItemRequest> orderLineItems,
final UUID orderTableId) {
this.id = id;
this.status = status;
this.orderDateTime = orderDateTime;
this.orderLineItems = orderLineItems;
this.orderTableId = orderTableId;
}

public TobeOrderLineItems tobeOrderLineItems() {
return new TobeOrderLineItems(orderLineItems.stream()
.map(TobeOrderLineItemRequest::toDomain)
.collect(Collectors.toList()));
}

public UUID getId() {
return id;
}

public OrderStatus getStatus() {
return status;
}

public List<TobeOrderLineItemRequest> getOrderLineItems() {
return orderLineItems;
}

public UUID getOrderTableId() {
return orderTableId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package kitchenpos.eatinorders.tobe.application.dto;

import kitchenpos.eatinorders.domain.OrderStatus;
import kitchenpos.eatinorders.tobe.domain.TobeOrder;
import kitchenpos.eatinorders.tobe.domain.TobeOrderLineItem;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

public class TobeOrderCreateResponse {
private final UUID id;
private final OrderStatus status;
private final LocalDateTime orderDateTime;
private final List<TobeOrderLineItemResponse> orderLineItems;
private final UUID orderTableId;

public static class TobeOrderLineItemResponse {
private final UUID menuId;
private final long quantity;
private final BigDecimal price;

public TobeOrderLineItemResponse(final UUID menuId, final long quantity, final BigDecimal price) {
this.menuId = menuId;
this.quantity = quantity;
this.price = price;
}

public static TobeOrderCreateResponse.TobeOrderLineItemResponse from(TobeOrderLineItem item) {
return new TobeOrderCreateResponse.TobeOrderLineItemResponse(item.getMenuId(), item.getQuantity(), item.getPrice());
}

public UUID getMenuId() {
return menuId;
}

public long getQuantity() {
return quantity;
}

public BigDecimal getPrice() {
return price;
}
}

public TobeOrderCreateResponse(final UUID id, final OrderStatus status, final LocalDateTime orderDateTime,
final List<TobeOrderLineItemResponse> orderLineItems,
final UUID orderTableId) {
this.id = id;
this.status = status;
this.orderDateTime = orderDateTime;
this.orderLineItems = orderLineItems;
this.orderTableId = orderTableId;
}

public static TobeOrderCreateResponse from(TobeOrder tobeOrder) {
return new TobeOrderCreateResponse(tobeOrder.getId(), tobeOrder.getStatus(), tobeOrder.getOrderDateTime(),
tobeOrder.getOrderLineItemsStream()
.map(TobeOrderLineItemResponse::from)
.collect(Collectors.toList()), tobeOrder.getOrderTableId());

}

public UUID getId() {
return id;
}

public OrderStatus getStatus() {
return status;
}

public LocalDateTime getOrderDateTime() {
return orderDateTime;
}

public List<TobeOrderLineItemResponse> getOrderLineItems() {
return orderLineItems;
}

public UUID getOrderTableId() {
return orderTableId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package kitchenpos.eatinorders.tobe.application.dto;

import kitchenpos.eatinorders.tobe.domain.TobeOrderLineItem;

import java.math.BigDecimal;
import java.util.UUID;

public class TobeOrderLineItemRequest {
private final Long seq;
private final UUID menuId;
private final long quantity;
private final BigDecimal price;

public TobeOrderLineItemRequest(final Long seq, final UUID menuId, final long quantity, final BigDecimal price) {
this.seq = seq;
this.menuId = menuId;
this.quantity = quantity;
this.price = price;
}

public static TobeOrderLineItemRequest from(TobeOrderLineItem item) {
return new TobeOrderLineItemRequest(item.getSeq(), item.getMenuId(), item.getQuantity(), item.getPrice());
}

public TobeOrderLineItem toDomain() {
return new TobeOrderLineItem(this.seq, this.quantity, this.menuId, this.price);
}

public UUID getMenuId() {
return menuId;
}

public long getQuantity() {
return quantity;
}

public BigDecimal getPrice() {
return price;
}
}
Loading