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

[영화 예매] 유시은 미션 제출합니다. #91

Closed
wants to merge 26 commits into from
Closed
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
397f8af
[추가] 기능 구현 목록 작성
yuyu154 Apr 16, 2019
a278983
[추가] 정수 입력 받는 기능 InputUtil클래스
yuyu154 Apr 16, 2019
b94c7bc
입력화면 구현 InputView클래스
yuyu154 Apr 16, 2019
8db9256
[추가] 시간표 출력 기능 구현
yuyu154 Apr 16, 2019
a662989
[추가] 구매량만큼 티켓수 감소시키는 기능
yuyu154 Apr 16, 2019
596279e
[추가] 영화 예약번호로 예약 기능 추가
yuyu154 Apr 16, 2019
da9bd6c
[추가] 결제 재시작 기능 구현
yuyu154 Apr 16, 2019
a1f37bd
[추가] 비용 클래스 구현
yuyu154 Apr 16, 2019
0dc4cb0
[추가] 최종 금액 생성 및 출력
yuyu154 Apr 16, 2019
2096609
[수정] movieId로 작동하던 함수들을 Movie인자로 작동하게 수정
yuyu154 Apr 16, 2019
62e398f
[수정] main함수 구조 조건에 맞게 리팩토링
yuyu154 Apr 16, 2019
823cc83
[추가] 예매 가능 인원을 초과했을때 예외처리
yuyu154 Apr 16, 2019
3d27bd9
[추가] 상영목록에 없는 영화를 선택했을때 예외처리 구현
yuyu154 Apr 16, 2019
4454465
[추가] OneOrTwoToken 추가해 1이나 2이외의 입력 예외처리
yuyu154 Apr 16, 2019
29fe1eb
[추가] 스케쥴 일정 선택에 대한 예외처리 구현
yuyu154 Apr 16, 2019
f164697
[추가] 영화가 매진됬는지 확인하는 기능
yuyu154 Apr 16, 2019
e95aeb2
[추가] 현재시간보다 전인지 확인
yuyu154 Apr 16, 2019
84976f3
[수정] 영화 조회 메소드 리팩토링
yuyu154 Apr 16, 2019
f407e46
[수정] Movie 예약가능한지 확인하는 메소드 추가
yuyu154 Apr 16, 2019
018c802
[추가] 한시간 이내의 영화인지 확인하는 기능
yuyu154 Apr 16, 2019
4642c3b
[수정] 전체적인 컨벤션에 맞게 수정
yuyu154 Apr 16, 2019
d2d77f4
[수정] 주석 제거
yuyu154 Apr 16, 2019
418f809
[수정] 전체적인 디버깅
yuyu154 Apr 16, 2019
2091ba1
[수정] 기능구현목록 수정
yuyu154 Apr 16, 2019
874706c
[수정] 주석 추가
yuyu154 Apr 16, 2019
c8e2572
[추가] 기능구현목록에 유의사항 표기
yuyu154 Apr 16, 2019
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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 영화 예매 프로그램
---

### 구현할 기능 목록

1. 입력
- 예약할 영화의 id 번호
- 예약할 시간표 번호
- 예약할 인원 수
- 예약을 끝내고 최종 결제를 할 것인지 (1), 추가 예약을 받을지(2) 결정
- 결제 금액 입력 받기
- 신용카드 (1), 현금(2) 입력받기

2. 중간 과정
- 맨처음 예매할 수 있는 영화가 있는지부터 살펴본다
- 영화의 id를 가지고 영화의 예약표를 찾는다
- 상영목록에 없으면 예외를 출력한다
- 예약한 시간표를 예약한다
- 단, 1시간 이내 차이가 나면 예약받지 않고 사유를 출력한다 (예외 상황)
- 상영 시간이 이미 지난 영화를 출력하면 예외를 처리한다
- 예약한 인원수를 바탕으로 예약처리한다
- 단 예매가능 인원을 초과하면 예매 불가하다고 한다.
- 처음 스케쥴 선택화면으로 돌아간다. 왜냐하면 원하는 스케쥴에 원하는 인원만큼 선택할 수 없기 때문이다.
- 결제
- 결제할때 신용카드는 5퍼센트, 현금은 2퍼센트
- 포인트를 사용할 수 있다
- 포인트에는 할인율 적용 X 따로 구현
- 포인트가 결제금액보다 많을시 0원을 부과한다

- 최종 예매 출력을 한다.

- 예외처리는 모두 구현했으나 그에맞는 출력 메시지 기능을 구현하지 못함
17 changes: 0 additions & 17 deletions src/main/java/MovieApplication.java

