diff --git a/src/main/java/study/book/object/movie/Customer.java b/src/main/java/study/book/object/movie/Customer.java index df4e2b9..6b2f757 100644 --- a/src/main/java/study/book/object/movie/Customer.java +++ b/src/main/java/study/book/object/movie/Customer.java @@ -1,4 +1,17 @@ package study.book.object.movie; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter @Setter +@ToString public class Customer { + private String name; + private String id; + + public Customer(String name, String id) { + this.name = name; + this.id = id; + } } diff --git a/src/main/java/study/book/object/movie/Movie.java b/src/main/java/study/book/object/movie/Movie.java index a7057c1..9ae0e9d 100644 --- a/src/main/java/study/book/object/movie/Movie.java +++ b/src/main/java/study/book/object/movie/Movie.java @@ -3,9 +3,14 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; +import study.book.object.movie.condition.DiscountCondition; +import study.book.object.movie.condition.DiscountConditionType; import study.book.object.movie.policy.DiscountPolicy; import java.time.Duration; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; @Getter @Setter @ToString @@ -13,6 +18,12 @@ public class Movie { private String title; private Duration runningTime; private Money fee; + private List discountConditions; + + private MovieType movieType; + private Money discountAmount; + private double discountPercent; + private DiscountPolicy discountPolicy; public Movie(String title, Duration runningTime, Money fee, DiscountPolicy discountPolicy) { @@ -29,4 +40,47 @@ public Money calculateMovieFee(Screening screening) { public void changeDiscountPolicy(DiscountPolicy discountPolicy) { this.discountPolicy = discountPolicy; } + + public List getDiscountConditions() { + return Collections.unmodifiableList(discountConditions); + } + + public Money calculateAmountDiscountedFee() { + if(movieType != MovieType.AMOUNT_DISCOUNT) { + throw new IllegalArgumentException(); + } + + return fee.minus(discountAmount); + } + + public Money calculatePercentDiscountFee() { + if(movieType != MovieType.PERCENT_DISCOUNT) { + throw new IllegalArgumentException(); + } + + return fee.minus(fee.times(discountPercent)); + } + + public Money calculateNoneDiscountFee() { + if(movieType != MovieType.NONE_DISCOUNT) { + throw new IllegalArgumentException(); + } + + return fee; + } + + public boolean isDiscountable(LocalDateTime whenScreened, int sequence) { + for(DiscountCondition condition : discountConditions) { + if(condition.getType() == DiscountConditionType.PERIOD) { + if(condition.isDiscountable(whenScreened.getDayOfWeek(), whenScreened.toLocalTime())) { + return true; + } + } else { + if(condition.isDiscountable(sequence)) { + return true; + } + } + } + return false; + } } diff --git a/src/main/java/study/book/object/movie/MovieType.java b/src/main/java/study/book/object/movie/MovieType.java new file mode 100644 index 0000000..375d009 --- /dev/null +++ b/src/main/java/study/book/object/movie/MovieType.java @@ -0,0 +1,7 @@ +package study.book.object.movie; + +public enum MovieType { + AMOUNT_DISCOUNT, + PERCENT_DISCOUNT, + NONE_DISCOUNT +} diff --git a/src/main/java/study/book/object/movie/Reservation.java b/src/main/java/study/book/object/movie/Reservation.java index e47d7ad..a7af6ef 100644 --- a/src/main/java/study/book/object/movie/Reservation.java +++ b/src/main/java/study/book/object/movie/Reservation.java @@ -1,7 +1,10 @@ package study.book.object.movie; +import lombok.Getter; +import lombok.Setter; import lombok.ToString; +@Getter @Setter @ToString public class Reservation { private Customer customer; diff --git a/src/main/java/study/book/object/movie/ReservationAgency.java b/src/main/java/study/book/object/movie/ReservationAgency.java new file mode 100644 index 0000000..4d13518 --- /dev/null +++ b/src/main/java/study/book/object/movie/ReservationAgency.java @@ -0,0 +1,10 @@ +package study.book.object.movie; + +public class ReservationAgency { + + public Reservation reserve(Screening screening, Customer customer, int audienceCount) { + Money fee = screening.calculateFee(audienceCount); + + return new Reservation(customer, screening, fee, audienceCount); + } +} diff --git a/src/main/java/study/book/object/movie/Screening.java b/src/main/java/study/book/object/movie/Screening.java index 485a856..60e4176 100644 --- a/src/main/java/study/book/object/movie/Screening.java +++ b/src/main/java/study/book/object/movie/Screening.java @@ -1,7 +1,13 @@ package study.book.object.movie; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + import java.time.LocalDateTime; +@Getter @Setter +@ToString public class Screening { private Movie movie; private int sequece; @@ -13,23 +19,22 @@ public Screening(Movie movie, int sequence, LocalDateTime whenScreened) { this.whenScreened = whenScreened; } - public Reservation reserve(Customer customer, int audienceCount) { - return new Reservation(customer, this, calculateFee(audienceCount), audienceCount); - } - - public LocalDateTime getStartTime() { - return whenScreened; - } - - public boolean isSequence(int sequence) { - return this.sequece == sequece; - } - - public Money getMovieFee() { - return movie.getFee(); - } - - private Money calculateFee(int audienceCount) { - return movie.calculateMovieFee(this); + public Money calculateFee(int audienceCount) { + switch (movie.getMovieType()) { + case AMOUNT_DISCOUNT: + if(movie.isDiscountable(whenScreened, sequece)) { + return movie.calculateAmountDiscountedFee().times(audienceCount); + } + break; + case PERCENT_DISCOUNT: + if(movie.isDiscountable(whenScreened, sequece)) { + return movie.calculatePercentDiscountFee().times(audienceCount); + } + break; + case NONE_DISCOUNT: + return movie.calculateNoneDiscountFee().times(audienceCount); + } + + return movie.calculateNoneDiscountFee().times(audienceCount); } } diff --git a/src/main/java/study/book/object/movie/condition/DiscountCondition.java b/src/main/java/study/book/object/movie/condition/DiscountCondition.java index 2bd628d..2d045f7 100644 --- a/src/main/java/study/book/object/movie/condition/DiscountCondition.java +++ b/src/main/java/study/book/object/movie/condition/DiscountCondition.java @@ -1,8 +1,37 @@ package study.book.object.movie.condition; -import study.book.object.movie.Screening; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; -public interface DiscountCondition { +import java.time.DayOfWeek; +import java.time.LocalTime; - boolean isSatisfiedBy(Screening screening); +@Getter @Setter +@ToString +public class DiscountCondition { + private DiscountConditionType type; + + private int sequence; + + private DayOfWeek dayOfWeek; + private LocalTime startTime; + private LocalTime endTime; + + public boolean isDiscountable(DayOfWeek dayOfWeek, LocalTime time) { + if(type != DiscountConditionType.PERIOD) { + throw new IllegalArgumentException(); + } + + return this.dayOfWeek.equals(dayOfWeek) && + this.startTime.compareTo(time) <= 0 && + this.endTime.compareTo(time) >=0; + } + + public boolean isDiscountable(int sequence) { + if (type != DiscountConditionType.SEQUENCE) { + throw new IllegalArgumentException(); + } + return this.sequence == sequence; + } } diff --git a/src/main/java/study/book/object/movie/condition/DiscountConditionType.java b/src/main/java/study/book/object/movie/condition/DiscountConditionType.java new file mode 100644 index 0000000..9e229d0 --- /dev/null +++ b/src/main/java/study/book/object/movie/condition/DiscountConditionType.java @@ -0,0 +1,6 @@ +package study.book.object.movie.condition; + +public enum DiscountConditionType { + SEQUENCE, // 순번 조건 + PERIOD //기간 조건 +}