Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[크리스마스 프로모션] 신창혁 미션 제출합니다. #5

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0b8d931
docs: 기능 구현 목록 작성
Hugh-KR Nov 13, 2023
7ba70a7
feat: 식당 예약 방문 날짜 입력 기능
Hugh-KR Nov 14, 2023
026bd2f
docs: 식당 예약 방문 날짜 입력 기능
Hugh-KR Nov 14, 2023
e414fd5
feat: 주문 메뉴 입력 기능
Hugh-KR Nov 14, 2023
86e5443
docs: 주문 메뉴 입력 기능
Hugh-KR Nov 14, 2023
af0ee12
feat: 방문 날짜 1 이상 31 이하의 숫자 아닌 경우 예외 처리
Hugh-KR Nov 14, 2023
71f852e
docs: 방문 날짜 1 이상 31 이하의 숫자 아닌 경우 예외 처리
Hugh-KR Nov 14, 2023
3169105
feat: 주문 메뉴 입력 주문 메뉴 개수 숫자 아닌 경우 예외 처리
Hugh-KR Nov 14, 2023
56027e8
docs: 주문 메뉴 입력 주문 메뉴 개수 숫자 아닌 경우 예외 처리
Hugh-KR Nov 14, 2023
cf0d076
feat: 할인 전 총주문 금액 출력 기능
Hugh-KR Nov 15, 2023
ed15106
docs: 할인 전 총주문 금액 출력 기능
Hugh-KR Nov 15, 2023
282aa84
feat: 증정 메뉴 출력 기능
Hugh-KR Nov 15, 2023
2dde62e
docs: 증정 메뉴 출력 기능
Hugh-KR Nov 15, 2023
588e90d
feat: 음료만 주문 시, 주문할 수 없도록 하는 기능
Hugh-KR Nov 15, 2023
8e7077b
docs: 음료만 주문 시, 주문할 수 없도록 하는 기
Hugh-KR Nov 15, 2023
3522aa2
feat: 메뉴는 한 번에 최대 20개까지만 주문 가능 하도록 하는 기능
Hugh-KR Nov 15, 2023
aa1c421
docs: 메뉴는 한 번에 최대 20개까지만 주문 가능 하도록 하는 기능
Hugh-KR Nov 15, 2023
6d5bc4f
feat: 혜택 내역 출력 기능
Hugh-KR Nov 15, 2023
ba007de
docs: 혜택 내역 출력 기능
Hugh-KR Nov 15, 2023
192d519
feat: 할인 후 예상 결제 금액 출력 기능
Hugh-KR Nov 15, 2023
e9e2ec7
docs: 할인 후 예상 결제 금액 출력 기능
Hugh-KR Nov 15, 2023
0871b64
fix: 증정 메뉴 할인 "할인 후 예상 결제 금액"에 반영되지 않도록 수정
Hugh-KR Nov 15, 2023
c556441
docs: 증정 메뉴 할인 "할인 후 예상 결제 금액"에 반영되지 않음
Hugh-KR Nov 15, 2023
4d17c31
feat: 총혜택 금액에 따라 다른 이벤트 배지를 부여하는 기능
Hugh-KR Nov 15, 2023
c98c8a5
docs: 총혜택 금액에 따라 다른 이벤트 배지를 부여하는 기능
Hugh-KR Nov 15, 2023
21064b8
docs: 클래스 다이어그램 추가
Hugh-KR Nov 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/EventDiagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
## 🎯기능 구현 목록

- **고객 예약 사항 입력**
- [X] 식당 예상 방문 날짜 입력
- [X] 주문 메뉴 입력
- **입력 시 예외 처리**
- [X] 방문 날짜 숫자가 아닌 경우
- [X] 방문 날짜 NULL 인 경우
- [X] 주문 메뉴 NULL 인 경우
- [X] 주문 메뉴와 개수 양끝 공백인 경우
- [X] 주문 메뉴 개수 숫자 아닌 경우
- **입력 후 예외 처리**
- [X] 방문 날짜 1 이상 31 이하의 숫자 아닌 경우
- [X] 주문 메뉴 입력 메뉴판에 없을 경우
- [X] 음료만 주문 시, 주문할 수 없음
- [X] 메뉴는 한 번에 최대 20개까지만 주문 가능

- **주문 메뉴**
- [X] 주문 메뉴 출력

- **할인 전 총주문 금액**
- [X] 총주문 금액 계산
- [X] 총주문 금액 출력