This file was deleted.

40 changes: 40 additions & 0 deletions src/main/java/domain/AllPay.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package domain;

import java.util.List;

public class AllPay {
private final static double CREDIT_DISCOUNT = 0.95;
private final static double CASH_DISCOUNT = 0.98;

private List<MovieCost> movieCosts;

public AllPay(List<MovieCost> movieCosts) {
this.movieCosts = movieCosts;
}

public int getTotalCost(int point, OneOrTwoToken isCredit) {
int ret = calcTotalCost(point, isCredit);
if (ret >= 0) {
return ret;
}
System.out.println("포인트가 결제금액보다 크므로 0원이 결제되었습니다.");
return 0;
}

private int calcTotalCost(int point, OneOrTwoToken isCredit) {
if (isCredit.isOne()) {
return (int) ((getTotalMovieCost() * CREDIT_DISCOUNT) - point);
}
return (int) ((getTotalMovieCost() * CASH_DISCOUNT) - point);
}

private int getTotalMovieCost() {
int sum = 0;
for (MovieCost cost : movieCosts) {
sum += cost.getCost();
}
return sum;
}


}
48 changes: 48 additions & 0 deletions src/main/java/domain/Movie.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

public class Movie {
private static final char NEW_LINE = '\n';
private static final int ONE = 1;

private final int id;
private final String name;
Expand All @@ -31,4 +32,51 @@ public String toString() {
return id + " - " + name + ", " + price + "원" + NEW_LINE
+ sb.toString();
}

public int getId() {
return this.id;
}

public int getPrice() {
return price;
}

public List<PlaySchedule> getPlaySchedules() {
return playSchedules;
}

public boolean isSameMovie(int movieId) {
return (id == movieId);
}

public void checkMovieValid() {
if (!isMoviePossible()) {
throw new IllegalArgumentException("영화를 예매할 수 없습니다."); // 영화 좌석이 없는 경우
}
}

public void checkTimeScheduleValid(int timeScheduleIndex) {
// 시간이 이미 지났는지 확인하는 메소드

playSchedules.get(timeScheduleIndex - ONE);
if (!checkMovieSchedule(timeScheduleIndex - ONE)) {
throw new IllegalArgumentException("이미 지난 시간표입니다");
}
}

private boolean checkMovieSchedule(int timeScheduleIndex) {
return playSchedules.get(timeScheduleIndex).isSchedulePossible();
}

// 영화가 예매가 가능한지 확인하는 메소드
public boolean isMoviePossible() {
return playSchedules.stream()
.anyMatch(schedule -> schedule.isSchedulePossible());
}

public boolean isOneHourWithRangeMovie(int timeIndex) {
PlaySchedule inputSchedule = playSchedules.get(timeIndex - ONE);
return playSchedules.stream()
.anyMatch(playschedule -> playschedule.isOneHourWithinRangeSchedule(inputSchedule));
}
}
16 changes: 16 additions & 0 deletions src/main/java/domain/MovieCost.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package domain;

public class MovieCost {
private final int cost;

public MovieCost(Reservation reservation) {
Movie movie = reservation.getMovie();
int count = reservation.getBuyCount();

cost = movie.getPrice() * count;
}

public int getCost() {
return cost;
}
}
37 changes: 37 additions & 0 deletions src/main/java/domain/MovieRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static utils.DateTimeUtils.createDateTime;

