diff --git a/README.md b/README.md index 61e6211a9..ecbd2fe3b 100644 --- a/README.md +++ b/README.md @@ -98,22 +98,23 @@ docker compose -p kitchenpos up -d ### 상품 -| 한글명 | 영문명 | 설명 | -| --- | --- | --- | -| 상품 | product | 메뉴를 관리하는 기준이 되는 데이터 | +| 한글명 | 영문명 | 설명 | +| --- |----------------| --- | +| 상품 | product | 메뉴를 관리하는 기준이 되는 데이터 | | 이름 | displayed name | 음식을 상상하게 만드는 중요한 요소 | ### 메뉴 -| 한글명 | 영문명 | 설명 | -|--------| --- | --- | -| 원래 가격 | original price | 메뉴에 포함된 상품가격 * 수량의 총합. 즉, 메뉴에 포함된 상품들을 메뉴가 아니라 단품으로 모두 시켰을때의 가격의 총합 | -| 금액 | amount | 가격 * 수량 | -| 메뉴 | menu | 메뉴 그룹에 속하는 실제 주문 가능 단위 | -| 메뉴 그룹 | menu group | 각각의 메뉴를 성격에 따라 분류하여 묶어둔 그룹 | -| 메뉴 상품 | menu product | 메뉴에 속하는 수량이 있는 상품 | +| 한글명 | 영문명 | 설명 | +|-------|--------------------| --- | +| 원래 가격 | original price | 메뉴에 포함된 상품가격 * 수량의 총합. 즉, 메뉴에 포함된 상품들을 메뉴가 아니라 단품으로 모두 시켰을때의 가격의 총합 | +| 금액 | amount | 가격 * 수량 | +| 메뉴 | menu | 메뉴 그룹에 속하는 실제 주문 가능 단위 | +| 메뉴 그룹 | menu group | 각각의 메뉴를 성격에 따라 분류하여 묶어둔 그룹 | +| 메뉴 상품 | menuProduct | 메뉴에 속하는 수량이 있는 상품 | +| 포함 상품 | includedProduct | 메뉴 상품에 속하는 가격이 있는 상품 | | 숨겨진 메뉴 | not displayed menu | 주문할 수 없는 숨겨진 메뉴 | -| 이름 | displayed name | 음식을 상상하게 만드는 중요한 요소 | +| 이름 | displayed name | 음식을 상상하게 만드는 중요한 요소 | ### 매장 주문 diff --git a/src/main/java/kitchenpos/products/tobe/domain/infra/PurgomalumValidator.java b/src/main/java/kitchenpos/common/domain/infra/PurgomalumValidator.java similarity index 64% rename from src/main/java/kitchenpos/products/tobe/domain/infra/PurgomalumValidator.java rename to src/main/java/kitchenpos/common/domain/infra/PurgomalumValidator.java index 27bd7af3d..88afc7c03 100644 --- a/src/main/java/kitchenpos/products/tobe/domain/infra/PurgomalumValidator.java +++ b/src/main/java/kitchenpos/common/domain/infra/PurgomalumValidator.java @@ -1,4 +1,4 @@ -package kitchenpos.products.tobe.domain.infra; +package kitchenpos.common.domain.infra; public interface PurgomalumValidator { boolean containsProfanity(String text); diff --git a/src/main/java/kitchenpos/products/tobe/domain/vo/ProductName.java b/src/main/java/kitchenpos/common/domain/vo/Name.java similarity index 66% rename from src/main/java/kitchenpos/products/tobe/domain/vo/ProductName.java rename to src/main/java/kitchenpos/common/domain/vo/Name.java index a09bfb1a1..3e6df98ed 100644 --- a/src/main/java/kitchenpos/products/tobe/domain/vo/ProductName.java +++ b/src/main/java/kitchenpos/common/domain/vo/Name.java @@ -1,17 +1,17 @@ -package kitchenpos.products.tobe.domain.vo; +package kitchenpos.common.domain.vo; -import kitchenpos.products.tobe.domain.infra.PurgomalumValidator; +import kitchenpos.common.domain.infra.PurgomalumValidator; import javax.persistence.Column; import javax.persistence.Embeddable; import java.util.Objects; @Embeddable -public class ProductName { - @Column(name = "name", nullable = false) +public class Name { + @Column() private String name; - public ProductName(String name, PurgomalumValidator purgomalumValidator) { + public Name(String name, PurgomalumValidator purgomalumValidator) { if (Objects.isNull(name) || purgomalumValidator.containsProfanity(name)) { throw new IllegalArgumentException(); } @@ -23,13 +23,13 @@ public String getName() { return name; } - protected ProductName() {} + protected Name() {} @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - ProductName that = (ProductName) o; + Name that = (Name) o; return Objects.equals(name, that.name); } diff --git a/src/main/java/kitchenpos/products/tobe/domain/vo/ProductPrice.java b/src/main/java/kitchenpos/common/domain/vo/Price.java similarity index 75% rename from src/main/java/kitchenpos/products/tobe/domain/vo/ProductPrice.java rename to src/main/java/kitchenpos/common/domain/vo/Price.java index b0c847989..d00ffe397 100644 --- a/src/main/java/kitchenpos/products/tobe/domain/vo/ProductPrice.java +++ b/src/main/java/kitchenpos/common/domain/vo/Price.java @@ -1,4 +1,4 @@ -package kitchenpos.products.tobe.domain.vo; +package kitchenpos.common.domain.vo; import javax.persistence.Column; import javax.persistence.Embeddable; @@ -6,13 +6,13 @@ import java.util.Objects; @Embeddable -public class ProductPrice { +public class Price { static final BigDecimal MIN_PRICE = BigDecimal.ZERO; - @Column(name = "price", nullable = false) + @Column() private BigDecimal price; - public ProductPrice(BigDecimal price) { + public Price(BigDecimal price) { if (Objects.isNull(price) || MIN_PRICE.compareTo(price) > 0) { throw new IllegalArgumentException(); } @@ -24,13 +24,13 @@ public BigDecimal getPrice() { return price; } - protected ProductPrice() {} + protected Price() {} @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - ProductPrice that = (ProductPrice) o; + Price that = (Price) o; return Objects.equals(price, that.price); } diff --git a/src/main/java/kitchenpos/products/infra/DefaultPurgomalumValidator.java b/src/main/java/kitchenpos/common/infra/DefaultPurgomalumValidator.java similarity index 89% rename from src/main/java/kitchenpos/products/infra/DefaultPurgomalumValidator.java rename to src/main/java/kitchenpos/common/infra/DefaultPurgomalumValidator.java index 6317fae09..233889735 100644 --- a/src/main/java/kitchenpos/products/infra/DefaultPurgomalumValidator.java +++ b/src/main/java/kitchenpos/common/infra/DefaultPurgomalumValidator.java @@ -1,6 +1,6 @@ -package kitchenpos.products.infra; +package kitchenpos.common.infra; -import kitchenpos.products.tobe.domain.infra.PurgomalumValidator; +import kitchenpos.common.domain.infra.PurgomalumValidator; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; diff --git a/src/main/java/kitchenpos/eatinorders/application/OrderService.java b/src/main/java/kitchenpos/eatinorders/application/OrderService.java index c20f52c7f..4decebb8e 100644 --- a/src/main/java/kitchenpos/eatinorders/application/OrderService.java +++ b/src/main/java/kitchenpos/eatinorders/application/OrderService.java @@ -3,7 +3,7 @@ import kitchenpos.deliveryorders.infra.KitchenridersClient; import kitchenpos.eatinorders.domain.*; import kitchenpos.menus.domain.Menu; -import kitchenpos.menus.domain.MenuRepository; +import kitchenpos.menus.domain.LegacyMenuRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,18 +15,18 @@ @Service public class OrderService { private final OrderRepository orderRepository; - private final MenuRepository menuRepository; + private final LegacyMenuRepository legacyMenuRepository; private final OrderTableRepository orderTableRepository; private final KitchenridersClient kitchenridersClient; public OrderService( final OrderRepository orderRepository, - final MenuRepository menuRepository, + final LegacyMenuRepository legacyMenuRepository, final OrderTableRepository orderTableRepository, final KitchenridersClient kitchenridersClient ) { this.orderRepository = orderRepository; - this.menuRepository = menuRepository; + this.legacyMenuRepository = legacyMenuRepository; this.orderTableRepository = orderTableRepository; this.kitchenridersClient = kitchenridersClient; } @@ -41,7 +41,7 @@ public Order create(final Order request) { if (Objects.isNull(orderLineItemRequests) || orderLineItemRequests.isEmpty()) { throw new IllegalArgumentException(); } - final List menus = menuRepository.findAllByIdIn( + final List menus = legacyMenuRepository.findAllByIdIn( orderLineItemRequests.stream() .map(OrderLineItem::getMenuId) .collect(Collectors.toList()) @@ -57,7 +57,7 @@ public Order create(final Order request) { throw new IllegalArgumentException(); } } - final Menu menu = menuRepository.findById(orderLineItemRequest.getMenuId()) + final Menu menu = legacyMenuRepository.findById(orderLineItemRequest.getMenuId()) .orElseThrow(NoSuchElementException::new); if (!menu.isDisplayed()) { throw new IllegalStateException(); diff --git a/src/main/java/kitchenpos/menus/application/ChangePriceService.java b/src/main/java/kitchenpos/menus/application/ChangePriceService.java new file mode 100644 index 000000000..cb10a1616 --- /dev/null +++ b/src/main/java/kitchenpos/menus/application/ChangePriceService.java @@ -0,0 +1,31 @@ +package kitchenpos.menus.application; + +import kitchenpos.common.domain.vo.Price; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import kitchenpos.menus.ui.dto.ChangePriceRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.NoSuchElementException; +import java.util.UUID; + +@Service +public class ChangePriceService { + private final MenuRepository menuRepository; + + public ChangePriceService(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Transactional + public Menu change(final UUID menuId, final ChangePriceRequest request) { + final Menu menu = menuRepository.findById(menuId) + .orElseThrow(NoSuchElementException::new); + + Price price = new Price(request.price); + menu.changePrice(price); + + return menu; + } +} diff --git a/src/main/java/kitchenpos/menus/application/CreateMenuGroupService.java b/src/main/java/kitchenpos/menus/application/CreateMenuGroupService.java new file mode 100644 index 000000000..88694f945 --- /dev/null +++ b/src/main/java/kitchenpos/menus/application/CreateMenuGroupService.java @@ -0,0 +1,24 @@ +package kitchenpos.menus.application; + +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.tobe.domain.repository.MenuGroupRepository; +import kitchenpos.menus.tobe.domain.vo.MenuGroupName; +import kitchenpos.menus.ui.dto.CreateMenuGroupRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class CreateMenuGroupService { + private final MenuGroupRepository menuGroupRepository; + + public CreateMenuGroupService(MenuGroupRepository menuGroupRepository) { + this.menuGroupRepository = menuGroupRepository; + } + + @Transactional + public MenuGroup create(final CreateMenuGroupRequest request) { + MenuGroupName menuGroupName = new MenuGroupName(request.name); + final MenuGroup menuGroup = new MenuGroup(menuGroupName); + return menuGroupRepository.save(menuGroup); + } +} diff --git a/src/main/java/kitchenpos/menus/application/CreateMenuService.java b/src/main/java/kitchenpos/menus/application/CreateMenuService.java new file mode 100644 index 000000000..6f1afa11c --- /dev/null +++ b/src/main/java/kitchenpos/menus/application/CreateMenuService.java @@ -0,0 +1,58 @@ +package kitchenpos.menus.application; + +import kitchenpos.common.domain.infra.PurgomalumValidator; +import kitchenpos.common.domain.vo.Name; +import kitchenpos.common.domain.vo.Price; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.tobe.domain.entity.MenuProduct; +import kitchenpos.menus.tobe.domain.entity.IncludedProduct; +import kitchenpos.menus.tobe.domain.repository.MenuGroupRepository; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import kitchenpos.menus.tobe.domain.repository.IncludedProductRepository; +import kitchenpos.menus.tobe.domain.vo.MenuProductQuantity; +import kitchenpos.menus.ui.dto.CreateMenuRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class CreateMenuService { + private final MenuGroupRepository menuGroupRepository; + private final PurgomalumValidator purgomalumValidator; + private final IncludedProductRepository includedProductRepository; + private final MenuRepository menuRepository; + + public CreateMenuService( + MenuGroupRepository menuGroupRepository, + PurgomalumValidator purgomalumValidator, + IncludedProductRepository includedProductRepository, + MenuRepository menuRepository + ) { + this.menuGroupRepository = menuGroupRepository; + this.purgomalumValidator = purgomalumValidator; + this.includedProductRepository = includedProductRepository; + this.menuRepository = menuRepository; + } + + @Transactional + public Menu create(final CreateMenuRequest request) { + final MenuGroup menuGroup = menuGroupRepository.findById(request.menuGroupId) + .orElseThrow(IllegalArgumentException::new); + + Name name = new Name(request.name, purgomalumValidator); + final Price price = new Price(request.price); + final Menu menu = new Menu(price, name, request.isDisplayed, menuGroup); + + for (final CreateMenuRequest.CreateMenuProductRequest menuProductRequest : request.createMenuProductRequests) { + final IncludedProduct includedProduct = includedProductRepository.findById(menuProductRequest.productId) + .orElseThrow(IllegalArgumentException::new); + final MenuProductQuantity quantity = new MenuProductQuantity(menuProductRequest.quantity); + final MenuProduct menuProduct = new MenuProduct( + quantity, includedProduct + ); + menu.registerMenuProduct(menuProduct); + } + + return menuRepository.save(menu); + } +} diff --git a/src/main/java/kitchenpos/menus/application/DisplayMenuService.java b/src/main/java/kitchenpos/menus/application/DisplayMenuService.java new file mode 100644 index 000000000..452e0914f --- /dev/null +++ b/src/main/java/kitchenpos/menus/application/DisplayMenuService.java @@ -0,0 +1,28 @@ +package kitchenpos.menus.application; + +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.NoSuchElementException; +import java.util.UUID; + +@Service +public class DisplayMenuService { + private final MenuRepository menuRepository; + + public DisplayMenuService(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Transactional + public Menu display(final UUID menuId) { + final Menu menu = menuRepository.findById(menuId) + .orElseThrow(NoSuchElementException::new); + + menu.display(); + + return menu; + } +} diff --git a/src/main/java/kitchenpos/menus/application/FindAllMenuGroupService.java b/src/main/java/kitchenpos/menus/application/FindAllMenuGroupService.java new file mode 100644 index 000000000..3f4a7c0ff --- /dev/null +++ b/src/main/java/kitchenpos/menus/application/FindAllMenuGroupService.java @@ -0,0 +1,23 @@ +package kitchenpos.menus.application; + +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.tobe.domain.repository.MenuGroupRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class FindAllMenuGroupService { + private final MenuGroupRepository menuGroupRepository; + + public FindAllMenuGroupService(MenuGroupRepository menuGroupRepository) { + this.menuGroupRepository = menuGroupRepository; + } + + + @Transactional(readOnly = true) + public List findAll() { + return menuGroupRepository.findAll(); + } +} diff --git a/src/main/java/kitchenpos/menus/application/FindAllMenuService.java b/src/main/java/kitchenpos/menus/application/FindAllMenuService.java new file mode 100644 index 000000000..15d94bbd6 --- /dev/null +++ b/src/main/java/kitchenpos/menus/application/FindAllMenuService.java @@ -0,0 +1,22 @@ +package kitchenpos.menus.application; + +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class FindAllMenuService { + private final MenuRepository menuRepository; + + public FindAllMenuService(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Transactional(readOnly = true) + public List findAll() { + return menuRepository.findAll(); + } +} diff --git a/src/main/java/kitchenpos/menus/application/HideMenuService.java b/src/main/java/kitchenpos/menus/application/HideMenuService.java new file mode 100644 index 000000000..93964aa75 --- /dev/null +++ b/src/main/java/kitchenpos/menus/application/HideMenuService.java @@ -0,0 +1,26 @@ +package kitchenpos.menus.application; + +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.NoSuchElementException; +import java.util.UUID; + +@Service +public class HideMenuService { + private final MenuRepository menuRepository; + + public HideMenuService(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Transactional + public Menu hide(final UUID menuId) { + final Menu menu = menuRepository.findById(menuId) + .orElseThrow(NoSuchElementException::new); + menu.hide(); + return menu; + } +} diff --git a/src/main/java/kitchenpos/menus/application/MenuGroupService.java b/src/main/java/kitchenpos/menus/application/MenuGroupService.java deleted file mode 100644 index c468893a2..000000000 --- a/src/main/java/kitchenpos/menus/application/MenuGroupService.java +++ /dev/null @@ -1,36 +0,0 @@ -package kitchenpos.menus.application; - -import kitchenpos.menus.domain.MenuGroup; -import kitchenpos.menus.domain.MenuGroupRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Objects; -import java.util.UUID; - -@Service -public class MenuGroupService { - private final MenuGroupRepository menuGroupRepository; - - public MenuGroupService(final MenuGroupRepository menuGroupRepository) { - this.menuGroupRepository = menuGroupRepository; - } - - @Transactional - public MenuGroup create(final MenuGroup request) { - final String name = request.getName(); - if (Objects.isNull(name) || name.isEmpty()) { - throw new IllegalArgumentException(); - } - final MenuGroup menuGroup = new MenuGroup(); - menuGroup.setId(UUID.randomUUID()); - menuGroup.setName(name); - return menuGroupRepository.save(menuGroup); - } - - @Transactional(readOnly = true) - public List findAll() { - return menuGroupRepository.findAll(); - } -} diff --git a/src/main/java/kitchenpos/menus/application/MenuService.java b/src/main/java/kitchenpos/menus/application/MenuService.java deleted file mode 100644 index 88297fae4..000000000 --- a/src/main/java/kitchenpos/menus/application/MenuService.java +++ /dev/null @@ -1,145 +0,0 @@ -package kitchenpos.menus.application; - -import kitchenpos.menus.domain.*; -import kitchenpos.products.tobe.domain.infra.PurgomalumValidator; -import kitchenpos.products.tobe.domain.entity.Product; -import kitchenpos.products.tobe.domain.repository.ProductRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class MenuService { - private final MenuRepository menuRepository; - private final MenuGroupRepository menuGroupRepository; - private final ProductRepository productRepository; - private final PurgomalumValidator purgomalumValidator; - - public MenuService( - final MenuRepository menuRepository, - final MenuGroupRepository menuGroupRepository, - final ProductRepository productRepository, - final PurgomalumValidator purgomalumValidator - ) { - this.menuRepository = menuRepository; - this.menuGroupRepository = menuGroupRepository; - this.productRepository = productRepository; - this.purgomalumValidator = purgomalumValidator; - } - - @Transactional - public Menu create(final Menu request) { - final BigDecimal price = request.getPrice(); - if (Objects.isNull(price) || price.compareTo(BigDecimal.ZERO) < 0) { - throw new IllegalArgumentException(); - } - final MenuGroup menuGroup = menuGroupRepository.findById(request.getMenuGroupId()) - .orElseThrow(NoSuchElementException::new); - final List menuProductRequests = request.getMenuProducts(); - if (Objects.isNull(menuProductRequests) || menuProductRequests.isEmpty()) { - throw new IllegalArgumentException(); - } - final List products = productRepository.findAllByIdIn( - menuProductRequests.stream() - .map(MenuProduct::getProductId) - .collect(Collectors.toList()) - ); - if (products.size() != menuProductRequests.size()) { - throw new IllegalArgumentException(); - } - final List menuProducts = new ArrayList<>(); - BigDecimal sum = BigDecimal.ZERO; - for (final MenuProduct menuProductRequest : menuProductRequests) { - final long quantity = menuProductRequest.getQuantity(); - if (quantity < 0) { - throw new IllegalArgumentException(); - } - final Product product = productRepository.findById(menuProductRequest.getProductId()) - .orElseThrow(NoSuchElementException::new); - sum = sum.add( - product.getPrice() - .getPrice() - .multiply(BigDecimal.valueOf(quantity)) - ); - final MenuProduct menuProduct = new MenuProduct(); - menuProduct.setProduct(product); - menuProduct.setQuantity(quantity); - menuProducts.add(menuProduct); - } - if (price.compareTo(sum) > 0) { - throw new IllegalArgumentException(); - } - final String name = request.getName(); - if (Objects.isNull(name) || purgomalumValidator.containsProfanity(name)) { - throw new IllegalArgumentException(); - } - final Menu menu = new Menu(); - menu.setId(UUID.randomUUID()); - menu.setName(name); - menu.setPrice(price); - menu.setMenuGroup(menuGroup); - menu.setDisplayed(request.isDisplayed()); - menu.setMenuProducts(menuProducts); - return menuRepository.save(menu); - } - - @Transactional - public Menu changePrice(final UUID menuId, final Menu request) { - final BigDecimal price = request.getPrice(); - if (Objects.isNull(price) || price.compareTo(BigDecimal.ZERO) < 0) { - throw new IllegalArgumentException(); - } - final Menu menu = menuRepository.findById(menuId) - .orElseThrow(NoSuchElementException::new); - BigDecimal sum = BigDecimal.ZERO; - for (final MenuProduct menuProduct : menu.getMenuProducts()) { - sum = sum.add( - menuProduct.getProduct() - .getPrice() - .getPrice() - .multiply(BigDecimal.valueOf(menuProduct.getQuantity())) - ); - } - if (price.compareTo(sum) > 0) { - throw new IllegalArgumentException(); - } - menu.setPrice(price); - return menu; - } - - @Transactional - public Menu display(final UUID menuId) { - final Menu menu = menuRepository.findById(menuId) - .orElseThrow(NoSuchElementException::new); - BigDecimal sum = BigDecimal.ZERO; - for (final MenuProduct menuProduct : menu.getMenuProducts()) { - sum = sum.add( - menuProduct.getProduct() - .getPrice() - .getPrice() - .multiply(BigDecimal.valueOf(menuProduct.getQuantity())) - ); - } - if (menu.getPrice().compareTo(sum) > 0) { - throw new IllegalStateException(); - } - menu.setDisplayed(true); - return menu; - } - - @Transactional - public Menu hide(final UUID menuId) { - final Menu menu = menuRepository.findById(menuId) - .orElseThrow(NoSuchElementException::new); - menu.setDisplayed(false); - return menu; - } - - @Transactional(readOnly = true) - public List findAll() { - return menuRepository.findAll(); - } -} diff --git a/src/main/java/kitchenpos/menus/domain/JpaMenuRepository.java b/src/main/java/kitchenpos/menus/domain/JpaLegacyMenuRepository.java similarity index 81% rename from src/main/java/kitchenpos/menus/domain/JpaMenuRepository.java rename to src/main/java/kitchenpos/menus/domain/JpaLegacyMenuRepository.java index 796499c30..c677c6bcd 100644 --- a/src/main/java/kitchenpos/menus/domain/JpaMenuRepository.java +++ b/src/main/java/kitchenpos/menus/domain/JpaLegacyMenuRepository.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.UUID; -public interface JpaMenuRepository extends MenuRepository, JpaRepository { +public interface JpaLegacyMenuRepository extends LegacyMenuRepository, JpaRepository { @Query("select m from Menu m join m.menuProducts mp where mp.product.id = :productId") @Override List findAllByProductId(@Param("productId") UUID productId); diff --git a/src/main/java/kitchenpos/menus/domain/MenuRepository.java b/src/main/java/kitchenpos/menus/domain/LegacyMenuRepository.java similarity index 88% rename from src/main/java/kitchenpos/menus/domain/MenuRepository.java rename to src/main/java/kitchenpos/menus/domain/LegacyMenuRepository.java index 5fbaab864..792c33c4d 100644 --- a/src/main/java/kitchenpos/menus/domain/MenuRepository.java +++ b/src/main/java/kitchenpos/menus/domain/LegacyMenuRepository.java @@ -4,7 +4,7 @@ import java.util.Optional; import java.util.UUID; -public interface MenuRepository { +public interface LegacyMenuRepository { Menu save(Menu menu); Optional findById(UUID id); diff --git a/src/main/java/kitchenpos/menus/domain/Menu.java b/src/main/java/kitchenpos/menus/domain/Menu.java index c5f973453..5b8484f40 100644 --- a/src/main/java/kitchenpos/menus/domain/Menu.java +++ b/src/main/java/kitchenpos/menus/domain/Menu.java @@ -1,6 +1,6 @@ package kitchenpos.menus.domain; -import kitchenpos.products.tobe.domain.vo.ProductPrice; +import kitchenpos.common.domain.vo.Price; import javax.persistence.*; import java.math.BigDecimal; @@ -46,12 +46,12 @@ public class Menu { public Menu() { } - public ProductPrice originalPrice() { + public Price originalPrice() { BigDecimal sum = BigDecimal.ZERO; for (final MenuProduct menuProduct : this.menuProducts) { sum = sum.add(menuProduct.totalPrice().getPrice()); } - return new ProductPrice(sum); + return new Price(sum); } public boolean isReasonablePrice() { diff --git a/src/main/java/kitchenpos/menus/domain/MenuProduct.java b/src/main/java/kitchenpos/menus/domain/MenuProduct.java index 328d71825..884ce8e66 100644 --- a/src/main/java/kitchenpos/menus/domain/MenuProduct.java +++ b/src/main/java/kitchenpos/menus/domain/MenuProduct.java @@ -1,7 +1,7 @@ package kitchenpos.menus.domain; import kitchenpos.products.tobe.domain.entity.Product; -import kitchenpos.products.tobe.domain.vo.ProductPrice; +import kitchenpos.common.domain.vo.Price; import javax.persistence.*; import java.math.BigDecimal; @@ -32,8 +32,8 @@ public class MenuProduct { public MenuProduct() { } - public ProductPrice totalPrice() { - return new ProductPrice(product.getPrice().getPrice().multiply(BigDecimal.valueOf(quantity))); + public Price totalPrice() { + return new Price(product.getPrice().getPrice().multiply(BigDecimal.valueOf(quantity))); } public Long getSeq() { diff --git a/src/main/java/kitchenpos/menus/jparepository/JpaIncludedProductRepository.java b/src/main/java/kitchenpos/menus/jparepository/JpaIncludedProductRepository.java new file mode 100644 index 000000000..26dae2758 --- /dev/null +++ b/src/main/java/kitchenpos/menus/jparepository/JpaIncludedProductRepository.java @@ -0,0 +1,10 @@ +package kitchenpos.menus.jparepository; + +import kitchenpos.menus.tobe.domain.entity.IncludedProduct; +import kitchenpos.menus.tobe.domain.repository.IncludedProductRepository; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface JpaIncludedProductRepository extends JpaRepository, IncludedProductRepository { +} diff --git a/src/main/java/kitchenpos/menus/jparepository/JpaMenuGroupRepository.java b/src/main/java/kitchenpos/menus/jparepository/JpaMenuGroupRepository.java new file mode 100644 index 000000000..89a62b392 --- /dev/null +++ b/src/main/java/kitchenpos/menus/jparepository/JpaMenuGroupRepository.java @@ -0,0 +1,10 @@ +package kitchenpos.menus.jparepository; + +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.tobe.domain.repository.MenuGroupRepository; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface JpaMenuGroupRepository extends JpaRepository, MenuGroupRepository { +} diff --git a/src/main/java/kitchenpos/menus/jparepository/JpaMenuRepository.java b/src/main/java/kitchenpos/menus/jparepository/JpaMenuRepository.java new file mode 100644 index 000000000..c659f3907 --- /dev/null +++ b/src/main/java/kitchenpos/menus/jparepository/JpaMenuRepository.java @@ -0,0 +1,10 @@ +package kitchenpos.menus.jparepository; + +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface JpaMenuRepository extends JpaRepository, MenuRepository { +} diff --git a/src/main/java/kitchenpos/menus/listener/ProductPriceChangedListener.java b/src/main/java/kitchenpos/menus/listener/ProductPriceChangedListener.java new file mode 100644 index 000000000..d0e678246 --- /dev/null +++ b/src/main/java/kitchenpos/menus/listener/ProductPriceChangedListener.java @@ -0,0 +1,23 @@ +package kitchenpos.menus.listener; + +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import kitchenpos.menus.tobe.domain.service.MenuIncludedProductPricePolicy; +import kitchenpos.products.tobe.domain.event.ProductPriceChangedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; + +@Service +public class ProductPriceChangedListener { + private final MenuRepository menuRepository; + + public ProductPriceChangedListener(MenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @EventListener + public void listen(ProductPriceChangedEvent event) { + MenuIncludedProductPricePolicy policy = new MenuIncludedProductPricePolicy(menuRepository); + + policy.whenProductPriceChanged(event.getProductId()); + } +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/entity/IncludedProduct.java b/src/main/java/kitchenpos/menus/tobe/domain/entity/IncludedProduct.java new file mode 100644 index 000000000..9da3c8623 --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/entity/IncludedProduct.java @@ -0,0 +1,32 @@ +package kitchenpos.menus.tobe.domain.entity; + +import kitchenpos.common.domain.vo.Price; + +import javax.persistence.*; +import java.util.UUID; + +@Table(name = "product") +@Entity +public class IncludedProduct { + @Column(name = "id") + @Id + private UUID id; + + @Embedded + @AttributeOverride(name = "price", column = @Column(name = "price", nullable = false)) + private Price price; + + public IncludedProduct(Price price) { + this.price = price; + } + + public Price getPrice() { + return price; + } + + public UUID getId() { + return id; + } + + protected IncludedProduct() {} +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/entity/Menu.java b/src/main/java/kitchenpos/menus/tobe/domain/entity/Menu.java new file mode 100644 index 000000000..86608c599 --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/entity/Menu.java @@ -0,0 +1,120 @@ +package kitchenpos.menus.tobe.domain.entity; + +import kitchenpos.common.domain.vo.Name; +import kitchenpos.common.domain.vo.Price; + +import javax.persistence.*; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Table(name = "menu") +@Entity +public class Menu { + @Column(name = "id") + @Id + private UUID id; + + @Embedded + @AttributeOverride(name = "price", column = @Column(name = "price", nullable = false)) + private Price price; + + @Embedded + @AttributeOverride(name = "name", column = @Column(name = "productName", nullable = false)) + private Name name; + + @Column(name = "displayed", nullable = false) + private boolean displayed; + + @ManyToOne(optional = false) + @JoinColumn( + name = "menu_group_id", + columnDefinition = "binary(16)", + foreignKey = @ForeignKey(name = "fk_menu_to_menu_group") + ) + private MenuGroup menuGroup; + + @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @JoinColumn( + name = "menu_id", + nullable = false, + columnDefinition = "binary(16)", + foreignKey = @ForeignKey(name = "fk_menu_product_to_menu") + ) + private final List menuProducts = new ArrayList<>(); + + public Menu(Price price, Name name, boolean displayed, MenuGroup menuGroup) { + this.id = UUID.randomUUID(); + this.price = price; + this.name = name; + this.displayed = displayed; + this.menuGroup = menuGroup; + } + + public void registerMenuProduct(MenuProduct menuProduct) { + this.menuProducts.add(menuProduct); + + if (! isReasonablePrice()) { + throw new IllegalArgumentException(); + } + } + + public void changePrice(Price price) { + this.price = price; + + if (! isReasonablePrice()) { + throw new IllegalArgumentException(); + } + } + + public boolean isReasonablePrice() { + return price.getPrice().compareTo(originalPrice().getPrice()) <= 0; + } + + private Price originalPrice() { + BigDecimal sum = BigDecimal.ZERO; + for (final MenuProduct menuProduct : this.menuProducts) { + sum = sum.add(menuProduct.totalPrice().getPrice()); + } + return new Price(sum); + } + + public void display() { + if (! isReasonablePrice()) { + throw new IllegalStateException(); + } + + this.displayed = true; + } + + public void hide() { + this.displayed = false; + } + + public UUID getId() { + return id; + } + + public Price getPrice() { + return price; + } + + public Name getName() { + return name; + } + + public boolean isDisplayed() { + return displayed; + } + + public MenuGroup getMenuGroup() { + return menuGroup; + } + + public List getMenuProducts() { + return menuProducts; + } + + protected Menu() {} +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/entity/MenuGroup.java b/src/main/java/kitchenpos/menus/tobe/domain/entity/MenuGroup.java new file mode 100644 index 000000000..44afdbacc --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/entity/MenuGroup.java @@ -0,0 +1,33 @@ +package kitchenpos.menus.tobe.domain.entity; + +import kitchenpos.menus.tobe.domain.vo.MenuGroupName; + +import javax.persistence.*; +import java.util.UUID; + +@Table(name = "menu_group") +@Entity +public class MenuGroup { + @Column(name = "id", columnDefinition = "binary(16)") + @Id + private UUID id; + + @Embedded + @AttributeOverride(name = "name", column = @Column(name = "productName", nullable = false)) + private MenuGroupName name; + + public UUID getId() { + return id; + } + + public MenuGroupName getName() { + return name; + } + + public MenuGroup(MenuGroupName name) { + this.id = UUID.randomUUID(); + this.name = name; + } + + protected MenuGroup() {} +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/entity/MenuProduct.java b/src/main/java/kitchenpos/menus/tobe/domain/entity/MenuProduct.java new file mode 100644 index 000000000..e3314e78c --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/entity/MenuProduct.java @@ -0,0 +1,43 @@ +package kitchenpos.menus.tobe.domain.entity; + +import kitchenpos.common.domain.vo.Price; +import kitchenpos.menus.tobe.domain.vo.MenuProductQuantity; + +import javax.persistence.*; +import java.math.BigDecimal; + +@Table(name = "menu_product") +@Entity +public class MenuProduct { + @Column(name = "seq") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + private Long seq; + + @Embedded + @AttributeOverride(name = "quantity", column = @Column(name = "quantity", nullable = false)) + private MenuProductQuantity quantity; + + @ManyToOne(optional = false) + @JoinColumn( + name = "product_id", + columnDefinition = "binary(16)", + foreignKey = @ForeignKey(name = "fk_menu_product_to_product") + ) + private IncludedProduct includedProduct; + + public MenuProduct(MenuProductQuantity quantity, IncludedProduct includedProduct) { + this.quantity = quantity; + this.includedProduct = includedProduct; + } + + public Price totalPrice() { + return new Price(includedProduct.getPrice().getPrice().multiply(BigDecimal.valueOf(quantity.getQuantity()))); + } + + public IncludedProduct getProduct() { + return includedProduct; + } + + protected MenuProduct() {} +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/repository/IncludedProductRepository.java b/src/main/java/kitchenpos/menus/tobe/domain/repository/IncludedProductRepository.java new file mode 100644 index 000000000..01b41214f --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/repository/IncludedProductRepository.java @@ -0,0 +1,10 @@ +package kitchenpos.menus.tobe.domain.repository; + +import kitchenpos.menus.tobe.domain.entity.IncludedProduct; + +import java.util.Optional; +import java.util.UUID; + +public interface IncludedProductRepository { + Optional findById(UUID id); +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/repository/MenuGroupRepository.java b/src/main/java/kitchenpos/menus/tobe/domain/repository/MenuGroupRepository.java new file mode 100644 index 000000000..7ce76f6db --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/repository/MenuGroupRepository.java @@ -0,0 +1,15 @@ +package kitchenpos.menus.tobe.domain.repository; + +import kitchenpos.menus.tobe.domain.entity.MenuGroup; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface MenuGroupRepository { + MenuGroup save(MenuGroup menuGroup); + + List findAll(); + + Optional findById(UUID id); +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/repository/MenuRepository.java b/src/main/java/kitchenpos/menus/tobe/domain/repository/MenuRepository.java new file mode 100644 index 000000000..4a7fed8c3 --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/repository/MenuRepository.java @@ -0,0 +1,17 @@ +package kitchenpos.menus.tobe.domain.repository; + +import kitchenpos.menus.tobe.domain.entity.Menu; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface MenuRepository { + List findAllByProductId(UUID productId); + + Menu save(Menu menu); + + Optional findById(UUID menuId); + + List findAll(); +} diff --git a/src/main/java/kitchenpos/products/tobe/domain/service/ProductMenuPricePolicy.java b/src/main/java/kitchenpos/menus/tobe/domain/service/MenuIncludedProductPricePolicy.java similarity index 54% rename from src/main/java/kitchenpos/products/tobe/domain/service/ProductMenuPricePolicy.java rename to src/main/java/kitchenpos/menus/tobe/domain/service/MenuIncludedProductPricePolicy.java index 82d056268..bc8ec7cfa 100644 --- a/src/main/java/kitchenpos/products/tobe/domain/service/ProductMenuPricePolicy.java +++ b/src/main/java/kitchenpos/menus/tobe/domain/service/MenuIncludedProductPricePolicy.java @@ -1,19 +1,19 @@ -package kitchenpos.products.tobe.domain.service; +package kitchenpos.menus.tobe.domain.service; -import kitchenpos.menus.domain.Menu; -import kitchenpos.menus.domain.MenuRepository; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; import java.util.List; import java.util.UUID; -public class ProductMenuPricePolicy { +public class MenuIncludedProductPricePolicy { private final MenuRepository menuRepository; - public ProductMenuPricePolicy(MenuRepository menuRepository) { + public MenuIncludedProductPricePolicy(MenuRepository menuRepository) { this.menuRepository = menuRepository; } - public void checkMenuPrice(UUID productId) { + public void whenProductPriceChanged(UUID productId) { List productIncludedMenus = menuRepository.findAllByProductId(productId); for (final Menu menu : productIncludedMenus) { if (! menu.isReasonablePrice()) { diff --git a/src/main/java/kitchenpos/menus/tobe/domain/vo/MenuGroupName.java b/src/main/java/kitchenpos/menus/tobe/domain/vo/MenuGroupName.java new file mode 100644 index 000000000..2b9d3dc25 --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/vo/MenuGroupName.java @@ -0,0 +1,25 @@ +package kitchenpos.menus.tobe.domain.vo; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.util.Objects; + +@Embeddable +public class MenuGroupName { + @Column + private String name; + + public MenuGroupName(String name) { + if (Objects.isNull(name) || name.isEmpty()) { + throw new IllegalArgumentException(); + } + + this.name = name; + } + + public String getName() { + return name; + } + + protected MenuGroupName() {} +} diff --git a/src/main/java/kitchenpos/menus/tobe/domain/vo/MenuProductQuantity.java b/src/main/java/kitchenpos/menus/tobe/domain/vo/MenuProductQuantity.java new file mode 100644 index 000000000..8f39e752a --- /dev/null +++ b/src/main/java/kitchenpos/menus/tobe/domain/vo/MenuProductQuantity.java @@ -0,0 +1,26 @@ +package kitchenpos.menus.tobe.domain.vo; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class MenuProductQuantity { + public static final int MIN_QUANTITY = 0; + + @Column + private long quantity; + + public MenuProductQuantity(long quantity) { + if (quantity < MIN_QUANTITY) { + throw new IllegalArgumentException(); + } + + this.quantity = quantity; + } + + public long getQuantity() { + return quantity; + } + + protected MenuProductQuantity() {} +} diff --git a/src/main/java/kitchenpos/menus/ui/MenuGroupRestController.java b/src/main/java/kitchenpos/menus/ui/MenuGroupRestController.java index 1a5d0fd06..6621d5378 100644 --- a/src/main/java/kitchenpos/menus/ui/MenuGroupRestController.java +++ b/src/main/java/kitchenpos/menus/ui/MenuGroupRestController.java @@ -1,7 +1,9 @@ package kitchenpos.menus.ui; -import kitchenpos.menus.application.MenuGroupService; -import kitchenpos.menus.domain.MenuGroup; +import kitchenpos.menus.application.CreateMenuGroupService; +import kitchenpos.menus.application.FindAllMenuGroupService; +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.ui.dto.CreateMenuGroupRequest; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -11,21 +13,27 @@ @RequestMapping("/api/menu-groups") @RestController public class MenuGroupRestController { - private final MenuGroupService menuGroupService; + private final CreateMenuGroupService createMenuGroupService; - public MenuGroupRestController(final MenuGroupService menuGroupService) { - this.menuGroupService = menuGroupService; + private final FindAllMenuGroupService findAllMenuGroupService; + + public MenuGroupRestController( + CreateMenuGroupService createMenuGroupService, + FindAllMenuGroupService findAllMenuGroupService + ) { + this.createMenuGroupService = createMenuGroupService; + this.findAllMenuGroupService = findAllMenuGroupService; } @PostMapping - public ResponseEntity create(@RequestBody final MenuGroup request) { - final MenuGroup response = menuGroupService.create(request); + public ResponseEntity create(@RequestBody final CreateMenuGroupRequest request) { + final MenuGroup response = createMenuGroupService.create(request); return ResponseEntity.created(URI.create("/api/menu-groups/" + response.getId())) .body(response); } @GetMapping public ResponseEntity> findAll() { - return ResponseEntity.ok(menuGroupService.findAll()); + return ResponseEntity.ok(findAllMenuGroupService.findAll()); } } diff --git a/src/main/java/kitchenpos/menus/ui/MenuRestController.java b/src/main/java/kitchenpos/menus/ui/MenuRestController.java index 3e3a0e23a..0027a3526 100644 --- a/src/main/java/kitchenpos/menus/ui/MenuRestController.java +++ b/src/main/java/kitchenpos/menus/ui/MenuRestController.java @@ -1,47 +1,68 @@ package kitchenpos.menus.ui; -import kitchenpos.menus.application.MenuService; -import kitchenpos.menus.domain.Menu; +import kitchenpos.menus.application.*; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.ui.dto.ChangePriceRequest; +import kitchenpos.menus.ui.dto.CreateMenuRequest; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.net.URI; import java.util.List; +import java.util.Objects; import java.util.UUID; @RequestMapping("/api/menus") @RestController public class MenuRestController { - private final MenuService menuService; + private final CreateMenuService createMenuService; + private final ChangePriceService changePriceService; + private final DisplayMenuService displayMenuService; + private final HideMenuService hideMenuService; + private final FindAllMenuService findAllMenuService; - public MenuRestController(final MenuService menuService) { - this.menuService = menuService; + + public MenuRestController( + final CreateMenuService createMenuService, + final ChangePriceService changePriceService, + final DisplayMenuService displayMenuService, + final HideMenuService hideMenuService, + final FindAllMenuService findAllMenuService + ) { + this.createMenuService = createMenuService; + this.changePriceService = changePriceService; + this.displayMenuService = displayMenuService; + this.hideMenuService = hideMenuService; + this.findAllMenuService = findAllMenuService; } @PostMapping - public ResponseEntity create(@RequestBody final Menu request) { - final Menu response = menuService.create(request); + public ResponseEntity create(@RequestBody final CreateMenuRequest request) { + if (Objects.isNull(request.createMenuProductRequests) || request.createMenuProductRequests.isEmpty()) { + throw new IllegalArgumentException(); + } + final Menu response = createMenuService.create(request); return ResponseEntity.created(URI.create("/api/menus/" + response.getId())) .body(response); } @PutMapping("/{menuId}/price") - public ResponseEntity changePrice(@PathVariable final UUID menuId, @RequestBody final Menu request) { - return ResponseEntity.ok(menuService.changePrice(menuId, request)); + public ResponseEntity changePrice(@PathVariable final UUID menuId, @RequestBody final ChangePriceRequest request) { + return ResponseEntity.ok(changePriceService.change(menuId, request)); } @PutMapping("/{menuId}/display") public ResponseEntity display(@PathVariable final UUID menuId) { - return ResponseEntity.ok(menuService.display(menuId)); + return ResponseEntity.ok(displayMenuService.display(menuId)); } @PutMapping("/{menuId}/hide") public ResponseEntity hide(@PathVariable final UUID menuId) { - return ResponseEntity.ok(menuService.hide(menuId)); + return ResponseEntity.ok(hideMenuService.hide(menuId)); } @GetMapping public ResponseEntity> findAll() { - return ResponseEntity.ok(menuService.findAll()); + return ResponseEntity.ok(findAllMenuService.findAll()); } } diff --git a/src/main/java/kitchenpos/menus/ui/dto/ChangePriceRequest.java b/src/main/java/kitchenpos/menus/ui/dto/ChangePriceRequest.java new file mode 100644 index 000000000..8ec45cb02 --- /dev/null +++ b/src/main/java/kitchenpos/menus/ui/dto/ChangePriceRequest.java @@ -0,0 +1,21 @@ +package kitchenpos.menus.ui.dto; + +import java.math.BigDecimal; +import java.util.Objects; + +public class ChangePriceRequest { + public BigDecimal price; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ChangePriceRequest that = (ChangePriceRequest) o; + return Objects.equals(price, that.price); + } + + @Override + public int hashCode() { + return Objects.hash(price); + } +} diff --git a/src/main/java/kitchenpos/menus/ui/dto/CreateMenuGroupRequest.java b/src/main/java/kitchenpos/menus/ui/dto/CreateMenuGroupRequest.java new file mode 100644 index 000000000..6a188da80 --- /dev/null +++ b/src/main/java/kitchenpos/menus/ui/dto/CreateMenuGroupRequest.java @@ -0,0 +1,20 @@ +package kitchenpos.menus.ui.dto; + +import java.util.Objects; + +public class CreateMenuGroupRequest { + public String name; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CreateMenuGroupRequest that = (CreateMenuGroupRequest) o; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} diff --git a/src/main/java/kitchenpos/menus/ui/dto/CreateMenuRequest.java b/src/main/java/kitchenpos/menus/ui/dto/CreateMenuRequest.java new file mode 100644 index 000000000..dcc12ef9a --- /dev/null +++ b/src/main/java/kitchenpos/menus/ui/dto/CreateMenuRequest.java @@ -0,0 +1,46 @@ +package kitchenpos.menus.ui.dto; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +public class CreateMenuRequest { + public BigDecimal price; + public UUID menuGroupId; + public String name; + public boolean isDisplayed; + public List createMenuProductRequests = new ArrayList<>(); + + public static class CreateMenuProductRequest { + public UUID productId; + public long quantity; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CreateMenuProductRequest that = (CreateMenuProductRequest) o; + return quantity == that.quantity && Objects.equals(productId, that.productId); + } + + @Override + public int hashCode() { + return Objects.hash(productId, quantity); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CreateMenuRequest that = (CreateMenuRequest) o; + return isDisplayed == that.isDisplayed && Objects.equals(price, that.price) && Objects.equals(menuGroupId, that.menuGroupId) && Objects.equals(name, that.name) && Objects.equals(createMenuProductRequests, that.createMenuProductRequests); + } + + @Override + public int hashCode() { + return Objects.hash(price, menuGroupId, name, isDisplayed, createMenuProductRequests); + } +} diff --git a/src/main/java/kitchenpos/products/application/ChangeProductPriceService.java b/src/main/java/kitchenpos/products/application/ChangeProductPriceService.java index dac9c11de..50055b40d 100644 --- a/src/main/java/kitchenpos/products/application/ChangeProductPriceService.java +++ b/src/main/java/kitchenpos/products/application/ChangeProductPriceService.java @@ -1,10 +1,8 @@ package kitchenpos.products.application; -import kitchenpos.menus.domain.MenuRepository; import kitchenpos.products.tobe.domain.entity.Product; import kitchenpos.products.tobe.domain.repository.ProductRepository; -import kitchenpos.products.tobe.domain.service.ProductMenuPricePolicy; -import kitchenpos.products.tobe.domain.vo.ProductPrice; +import kitchenpos.common.domain.vo.Price; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,25 +12,23 @@ @Service public class ChangeProductPriceService { - private final MenuRepository menuRepository; - private final ProductRepository productRepository; public ChangeProductPriceService( - final MenuRepository menuRepository, final ProductRepository productRepository ) { - this.menuRepository = menuRepository; this.productRepository = productRepository; } @Transactional public Product changePrice(final UUID productId, final BigDecimal price) { - final ProductPrice productPrice = new ProductPrice(price); + final Price productPrice = new Price(price); final Product product = productRepository.findById(productId) .orElseThrow(NoSuchElementException::new); - product.changePrice(productPrice, new ProductMenuPricePolicy(menuRepository)); + product.changePrice(productPrice); + + productRepository.save(product); return product; } diff --git a/src/main/java/kitchenpos/products/application/CreateProductService.java b/src/main/java/kitchenpos/products/application/CreateProductService.java index 841c20772..8efba0f7c 100644 --- a/src/main/java/kitchenpos/products/application/CreateProductService.java +++ b/src/main/java/kitchenpos/products/application/CreateProductService.java @@ -1,10 +1,10 @@ package kitchenpos.products.application; -import kitchenpos.products.tobe.domain.infra.PurgomalumValidator; +import kitchenpos.common.domain.vo.Name; +import kitchenpos.common.domain.infra.PurgomalumValidator; import kitchenpos.products.tobe.domain.entity.Product; import kitchenpos.products.tobe.domain.repository.ProductRepository; -import kitchenpos.products.tobe.domain.vo.ProductName; -import kitchenpos.products.tobe.domain.vo.ProductPrice; +import kitchenpos.common.domain.vo.Price; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,8 +26,8 @@ public CreateProductService( @Transactional public Product create(final BigDecimal price, final String name) { - final ProductPrice productPrice = new ProductPrice(price); - final ProductName productName = new ProductName(name, purgomalumValidator); + final Price productPrice = new Price(price); + final Name productName = new Name(name, purgomalumValidator); Product product = new Product(productName, productPrice); diff --git a/src/main/java/kitchenpos/products/application/FindAllProductService.java b/src/main/java/kitchenpos/products/application/FindAllProductService.java index 69d4c697e..83eed2255 100644 --- a/src/main/java/kitchenpos/products/application/FindAllProductService.java +++ b/src/main/java/kitchenpos/products/application/FindAllProductService.java @@ -1,6 +1,5 @@ package kitchenpos.products.application; -import kitchenpos.menus.domain.MenuRepository; import kitchenpos.products.tobe.domain.entity.Product; import kitchenpos.products.tobe.domain.repository.ProductRepository; import org.springframework.stereotype.Service; diff --git a/src/main/java/kitchenpos/products/tobe/domain/entity/Product.java b/src/main/java/kitchenpos/products/tobe/domain/entity/Product.java index 3851d3ff1..5cc019e9a 100644 --- a/src/main/java/kitchenpos/products/tobe/domain/entity/Product.java +++ b/src/main/java/kitchenpos/products/tobe/domain/entity/Product.java @@ -1,45 +1,48 @@ package kitchenpos.products.tobe.domain.entity; -import kitchenpos.products.tobe.domain.service.ProductMenuPricePolicy; -import kitchenpos.products.tobe.domain.vo.ProductName; -import kitchenpos.products.tobe.domain.vo.ProductPrice; +import kitchenpos.products.tobe.domain.event.ProductPriceChangedEvent; +import kitchenpos.common.domain.vo.Name; +import kitchenpos.common.domain.vo.Price; +import org.springframework.data.domain.AbstractAggregateRoot; import javax.persistence.*; import java.util.UUID; @Entity -public class Product { +public class Product extends AbstractAggregateRoot { @Column(name = "id") @Id private UUID id; @Embedded - private ProductName name; + @AttributeOverride(name = "name", column = @Column(name = "productName", nullable = false)) + private Name name; @Embedded - private ProductPrice price; + @AttributeOverride(name = "price", column = @Column(name = "price", nullable = false)) + private Price price; - public Product(ProductName name, ProductPrice price) { + public Product(Name name, Price price) { this.id = UUID.randomUUID(); this.name = name; this.price = price; } - public void changePrice(ProductPrice price, ProductMenuPricePolicy productMenuPricePolicy) { + public void changePrice(Price price) { this.price = price; - productMenuPricePolicy.checkMenuPrice(id); + registerEvent(new ProductPriceChangedEvent(id)); } public UUID getId() { return id; } - public ProductName getName() { + public Name getName() { return name; } - public ProductPrice getPrice() { + public Price getPrice() { return price; } diff --git a/src/main/java/kitchenpos/products/tobe/domain/event/ProductPriceChangedEvent.java b/src/main/java/kitchenpos/products/tobe/domain/event/ProductPriceChangedEvent.java new file mode 100644 index 000000000..fb14ad544 --- /dev/null +++ b/src/main/java/kitchenpos/products/tobe/domain/event/ProductPriceChangedEvent.java @@ -0,0 +1,15 @@ +package kitchenpos.products.tobe.domain.event; + +import java.util.UUID; + +public class ProductPriceChangedEvent { + private final UUID productId; + + public ProductPriceChangedEvent(UUID productId) { + this.productId = productId; + } + + public UUID getProductId() { + return productId; + } +} diff --git a/src/main/resources/db/migration/V1__Initialize_project_tables.sql b/src/main/resources/db/migration/V1__Initialize_project_tables.sql index feb5d03b0..7a162d4a2 100644 --- a/src/main/resources/db/migration/V1__Initialize_project_tables.sql +++ b/src/main/resources/db/migration/V1__Initialize_project_tables.sql @@ -2,7 +2,7 @@ create table menu ( id binary(16) not null, displayed bit not null, - name varchar(255) not null, + productName varchar(255) not null, price decimal(19, 2) not null, menu_group_id binary(16) not null, primary key (id) @@ -11,7 +11,7 @@ create table menu create table menu_group ( id binary(16) not null, - name varchar(255) not null, + productName varchar(255) not null, primary key (id) ) engine = InnoDB; @@ -37,7 +37,7 @@ create table order_table ( id binary(16) not null, occupied bit not null, - name varchar(255) not null, + productName varchar(255) not null, number_of_guests integer not null, primary key (id) ) engine = InnoDB; @@ -56,7 +56,7 @@ create table orders create table product ( id binary(16) not null, - name varchar(255) not null, + productName varchar(255) not null, price decimal(19, 2) not null, primary key (id) ) engine = InnoDB; diff --git a/src/main/resources/db/migration/V2__Insert_default_data.sql b/src/main/resources/db/migration/V2__Insert_default_data.sql index 59ca0714f..b794dbd25 100644 --- a/src/main/resources/db/migration/V2__Insert_default_data.sql +++ b/src/main/resources/db/migration/V2__Insert_default_data.sql @@ -1,36 +1,36 @@ -insert into product (id, name, price) +insert into product (id, productName, price) values (x'3b52824434f7406bbb7e690912f66b10', '후라이드', 16000); -insert into product (id, name, price) +insert into product (id, productName, price) values (x'c5ee925c3dbb4941b825021446f24446', '양념치킨', 16000); -insert into product (id, name, price) +insert into product (id, productName, price) values (x'625c6fc4145d408f8dd533c16ba26064', '반반치킨', 16000); -insert into product (id, name, price) +insert into product (id, productName, price) values (x'4721ee722ff3417fade3acd0a804605b', '통구이', 16000); -insert into product (id, name, price) +insert into product (id, productName, price) values (x'0ac16db71b024a87b9c1e7d8f226c48d', '간장치킨', 17000); -insert into product (id, name, price) +insert into product (id, productName, price) values (x'7de4b8affa0f4391aaa9c61ea9b40f83', '순살치킨', 17000); -insert into menu_group (id, name) +insert into menu_group (id, productName) values (x'f1860abc2ea1411bbd4abaa44f0d5580', '두마리메뉴'); -insert into menu_group (id, name) +insert into menu_group (id, productName) values (x'cbc75faefeb04bb18be2cb8ce5d8fded', '한마리메뉴'); -insert into menu_group (id, name) +insert into menu_group (id, productName) values (x'5e9879b761124791a4cef22e94af8752', '순살파닭두마리메뉴'); -insert into menu_group (id, name) +insert into menu_group (id, productName) values (x'd9bc21accc104593b5064a40e0170e02', '신메뉴'); -insert into menu (id, displayed, name, price, menu_group_id) +insert into menu (id, displayed, productName, price, menu_group_id) values (x'f59b1e1cb145440aaa6f6095a0e2d63b', true, '후라이드치킨', 16000, x'cbc75faefeb04bb18be2cb8ce5d8fded'); -insert into menu (id, displayed, name, price, menu_group_id) +insert into menu (id, displayed, productName, price, menu_group_id) values (x'e1254913860846aab23aa07c1dcbc648', true, '양념치킨', 16000, x'cbc75faefeb04bb18be2cb8ce5d8fded'); -insert into menu (id, displayed, name, price, menu_group_id) +insert into menu (id, displayed, productName, price, menu_group_id) values (x'191fa247b5f34b51b175e65db523f754', true, '반반치킨', 16000, x'cbc75faefeb04bb18be2cb8ce5d8fded'); -insert into menu (id, displayed, name, price, menu_group_id) +insert into menu (id, displayed, productName, price, menu_group_id) values (x'33e558df7d934622b50efcc4282cd184', true, '통구이', 16000, x'cbc75faefeb04bb18be2cb8ce5d8fded'); -insert into menu (id, displayed, name, price, menu_group_id) +insert into menu (id, displayed, productName, price, menu_group_id) values (x'b9c670b04ef5409083496868df1c7d62', true, '간장치킨', 17000, x'cbc75faefeb04bb18be2cb8ce5d8fded'); -insert into menu (id, displayed, name, price, menu_group_id) +insert into menu (id, displayed, productName, price, menu_group_id) values (x'a64af6cac34d4cd882fe454abf512d1f', true, '순살치킨', 17000, x'cbc75faefeb04bb18be2cb8ce5d8fded'); insert into menu_product (quantity, product_id, menu_id) @@ -46,21 +46,21 @@ values (1, x'0ac16db71b024a87b9c1e7d8f226c48d', x'b9c670b04ef5409083496868df1c7d insert into menu_product (quantity, product_id, menu_id) values (1, x'7de4b8affa0f4391aaa9c61ea9b40f83', x'a64af6cac34d4cd882fe454abf512d1f'); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'8d71004329b6420e8452233f5a035520', false, '1번', 0); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'6ab59e8106eb441684e99faabc87c9ca', false, '2번', 0); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'ae92335ccd264626b7979e4ae8c4efbd', false, '3번', 0); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'a9858d4b80d0428881f48f41596a23fb', false, '4번', 0); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'3faec3ab5217405daaa2804f87697f84', false, '5번', 0); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'815b8395a2ad4e3589dc74c3b2191478', false, '6번', 0); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'7ce8b3a235454542ab9cb3d493bbd4fb', false, '7번', 0); -insert into order_table (id, occupied, name, number_of_guests) +insert into order_table (id, occupied, productName, number_of_guests) values (x'7bdb1ffde36e4e2b94e3d2c14d391ef3', false, '8번', 0); insert into orders (id, delivery_address, order_date_time, status, type, order_table_id) diff --git a/src/test/java/kitchenpos/Fixtures.java b/src/test/java/kitchenpos/Fixtures.java index 2c61095a6..eeaab8321 100644 --- a/src/test/java/kitchenpos/Fixtures.java +++ b/src/test/java/kitchenpos/Fixtures.java @@ -1,13 +1,16 @@ package kitchenpos; import kitchenpos.eatinorders.domain.*; -import kitchenpos.menus.domain.Menu; -import kitchenpos.menus.domain.MenuGroup; -import kitchenpos.menus.domain.MenuProduct; +import kitchenpos.menus.tobe.domain.entity.IncludedProduct; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.tobe.domain.entity.MenuProduct; +import kitchenpos.menus.tobe.domain.vo.MenuGroupName; +import kitchenpos.menus.tobe.domain.vo.MenuProductQuantity; import kitchenpos.products.application.FakePurgomalumValidator; import kitchenpos.products.tobe.domain.entity.Product; -import kitchenpos.products.tobe.domain.vo.ProductName; -import kitchenpos.products.tobe.domain.vo.ProductPrice; +import kitchenpos.common.domain.vo.Name; +import kitchenpos.common.domain.vo.Price; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -27,41 +30,38 @@ public static Menu menu(final long price, final MenuProduct... menuProducts) { } public static Menu menu(final long price, final boolean displayed, final MenuProduct... menuProducts) { - final Menu menu = new Menu(); - menu.setId(UUID.randomUUID()); - menu.setName("후라이드+후라이드"); - menu.setPrice(BigDecimal.valueOf(price)); - menu.setMenuGroup(menuGroup()); - menu.setDisplayed(displayed); - menu.setMenuProducts(Arrays.asList(menuProducts)); + Price priceVo = new Price(BigDecimal.valueOf(price)); + + final Menu menu = new Menu(priceVo, new Name("후라이드+후라이드", new FakePurgomalumValidator()), displayed, menuGroup()); + for (MenuProduct menuProduct : menuProducts) { + menu.getMenuProducts().add(menuProduct); + } return menu; } + public static MenuGroup menuGroup() { return menuGroup("두마리메뉴"); } public static MenuGroup menuGroup(final String name) { - final MenuGroup menuGroup = new MenuGroup(); - menuGroup.setId(UUID.randomUUID()); - menuGroup.setName(name); - return menuGroup; + return new MenuGroup(new MenuGroupName(name)); } public static MenuProduct menuProduct() { - final MenuProduct menuProduct = new MenuProduct(); - menuProduct.setSeq(new Random().nextLong()); - menuProduct.setProduct(product()); - menuProduct.setQuantity(2L); - return menuProduct; + return new MenuProduct(new MenuProductQuantity(2L), includedProduct()); + } + + public static MenuProduct menuProduct(final IncludedProduct includedProduct, final long quantity) { + return new MenuProduct(new MenuProductQuantity(quantity), includedProduct); + } + + public static IncludedProduct includedProduct() { + return new IncludedProduct(new Price(BigDecimal.valueOf(16_000L))); } - public static MenuProduct menuProduct(final Product product, final long quantity) { - final MenuProduct menuProduct = new MenuProduct(); - menuProduct.setSeq(new Random().nextLong()); - menuProduct.setProduct(product); - menuProduct.setQuantity(quantity); - return menuProduct; + public static IncludedProduct includedProduct(final long price) { + return new IncludedProduct(new Price(BigDecimal.valueOf(price))); } public static Order order(final OrderStatus status, final String deliveryAddress) { @@ -99,7 +99,7 @@ public static Order order(final OrderStatus status, final OrderTable orderTable) public static OrderLineItem orderLineItem() { final OrderLineItem orderLineItem = new OrderLineItem(); orderLineItem.setSeq(new Random().nextLong()); - orderLineItem.setMenu(menu()); + orderLineItem.setMenu(new kitchenpos.menus.domain.Menu()); return orderLineItem; } @@ -121,6 +121,6 @@ public static Product product() { } public static Product product(final String name, final long price) { - return new Product(new ProductName(name, new FakePurgomalumValidator()), new ProductPrice(BigDecimal.valueOf(price))); + return new Product(new Name(name, new FakePurgomalumValidator()), new Price(BigDecimal.valueOf(price))); } } diff --git a/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java b/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java index 96bf0f286..dfa7cbab8 100644 --- a/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java +++ b/src/test/java/kitchenpos/eatinorders/application/OrderServiceTest.java @@ -1,377 +1,378 @@ -package kitchenpos.eatinorders.application; - -import kitchenpos.eatinorders.domain.*; -import kitchenpos.menus.application.InMemoryMenuRepository; -import kitchenpos.menus.domain.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.menus.application.InMemoryMenuRepository; +//import kitchenpos.menus.domain.LegacyMenuRepository; +//import kitchenpos.menus.tobe.domain.repository.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/menus/application/InMemoryIncludedProductRepository.java b/src/test/java/kitchenpos/menus/application/InMemoryIncludedProductRepository.java new file mode 100644 index 000000000..f1bf42868 --- /dev/null +++ b/src/test/java/kitchenpos/menus/application/InMemoryIncludedProductRepository.java @@ -0,0 +1,23 @@ +package kitchenpos.menus.application; + +import kitchenpos.menus.tobe.domain.entity.IncludedProduct; +import kitchenpos.menus.tobe.domain.repository.IncludedProductRepository; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +public class InMemoryIncludedProductRepository implements IncludedProductRepository { + private final Map includedProducts = new HashMap<>(); + + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(includedProducts.get(id)); + } + + public IncludedProduct save(IncludedProduct includedProduct) { + includedProducts.put(includedProduct.getId(), includedProduct); + return includedProduct; + } +} diff --git a/src/test/java/kitchenpos/menus/application/InMemoryMenuGroupRepository.java b/src/test/java/kitchenpos/menus/application/InMemoryMenuGroupRepository.java index 9b50d73bb..55ca904da 100644 --- a/src/test/java/kitchenpos/menus/application/InMemoryMenuGroupRepository.java +++ b/src/test/java/kitchenpos/menus/application/InMemoryMenuGroupRepository.java @@ -1,7 +1,7 @@ package kitchenpos.menus.application; -import kitchenpos.menus.domain.MenuGroup; -import kitchenpos.menus.domain.MenuGroupRepository; +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.tobe.domain.repository.MenuGroupRepository; import java.util.*; diff --git a/src/test/java/kitchenpos/menus/application/InMemoryMenuRepository.java b/src/test/java/kitchenpos/menus/application/InMemoryMenuRepository.java index 971ded7e3..b6b218768 100644 --- a/src/test/java/kitchenpos/menus/application/InMemoryMenuRepository.java +++ b/src/test/java/kitchenpos/menus/application/InMemoryMenuRepository.java @@ -1,7 +1,7 @@ package kitchenpos.menus.application; -import kitchenpos.menus.domain.Menu; -import kitchenpos.menus.domain.MenuRepository; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; import java.util.*; import java.util.stream.Collectors; @@ -10,34 +10,26 @@ public class InMemoryMenuRepository implements MenuRepository { private final Map menus = new HashMap<>(); @Override - public Menu save(final Menu menu) { + public List findAllByProductId(UUID productId) { + return menus.values() + .stream() + .filter(menu -> menu.getMenuProducts().stream().anyMatch(menuProduct -> menuProduct.getProduct().getId().equals(productId))) + .collect(Collectors.toList()); + } + + @Override + public Menu save(Menu menu) { menus.put(menu.getId(), menu); return menu; } @Override - public Optional findById(final UUID id) { - return Optional.ofNullable(menus.get(id)); + public Optional findById(UUID menuId) { + return Optional.ofNullable(menus.get(menuId)); } @Override public List findAll() { return new ArrayList<>(menus.values()); } - - @Override - public List findAllByIdIn(final List ids) { - return menus.values() - .stream() - .filter(menu -> ids.contains(menu.getId())) - .collect(Collectors.toList()); - } - - @Override - public List findAllByProductId(final UUID productId) { - return menus.values() - .stream() - .filter(menu -> menu.getMenuProducts().stream().anyMatch(menuProduct -> menuProduct.getProduct().getId().equals(productId))) - .collect(Collectors.toList()); - } } diff --git a/src/test/java/kitchenpos/menus/application/MenuGroupServiceTest.java b/src/test/java/kitchenpos/menus/application/MenuGroupServiceTest.java index a5fbc71d1..9b7eb5466 100644 --- a/src/test/java/kitchenpos/menus/application/MenuGroupServiceTest.java +++ b/src/test/java/kitchenpos/menus/application/MenuGroupServiceTest.java @@ -1,7 +1,8 @@ package kitchenpos.menus.application; -import kitchenpos.menus.domain.MenuGroup; -import kitchenpos.menus.domain.MenuGroupRepository; +import kitchenpos.menus.tobe.domain.entity.MenuGroup; +import kitchenpos.menus.tobe.domain.repository.MenuGroupRepository; +import kitchenpos.menus.ui.dto.CreateMenuGroupRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -16,24 +17,26 @@ import static org.junit.jupiter.api.Assertions.assertAll; class MenuGroupServiceTest { + private CreateMenuGroupService createMenuGroupService; + private FindAllMenuGroupService findAllMenuGroupService; private MenuGroupRepository menuGroupRepository; - private MenuGroupService menuGroupService; @BeforeEach void setUp() { menuGroupRepository = new InMemoryMenuGroupRepository(); - menuGroupService = new MenuGroupService(menuGroupRepository); + createMenuGroupService = new CreateMenuGroupService(menuGroupRepository); + findAllMenuGroupService = new FindAllMenuGroupService(menuGroupRepository); } @DisplayName("메뉴 그룹을 등록할 수 있다.") @Test void create() { - final MenuGroup expected = createMenuGroupRequest("두마리메뉴"); - final MenuGroup actual = menuGroupService.create(expected); + final CreateMenuGroupRequest expected = createMenuGroupRequest("두마리메뉴"); + final MenuGroup actual = createMenuGroupService.create(expected); assertThat(actual).isNotNull(); assertAll( () -> assertThat(actual.getId()).isNotNull(), - () -> assertThat(actual.getName()).isEqualTo(expected.getName()) + () -> assertThat(actual.getName().getName()).isEqualTo(expected.name) ); } @@ -41,8 +44,8 @@ void create() { @NullAndEmptySource @ParameterizedTest void create(final String name) { - final MenuGroup expected = createMenuGroupRequest(name); - assertThatThrownBy(() -> menuGroupService.create(expected)) + final CreateMenuGroupRequest expected = createMenuGroupRequest(name); + assertThatThrownBy(() -> createMenuGroupService.create(expected)) .isInstanceOf(IllegalArgumentException.class); } @@ -50,13 +53,13 @@ void create(final String name) { @Test void findAll() { menuGroupRepository.save(menuGroup("두마리메뉴")); - final List actual = menuGroupService.findAll(); + final List actual = findAllMenuGroupService.findAll(); assertThat(actual).hasSize(1); } - private MenuGroup createMenuGroupRequest(final String name) { - final MenuGroup menuGroup = new MenuGroup(); - menuGroup.setName(name); - return menuGroup; + private CreateMenuGroupRequest createMenuGroupRequest(final String name) { + CreateMenuGroupRequest request = new CreateMenuGroupRequest(); + request.name = name; + return request; } } diff --git a/src/test/java/kitchenpos/menus/application/MenuServiceTest.java b/src/test/java/kitchenpos/menus/application/MenuServiceTest.java index d10425c77..37e8b888b 100644 --- a/src/test/java/kitchenpos/menus/application/MenuServiceTest.java +++ b/src/test/java/kitchenpos/menus/application/MenuServiceTest.java @@ -1,14 +1,14 @@ package kitchenpos.menus.application; -import kitchenpos.menus.domain.Menu; -import kitchenpos.menus.domain.MenuGroupRepository; -import kitchenpos.menus.domain.MenuProduct; -import kitchenpos.menus.domain.MenuRepository; +import kitchenpos.menus.tobe.domain.entity.IncludedProduct; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.IncludedProductRepository; +import kitchenpos.menus.tobe.domain.repository.MenuGroupRepository; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; +import kitchenpos.menus.ui.dto.ChangePriceRequest; +import kitchenpos.menus.ui.dto.CreateMenuRequest; import kitchenpos.products.application.FakePurgomalumValidator; -import kitchenpos.products.application.InMemoryProductRepository; -import kitchenpos.products.tobe.domain.infra.PurgomalumValidator; -import kitchenpos.products.tobe.domain.entity.Product; -import kitchenpos.products.tobe.domain.repository.ProductRepository; +import kitchenpos.common.domain.infra.PurgomalumValidator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -27,39 +27,52 @@ import static org.junit.jupiter.api.Assertions.assertAll; class MenuServiceTest { - private MenuRepository menuRepository; private MenuGroupRepository menuGroupRepository; - private ProductRepository productRepository; + private IncludedProductRepository includedProductRepository; + private MenuRepository menuRepository; private PurgomalumValidator purgomalumValidator; - private MenuService menuService; + private CreateMenuService createMenuService; + private ChangePriceService changePriceService; + private DisplayMenuService displayMenuService; + private HideMenuService hideMenuService; + private FindAllMenuService findAllMenuService; private UUID menuGroupId; - private Product product; + private IncludedProduct includedProduct; + @BeforeEach void setUp() { - menuRepository = new InMemoryMenuRepository(); + InMemoryIncludedProductRepository inMemoryIncludedProductRepository = new InMemoryIncludedProductRepository(); + includedProduct = inMemoryIncludedProductRepository.save(includedProduct(16_000L)); + includedProductRepository = inMemoryIncludedProductRepository; + menuGroupRepository = new InMemoryMenuGroupRepository(); - productRepository = new InMemoryProductRepository(); - purgomalumValidator = new FakePurgomalumValidator(); - menuService = new MenuService(menuRepository, menuGroupRepository, productRepository, purgomalumValidator); menuGroupId = menuGroupRepository.save(menuGroup()).getId(); - product = productRepository.save(product("후라이드", 16_000L)); + + menuRepository = new InMemoryMenuRepository(); + + purgomalumValidator = new FakePurgomalumValidator(); + createMenuService = new CreateMenuService(menuGroupRepository, purgomalumValidator, includedProductRepository, menuRepository); + changePriceService = new ChangePriceService(menuRepository); + displayMenuService = new DisplayMenuService(menuRepository); + hideMenuService = new HideMenuService(menuRepository); + findAllMenuService = new FindAllMenuService(menuRepository); } @DisplayName("1개 이상의 등록된 상품으로 메뉴를 등록할 수 있다.") @Test void create() { - final Menu expected = createMenuRequest( - "후라이드+후라이드", 19_000L, menuGroupId, true, createMenuProductRequest(product.getId(), 2L) + final CreateMenuRequest expected = createMenuRequest( + "후라이드+후라이드", 19_000L, menuGroupId, true, createMenuProductRequest(includedProduct.getId(), 2L) ); - final Menu actual = menuService.create(expected); + final kitchenpos.menus.tobe.domain.entity.Menu actual = createMenuService.create(expected); assertThat(actual).isNotNull(); assertAll( () -> assertThat(actual.getId()).isNotNull(), - () -> assertThat(actual.getName()).isEqualTo(expected.getName()), - () -> assertThat(actual.getPrice()).isEqualTo(expected.getPrice()), - () -> assertThat(actual.getMenuGroup().getId()).isEqualTo(expected.getMenuGroupId()), - () -> assertThat(actual.isDisplayed()).isEqualTo(expected.isDisplayed()), + () -> assertThat(actual.getName().getName()).isEqualTo(expected.name), + () -> assertThat(actual.getPrice().getPrice()).isEqualTo(expected.price), + () -> assertThat(actual.getMenuGroup().getId()).isEqualTo(expected.menuGroupId), + () -> assertThat(actual.isDisplayed()).isEqualTo(expected.isDisplayed), () -> assertThat(actual.getMenuProducts()).hasSize(1) ); } @@ -67,27 +80,25 @@ void create() { @DisplayName("상품이 없으면 등록할 수 없다.") @MethodSource("menuProducts") @ParameterizedTest - void create(final List menuProducts) { - final Menu expected = createMenuRequest("후라이드+후라이드", 19_000L, menuGroupId, true, menuProducts); - assertThatThrownBy(() -> menuService.create(expected)) + void create(final List menuProductRequests) { + final CreateMenuRequest expected = createMenuRequest("후라이드+후라이드", 19_000L, menuGroupId, true, menuProductRequests); + assertThatThrownBy(() -> createMenuService.create(expected)) .isInstanceOf(IllegalArgumentException.class); } private static List menuProducts() { - return Arrays.asList( - null, - Arguments.of(Collections.emptyList()), - Arguments.of(Arrays.asList(createMenuProductRequest(INVALID_ID, 2L))) + return List.of( + Arguments.of(List.of(createMenuProductRequest(INVALID_ID, 2L))) ); } @DisplayName("메뉴에 속한 상품의 수량은 0개 이상이어야 한다.") @Test void createNegativeQuantity() { - final Menu expected = createMenuRequest( - "후라이드+후라이드", 19_000L, menuGroupId, true, createMenuProductRequest(product.getId(), -1L) + final CreateMenuRequest expected = createMenuRequest( + "후라이드+후라이드", 19_000L, menuGroupId, true, createMenuProductRequest(includedProduct.getId(), -1L) ); - assertThatThrownBy(() -> menuService.create(expected)) + assertThatThrownBy(() -> createMenuService.create(expected)) .isInstanceOf(IllegalArgumentException.class); } @@ -96,20 +107,20 @@ void createNegativeQuantity() { @NullSource @ParameterizedTest void create(final BigDecimal price) { - final Menu expected = createMenuRequest( - "후라이드+후라이드", price, menuGroupId, true, createMenuProductRequest(product.getId(), 2L) + final CreateMenuRequest expected = createMenuRequest( + "후라이드+후라이드", price, menuGroupId, true, createMenuProductRequest(includedProduct.getId(), 2L) ); - assertThatThrownBy(() -> menuService.create(expected)) + assertThatThrownBy(() -> createMenuService.create(expected)) .isInstanceOf(IllegalArgumentException.class); } @DisplayName("메뉴에 속한 상품 금액의 합은 메뉴의 가격보다 크거나 같아야 한다.") @Test void createExpensiveMenu() { - final Menu expected = createMenuRequest( - "후라이드+후라이드", 33_000L, menuGroupId, true, createMenuProductRequest(product.getId(), 2L) + final CreateMenuRequest expected = createMenuRequest( + "후라이드+후라이드", 33_000L, menuGroupId, true, createMenuProductRequest(includedProduct.getId(), 2L) ); - assertThatThrownBy(() -> menuService.create(expected)) + assertThatThrownBy(() -> createMenuService.create(expected)) .isInstanceOf(IllegalArgumentException.class); } @@ -117,11 +128,11 @@ void createExpensiveMenu() { @NullSource @ParameterizedTest void create(final UUID menuGroupId) { - final Menu expected = createMenuRequest( - "후라이드+후라이드", 19_000L, menuGroupId, true, createMenuProductRequest(product.getId(), 2L) + final CreateMenuRequest expected = createMenuRequest( + "후라이드+후라이드", 19_000L, menuGroupId, true, createMenuProductRequest(includedProduct.getId(), 2L) ); - assertThatThrownBy(() -> menuService.create(expected)) - .isInstanceOf(NoSuchElementException.class); + assertThatThrownBy(() -> createMenuService.create(expected)) + .isInstanceOf(IllegalArgumentException.class); } @DisplayName("메뉴의 이름이 올바르지 않으면 등록할 수 없다.") @@ -129,20 +140,20 @@ void create(final UUID menuGroupId) { @NullSource @ParameterizedTest void create(final String name) { - final Menu expected = createMenuRequest( - name, 19_000L, menuGroupId, true, createMenuProductRequest(product.getId(), 2L) + final CreateMenuRequest expected = createMenuRequest( + name, 19_000L, menuGroupId, true, createMenuProductRequest(includedProduct.getId(), 2L) ); - assertThatThrownBy(() -> menuService.create(expected)) + assertThatThrownBy(() -> createMenuService.create(expected)) .isInstanceOf(IllegalArgumentException.class); } @DisplayName("메뉴의 가격을 변경할 수 있다.") @Test void changePrice() { - final UUID menuId = menuRepository.save(menu(19_000L, menuProduct(product, 2L))).getId(); - final Menu expected = changePriceRequest(16_000L); - final Menu actual = menuService.changePrice(menuId, expected); - assertThat(actual.getPrice()).isEqualTo(expected.getPrice()); + final UUID menuId = menuRepository.save(menu(19_000L, menuProduct(includedProduct, 2L))).getId(); + final ChangePriceRequest expected = changePriceRequest(16_000L); + final Menu actual = changePriceService.change(menuId, expected); + assertThat(actual.getPrice().getPrice()).isEqualTo(expected.price); } @DisplayName("메뉴의 가격이 올바르지 않으면 변경할 수 없다.") @@ -150,113 +161,116 @@ void changePrice() { @NullSource @ParameterizedTest void changePrice(final BigDecimal price) { - final UUID menuId = menuRepository.save(menu(19_000L, menuProduct(product, 2L))).getId(); - final Menu expected = changePriceRequest(price); - assertThatThrownBy(() -> menuService.changePrice(menuId, expected)) + final UUID menuId = menuRepository.save(menu(19_000L, menuProduct(includedProduct, 2L))).getId(); + final ChangePriceRequest expected = changePriceRequest(price); + assertThatThrownBy(() -> changePriceService.change(menuId, expected)) .isInstanceOf(IllegalArgumentException.class); } @DisplayName("메뉴에 속한 상품 금액의 합은 메뉴의 가격보다 크거나 같아야 한다.") @Test void changePriceToExpensive() { - final UUID menuId = menuRepository.save(menu(19_000L, menuProduct(product, 2L))).getId(); - final Menu expected = changePriceRequest(33_000L); - assertThatThrownBy(() -> menuService.changePrice(menuId, expected)) + final UUID menuId = menuRepository.save(menu(19_000L, menuProduct(includedProduct, 2L))).getId(); + final ChangePriceRequest expected = changePriceRequest(33_000L); + assertThatThrownBy(() -> changePriceService.change(menuId, expected)) .isInstanceOf(IllegalArgumentException.class); } @DisplayName("메뉴를 노출할 수 있다.") @Test void display() { - final UUID menuId = menuRepository.save(menu(19_000L, false, menuProduct(product, 2L))).getId(); - final Menu actual = menuService.display(menuId); + final UUID menuId = menuRepository.save(menu(19_000L, false, menuProduct(includedProduct, 2L))).getId(); + final Menu actual = displayMenuService.display(menuId); assertThat(actual.isDisplayed()).isTrue(); } @DisplayName("메뉴의 가격이 메뉴에 속한 상품 금액의 합보다 높을 경우 메뉴를 노출할 수 없다.") @Test void displayExpensiveMenu() { - final UUID menuId = menuRepository.save(menu(33_000L, false, menuProduct(product, 2L))).getId(); - assertThatThrownBy(() -> menuService.display(menuId)) + final UUID menuId = menuRepository.save(menu(33_000L, false, menuProduct(includedProduct, 2L))).getId(); + assertThatThrownBy(() -> displayMenuService.display(menuId)) .isInstanceOf(IllegalStateException.class); } @DisplayName("메뉴를 숨길 수 있다.") @Test void hide() { - final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct(product, 2L))).getId(); - final Menu actual = menuService.hide(menuId); + final UUID menuId = menuRepository.save(menu(19_000L, true, menuProduct(includedProduct, 2L))).getId(); + final Menu actual = hideMenuService.hide(menuId); assertThat(actual.isDisplayed()).isFalse(); } @DisplayName("메뉴의 목록을 조회할 수 있다.") @Test void findAll() { - menuRepository.save(menu(19_000L, true, menuProduct(product, 2L))); - final List actual = menuService.findAll(); + menuRepository.save(menu(19_000L, true, menuProduct(includedProduct, 2L))); + final List actual = findAllMenuService.findAll(); assertThat(actual).hasSize(1); } - private Menu createMenuRequest( + private CreateMenuRequest createMenuRequest( final String name, final long price, final UUID menuGroupId, final boolean displayed, - final MenuProduct... menuProducts + final CreateMenuRequest.CreateMenuProductRequest... menuProductRequests ) { - return createMenuRequest(name, BigDecimal.valueOf(price), menuGroupId, displayed, menuProducts); + return createMenuRequest(name, BigDecimal.valueOf(price), menuGroupId, displayed, menuProductRequests); } - private Menu createMenuRequest( + private CreateMenuRequest createMenuRequest( final String name, final BigDecimal price, final UUID menuGroupId, final boolean displayed, - final MenuProduct... menuProducts + final CreateMenuRequest.CreateMenuProductRequest... menuProductRequests ) { - return createMenuRequest(name, price, menuGroupId, displayed, Arrays.asList(menuProducts)); + return createMenuRequest(name, price, menuGroupId, displayed, Arrays.asList(menuProductRequests)); } - private Menu createMenuRequest( + private CreateMenuRequest createMenuRequest( final String name, final long price, final UUID menuGroupId, final boolean displayed, - final List menuProducts + final List menuProductRequests ) { - return createMenuRequest(name, BigDecimal.valueOf(price), menuGroupId, displayed, menuProducts); + return createMenuRequest(name, BigDecimal.valueOf(price), menuGroupId, displayed, menuProductRequests); } - private Menu createMenuRequest( + private CreateMenuRequest createMenuRequest( final String name, final BigDecimal price, final UUID menuGroupId, final boolean displayed, - final List menuProducts + final List menuProductRequests ) { - final Menu menu = new Menu(); - menu.setName(name); - menu.setPrice(price); - menu.setMenuGroupId(menuGroupId); - menu.setDisplayed(displayed); - menu.setMenuProducts(menuProducts); - return menu; + CreateMenuRequest request = new CreateMenuRequest(); + + request.name = name; + request.price = price; + request.menuGroupId = menuGroupId; + request.isDisplayed = displayed; + + request.createMenuProductRequests = menuProductRequests; + + return request; } - private static MenuProduct createMenuProductRequest(final UUID productId, final long quantity) { - final MenuProduct menuProduct = new MenuProduct(); - menuProduct.setProductId(productId); - menuProduct.setQuantity(quantity); - return menuProduct; + private static CreateMenuRequest.CreateMenuProductRequest createMenuProductRequest(final UUID productId, final long quantity) { + CreateMenuRequest.CreateMenuProductRequest request = new CreateMenuRequest.CreateMenuProductRequest(); + request.productId = productId; + request.quantity = quantity; + return request; } - private Menu changePriceRequest(final long price) { + private ChangePriceRequest changePriceRequest(final long price) { return changePriceRequest(BigDecimal.valueOf(price)); } - private Menu changePriceRequest(final BigDecimal price) { - final Menu menu = new Menu(); - menu.setPrice(price); - return menu; + private ChangePriceRequest changePriceRequest(final BigDecimal price) { + ChangePriceRequest request = new ChangePriceRequest(); + request.price = price; + return request; } } diff --git a/src/test/java/kitchenpos/products/application/ChangeProductPriceServiceTest.java b/src/test/java/kitchenpos/products/application/ChangePriceServiceTest.java similarity index 89% rename from src/test/java/kitchenpos/products/application/ChangeProductPriceServiceTest.java rename to src/test/java/kitchenpos/products/application/ChangePriceServiceTest.java index 2d9c06c82..b5a1a96b1 100644 --- a/src/test/java/kitchenpos/products/application/ChangeProductPriceServiceTest.java +++ b/src/test/java/kitchenpos/products/application/ChangePriceServiceTest.java @@ -1,8 +1,9 @@ package kitchenpos.products.application; import kitchenpos.menus.application.InMemoryMenuRepository; -import kitchenpos.menus.domain.Menu; -import kitchenpos.menus.domain.MenuRepository; +import kitchenpos.menus.domain.LegacyMenuRepository; +import kitchenpos.menus.tobe.domain.entity.Menu; +import kitchenpos.menus.tobe.domain.repository.MenuRepository; import kitchenpos.products.tobe.domain.entity.Product; import kitchenpos.products.tobe.domain.repository.ProductRepository; import org.junit.jupiter.api.BeforeEach; @@ -19,16 +20,16 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -class ChangeProductPriceServiceTest { +class ChangePriceServiceTest { private ProductRepository productRepository; - private MenuRepository menuRepository; private ChangeProductPriceService changeProductPriceService; + private MenuRepository menuRepository; @BeforeEach void setUp() { productRepository = new InMemoryProductRepository(); menuRepository = new InMemoryMenuRepository(); - changeProductPriceService = new ChangeProductPriceService(menuRepository, productRepository); + changeProductPriceService = new ChangeProductPriceService(productRepository); } @DisplayName("상품의 가격을 변경할 수 있다.") @@ -54,7 +55,7 @@ void changePrice(final BigDecimal price) { @Test void changePriceInMenu() { final Product product = productRepository.save(product("후라이드", 16_000L)); - final Menu menu = menuRepository.save(menu(19_000L, true, menuProduct(product, 2L))); + final Menu menu = menuRepository.save(menu(19_000L, true, menuProduct(includedProduct(product.getPrice().getPrice().longValue()), 2L))); BigDecimal price = BigDecimal.valueOf(8_000L); changeProductPriceService.changePrice(product.getId(), price); assertThat(menuRepository.findById(menu.getId()).get().isDisplayed()).isFalse(); diff --git a/src/test/java/kitchenpos/products/application/CreateProductServiceTest.java b/src/test/java/kitchenpos/products/application/CreateProductServiceTest.java index 41e5c74a1..14cec6baa 100644 --- a/src/test/java/kitchenpos/products/application/CreateProductServiceTest.java +++ b/src/test/java/kitchenpos/products/application/CreateProductServiceTest.java @@ -1,6 +1,6 @@ package kitchenpos.products.application; -import kitchenpos.products.tobe.domain.infra.PurgomalumValidator; +import kitchenpos.common.domain.infra.PurgomalumValidator; import kitchenpos.products.tobe.domain.entity.Product; import kitchenpos.products.tobe.domain.repository.ProductRepository; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/kitchenpos/products/application/FakePurgomalumValidator.java b/src/test/java/kitchenpos/products/application/FakePurgomalumValidator.java index eff472070..6eb2ae43c 100644 --- a/src/test/java/kitchenpos/products/application/FakePurgomalumValidator.java +++ b/src/test/java/kitchenpos/products/application/FakePurgomalumValidator.java @@ -1,6 +1,6 @@ package kitchenpos.products.application; -import kitchenpos.products.tobe.domain.infra.PurgomalumValidator; +import kitchenpos.common.domain.infra.PurgomalumValidator; import java.util.Arrays; import java.util.List;