- **증정 메뉴**
- [X] 할인 전 총주문 금액이 12만 원 이상일 때, 샴페인 1개 증정
- [X] 증정 이벤트에 해당하지 않는 경우, 증정 메뉴 "없음" 출력
- [X] -25,000원 혜택 내역 추가
- [X] 할인 후 예상 결제 금액에는 반영되지 않음

- **혜택 내역**
- [X] 총주문 금액 10,000원 이상부터 이벤트 적용
- **크리스마스 디데이 할인**
- [X] 이벤트 기간: 2023.12.1 ~ 2023.12.25
- [X] 1,000원으로 시작하여 크리스마스가 다가올수록 날마다 할인 금액이 100원씩 증가
- [X] 총주문 금액에서 해당 금액만큼 할인
(e.g. 시작일인 12월 1일에 1,000원, 2일에 1,100원, ..., 25일엔 3,400원 할인)
- [X] 평일 할인(일요일~목요일): 평일에는 디저트 메뉴를 메뉴 1개당 2,023원 할인
- [X] 주말 할인(금요일, 토요일): 주말에는 메인 메뉴를 메뉴 1개당 2,023원 할인
- [X] 특별 할인: 이벤트 달력에 별이 있으면 총주문 금액에서 1,000원 할인

- **총혜택 금액**
- [X] 0원일 경우 "0원" 출력
- [X] 적용되는 모든 혜택의 합 출력

- **할인 후 예상 결제 금액**
- [X] "할인 전 총주문 금액 - 총혜택 금액" 출력
- [X] 결과값 음수인 경우 "0원" 출력

- **12월 이벤트 배지**
- [X] 12월 이벤트 배지 출력
- **총혜택 금액에 따라 다른 이벤트 배지를 부여**
- [X] 5천 원 이상: 별
- [X] 1만 원 이상: 트리
- [X] 2만 원 이상: 산타

## 이벤트 목표
1. 중복된 할인과 증정을 허용해서, 고객들이 혜택을 많이 받는다는 것을 체감할 수 있게 하는 것
2. 올해 12월에 지난 5년 중 최고의 판매 금액을 달성
3. 12월 이벤트 참여 고객의 5%가 내년 1월 새해 이벤트에 재참여하는 것

## 👨‍💻프로그래밍 요구 사항

- **Java 코드 컨벤션 가이드를 준수하며 프로그래밍한다.**
- **indent depth 를 3이 넘지 않도록 구현한다. 2까지만 허용한다.**
- **3항 연산자를 쓰지 않는다.**
- **함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다.**
- **JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을 테스트 코드로 확인한다.**
- **else 예약어를 쓰지 않는다.**
- **명확한 유형의 예외를 처리한다.**

## 추가된 요구 사항

- **입력과 출력을 담당하는 클래스를 별도로 구현한다.**
- **해당 클래스의 패키지, 클래스명, 메서드의 반환 타입과 시그니처는 자유롭게 구현할 수 있다.**
53 changes: 53 additions & 0 deletions src/main/java/christmas/AppConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package christmas;

import christmas.controller.EventController;
import christmas.service.EventService;
import christmas.view.input.InputView;
import christmas.view.input.reader.DefaultReader;
import christmas.view.input.reader.Reader;
import christmas.view.output.OutputView;

public class AppConfig {

private static final AppConfig APP_CONFIG = new AppConfig();

public final EventController eventController;
public final EventService eventService;
public final OutputView outputView;
public final InputView inputView;
public final DefaultReader reader;

private AppConfig() {
this.reader = initReader();
this.inputView = initInputView(reader);
this.outputView = initOutputView();
this.eventService = initEventService();
this.eventController = initEventController(eventService, inputView, outputView);
}

public static AppConfig getInstance() {
return APP_CONFIG;
}

private DefaultReader initReader() {
return new DefaultReader();
}

private InputView initInputView(final Reader reader) {
return new InputView(reader);
}

private OutputView initOutputView() {
return new OutputView();
}

private EventService initEventService() {
return new EventService();
}

private EventController initEventController(final EventService eventService,
final InputView inputView,
final OutputView outputView) {
return new EventController(eventService, inputView, outputView);
}
}
17 changes: 16 additions & 1 deletion src/main/java/christmas/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
package christmas;

import christmas.controller.EventController;