public class MovieRepository {
private static final int ONE = 1;
private static List<Movie> movies = new ArrayList<>();

static {
Expand Down Expand Up @@ -42,4 +44,39 @@ public class MovieRepository {
public static List<Movie> getMovies() {
return movies;
}

public static Movie getMovie(int movieId) {
Movie movie = getWantMovie(movieId);
movie.checkMovieValid();
return movie;
}

public static Movie getWantMovie(int movieId) {
if (isContains(movieId)) {
return movies.stream()
.filter(movie -> movie.isSameMovie(movieId))
.collect(Collectors.toList())
.get(0);
}
throw new IllegalArgumentException("상영 목록에 없는 영화를 선택하셨습니다");
}

private static boolean isContains(int movieId) {
return movies.stream()
.anyMatch(movie -> movie.isSameMovie(movieId));
}

public static List<PlaySchedule> getPlaySchedule(Movie inputMovie) {
return getWantMovie(inputMovie.getId()).getPlaySchedules();
}

public static void buyMovieTickets(Movie movie, int playScheduleIndex, int buyCount) {
List<PlaySchedule> playScheduleList = getPlaySchedule(movie);
playScheduleList.get(playScheduleIndex - 1).buyTicket(buyCount);
}

public static boolean isAllMoviePossible() {
return movies.stream()
.anyMatch(movie -> movie.isMoviePossible());
}
}
25 changes: 25 additions & 0 deletions src/main/java/domain/OneOrTwoToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package domain;

public class OneOrTwoToken {

private final int number;

public OneOrTwoToken(int number) {
checkIfValidNumber(number);
this.number = number;
}

private void checkIfValidNumber(int number) {
if (!(number == 1 || number == 2)) {
throw new IllegalArgumentException("올바른 1, 2를 입력해주세요");
}
}

public boolean isOne() {
return (number == 1);
}

public boolean isTwo() {
return (number == 2);
}
}
24 changes: 24 additions & 0 deletions src/main/java/domain/PlaySchedule.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package domain;

import utils.DateTimeUtils;

import java.time.LocalDateTime;

import static utils.DateTimeUtils.format;
Expand All @@ -13,6 +15,28 @@ public PlaySchedule(LocalDateTime startDateTime, int capacity) {
this.capacity = capacity;
}

public void buyTicket(int buyCount) {
if (capacity - buyCount < 0) {
throw new IllegalArgumentException("인원 초과입니다 다른 일정을 선택해주세요\n");
}
this.capacity -= buyCount;
}

public boolean isSchedulePossible() {
return (capacity > 0 && isScheduleValidTime());
}

// 현재 시간 이후인지 체크
private boolean isScheduleValidTime() {
LocalDateTime currentTime = LocalDateTime.now();
return currentTime.isBefore(this.startDateTime);
}

// 1시간 이내인지 체크
public boolean isOneHourWithinRangeSchedule(PlaySchedule inputSchedule) {
return DateTimeUtils.isOneHourWithinRange(this.startDateTime, inputSchedule.startDateTime);
}

@Override
public String toString() {
return "시작시간: " + format(startDateTime) + " 예약가능인원: " + capacity + "\n";
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/domain/Reservation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package domain;

public class Reservation {

private final Movie movie;
private final int scheduleNumber;
private final int buyCount;

public Reservation(Movie movie, int scheduleNumber, int buyCount) {
this.movie = movie;
this.scheduleNumber = scheduleNumber;
this.buyCount = buyCount;
this.setMovieRepository();
}

private void setMovieRepository() {
MovieRepository.buyMovieTickets(movie, scheduleNumber, buyCount);
}

public Movie getMovie() {
return movie;
}

public int getBuyCount() {
return buyCount;
}

public void isMatchInOneHour(int timeIndex) {
if (movie.isOneHourWithRangeMovie(timeIndex)) {
throw new IllegalArgumentException("1시간 이내의 영화는 예매 불가능합니다");
}
}
}
9 changes: 9 additions & 0 deletions src/main/java/logic/MovieApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package logic;

public class MovieApplication {
public static void main(String[] args) {
Player player = new Player();
player.play();
player.calculateCost();
}
}
61 changes: 61 additions & 0 deletions src/main/java/logic/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package logic;

import domain.*;
import view.InputView;
import view.OutputView;

import java.util.ArrayList;
import java.util.List;

public class Player {
private List<Reservation> reservations;
private List<MovieCost> movieCosts;

public Player() {
reservations = new ArrayList<>();
movieCosts = new ArrayList<>();
}

public void play() {
if (!MovieRepository.isAllMoviePossible()) {
return;
}
do {
Movie movie = InputView.inputMovie();
BuyWithTimeschedule(movie);
System.out.println("확인");
OutputView.printPlaySchedule(movie);
} while (checkContinue() && MovieRepository.isAllMoviePossible());
}

private boolean checkContinue() {
return InputView.inputContinue().isTwo();
}

private void BuyWithTimeschedule(Movie movie) {
try {
OutputView.printPlaySchedule(movie);
int timeScheduleIndex = InputView.InputTimeScheduleIndex(movie);
int countOfBuy = InputView.inputCustomerBuyCount();
checkReservationAndAdd(movie, timeScheduleIndex, countOfBuy);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
BuyWithTimeschedule(movie);
}
}

private void checkReservationAndAdd(Movie movie, int timeScheduleIndex, int countOfBuy) {
for (Reservation reservation : reservations) {
reservation.isMatchInOneHour(timeScheduleIndex);
}
reservations.add(new Reservation(movie, timeScheduleIndex, countOfBuy));
}

public void calculateCost() {
for (Reservation reservation : reservations) {
movieCosts.add(new MovieCost(reservation));
}
AllPay allPay = new AllPay(movieCosts);
OutputView.printPayResult(allPay);
}
}
Loading