public class Application {

private final EventController eventController;

public Application(final AppConfig appConfig) {
this.eventController = appConfig.eventController;
}

public static void main(String[] args) {
// TODO: 프로그램 구현
Application application = new Application(AppConfig.getInstance());
application.run();
}

public void run() {
eventController.initEvent();
eventController.playEvent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package christmas.constant.errorMessage;

public interface ExceptionStatus {

String getMessage();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package christmas.constant.errorMessage.exception;

import christmas.constant.errorMessage.ExceptionStatus;

public class CustomArrayIndexOutOfBoundsException extends ArrayIndexOutOfBoundsException {

public CustomArrayIndexOutOfBoundsException(ExceptionStatus exceptionStatus) {
super(exceptionStatus.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package christmas.constant.errorMessage.exception;

import christmas.constant.errorMessage.ExceptionStatus;

public class CustomIllegalArgumentException extends IllegalArgumentException {

public CustomIllegalArgumentException(ExceptionStatus exceptionStatus) {
super(exceptionStatus.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package christmas.constant.errorMessage.exception;

import christmas.constant.errorMessage.ExceptionStatus;

public class CustomIllegalStateException extends IllegalStateException {

public CustomIllegalStateException(ExceptionStatus exceptionStatus) {
super(exceptionStatus.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package christmas.constant.errorMessage.exception;

import christmas.constant.errorMessage.ExceptionStatus;

public class CustomNullPointException extends NullPointerException {

public CustomNullPointException(ExceptionStatus exceptionStatus) {
super(exceptionStatus.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package christmas.constant.errorMessage.exception;

import christmas.constant.errorMessage.ExceptionStatus;

public class CustomNumberFormatException extends NumberFormatException {

public CustomNumberFormatException(ExceptionStatus exceptionStatus) {
super(exceptionStatus.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package christmas.constant.errorMessage.input;

import christmas.constant.errorMessage.ExceptionStatus;

public enum EventExceptionStatus implements ExceptionStatus {

DATE_IS_NOT_CORRECT("유효하지 않은 날짜입니다."),
MENU_IS_NOT_CORRECT("유효하지 않은 주문입니다.");


private static final String MESSAGE_PREFIX = "[ERROR] ";
private static final String MESSAGE_SUFFIX = " 다시 입력해 주세요.";

private final String message;

EventExceptionStatus(final String message) {
this.message = MESSAGE_PREFIX + message + MESSAGE_SUFFIX;
}

public String getMessage() {
return this.message;
}
}
85 changes: 85 additions & 0 deletions src/main/java/christmas/controller/EventController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package christmas.controller;

import christmas.constant.errorMessage.exception.CustomArrayIndexOutOfBoundsException;
import christmas.constant.errorMessage.exception.CustomIllegalArgumentException;
import christmas.constant.errorMessage.exception.CustomIllegalStateException;
import christmas.constant.errorMessage.exception.CustomNullPointException;
import christmas.constant.errorMessage.exception.CustomNumberFormatException;
import christmas.dto.BenefitDto;
import christmas.dto.OrderDto;
import christmas.service.EventService;
import christmas.view.input.InputView;
import christmas.view.output.OutputView;
import java.util.Map;

public class EventController {

private final OutputView outputView;
private final InputView inputView;
private final EventService eventService;

public EventController(final EventService eventService, final InputView inputView, final OutputView outputView) {
this.eventService = eventService;
this.inputView = inputView;
this.outputView = outputView;
}

public void initEvent() {
initDate();
initOrder();
initBenefit();
}

private void initDate() {
try {
final int date = inputView.readDate();
eventService.initDate(date);
} catch (CustomNumberFormatException | CustomNullPointException |
CustomIllegalArgumentException e) {
System.out.println(e.getMessage());
initDate();
}
}

private void initOrder() {
try {
final Map<String, Integer> menus = inputView.readOrder();
eventService.initOrder(menus);
} catch (CustomNumberFormatException | CustomNullPointException |
CustomIllegalArgumentException | CustomIllegalStateException |
CustomArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
initOrder();
}
}

private void initBenefit() {
eventService.initBenefit();
}

public void playEvent() {
announceOrderResult();
announceTotalOrder();
announceTotalBenefit();
}

private void announceOrderResult() {
final int date = eventService.getEventDate();
outputView.printOrderResult(date);
}

private void announceTotalOrder() {
final OrderDto orderDto = eventService.getOrderDto();
outputView.printTotalMenu(orderDto);
outputView.printTotalPrice(orderDto);
outputView.printGiftMenuBenefit(orderDto);
}

private void announceTotalBenefit() {
final BenefitDto benefitDto = eventService.getBenefitDto();
outputView.printTotalBenefit(benefitDto);
outputView.printTotalDiscount(benefitDto);
outputView.printDiscountedTotalPrice(benefitDto);
outputView.printEventBadge(benefitDto);
}
}
Loading