diff --git a/src/main/java/com/beat/BeatApplication.java b/src/main/java/com/beat/BeatApplication.java index 263f8261..4a4b8cb8 100644 --- a/src/main/java/com/beat/BeatApplication.java +++ b/src/main/java/com/beat/BeatApplication.java @@ -5,9 +5,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignAutoConfiguration; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableFeignClients +@EnableScheduling @ImportAutoConfiguration({FeignAutoConfiguration.class}) public class BeatApplication { diff --git a/src/main/java/com/beat/domain/performance/application/PerformanceService.java b/src/main/java/com/beat/domain/performance/application/PerformanceService.java index 1907a176..d2c85c44 100644 --- a/src/main/java/com/beat/domain/performance/application/PerformanceService.java +++ b/src/main/java/com/beat/domain/performance/application/PerformanceService.java @@ -36,6 +36,7 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -58,11 +59,17 @@ public PerformanceDetailResponse getPerformanceDetail(Long performanceId) { .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); List scheduleList = scheduleRepository.findByPerformanceId(performanceId).stream() - .map(schedule -> PerformanceDetailSchedule.of( - schedule.getId(), - schedule.getPerformanceDate(), - schedule.getScheduleNumber().name() - )).collect(Collectors.toList()); + .map(schedule -> { + int dueDate = scheduleService.calculateDueDate(schedule); + return PerformanceDetailSchedule.of( + schedule.getId(), + schedule.getPerformanceDate(), + schedule.getScheduleNumber().name(), + dueDate + ); + }).collect(Collectors.toList()); + + int minDueDate = scheduleService.getMinDueDate(scheduleRepository.findAllByPerformanceId(performanceId)); List castList = castRepository.findByPerformanceId(performanceId).stream() .map(cast -> PerformanceDetailCast.of( @@ -95,7 +102,8 @@ public PerformanceDetailResponse getPerformanceDetail(Long performanceId) { performance.getPerformanceContact(), performance.getPerformanceTeamName(), castList, - staffList + staffList, + minDueDate ); } @@ -107,12 +115,14 @@ public BookingPerformanceDetailResponse getBookingPerformanceDetail(Long perform List scheduleList = scheduleRepository.findByPerformanceId(performanceId).stream() .map(schedule -> { scheduleService.updateBookingStatus(schedule); + int dueDate = scheduleService.calculateDueDate(schedule); return BookingPerformanceDetailSchedule.of( schedule.getId(), schedule.getPerformanceDate(), schedule.getScheduleNumber().name(), scheduleService.getAvailableTicketCount(schedule), - schedule.isBooking() + schedule.isBooking(), + dueDate ); }).collect(Collectors.toList()); @@ -206,18 +216,40 @@ public MakerPerformanceResponse getMemberPerformances(Long memberId) { List performances = performanceRepository.findByUsersId(user.getId()); List performanceDetails = performances.stream() - .map(performance -> MakerPerformanceDetail.of( - performance.getId(), - performance.getGenre().name(), - performance.getPerformanceTitle(), - performance.getPosterImage(), - performance.getPerformancePeriod() - )) + .map(performance -> { + List schedules = scheduleRepository.findByPerformanceId(performance.getId()); + int minDueDate = scheduleService.getMinDueDate(schedules); + + return MakerPerformanceDetail.of( + performance.getId(), + performance.getGenre().name(), + performance.getPerformanceTitle(), + performance.getPosterImage(), + performance.getPerformancePeriod(), + minDueDate + ); + }) .collect(Collectors.toList()); - return MakerPerformanceResponse.of(user.getId(), performanceDetails); + // 양수 minDueDate 정렬 + List positiveDueDates = performanceDetails.stream() + .filter(detail -> detail.minDueDate() >= 0) + .sorted(Comparator.comparingInt(MakerPerformanceDetail::minDueDate)) + .collect(Collectors.toList()); + + // 음수 minDueDate 정렬 + List negativeDueDates = performanceDetails.stream() + .filter(detail -> detail.minDueDate() < 0) + .sorted(Comparator.comparingInt(MakerPerformanceDetail::minDueDate).reversed()) + .collect(Collectors.toList()); + + // 병합된 리스트 + positiveDueDates.addAll(negativeDueDates); + + return MakerPerformanceResponse.of(user.getId(), positiveDueDates); } + @Transactional public PerformanceEditResponse getPerformanceEdit(Long memberId, Long performanceId) { Member member = memberRepository.findById(memberId) diff --git a/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java b/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java index 0cbe3616..3fedccf6 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java +++ b/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java @@ -7,10 +7,11 @@ public record BookingPerformanceDetailSchedule( LocalDateTime performanceDate, String scheduleNumber, int availableTicketCount, - boolean isBooking + boolean isBooking, + int dueDate ) { - public static BookingPerformanceDetailSchedule of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber, int availableTicketCount, boolean isBooking) { - return new BookingPerformanceDetailSchedule(scheduleId, performanceDate, scheduleNumber, availableTicketCount, isBooking); + public static BookingPerformanceDetailSchedule of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber, int availableTicketCount, boolean isBooking, int dueDate) { + return new BookingPerformanceDetailSchedule(scheduleId, performanceDate, scheduleNumber, availableTicketCount, isBooking, dueDate); } } diff --git a/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java b/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java index 21dcaa61..97ba91a0 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java +++ b/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java @@ -5,14 +5,16 @@ public record MakerPerformanceDetail( String genre, String performanceTitle, String posterImage, - String performancePeriod + String performancePeriod, + int minDueDate ) { public static MakerPerformanceDetail of( Long performanceId, String genre, String performanceTitle, String posterImage, - String performancePeriod) { - return new MakerPerformanceDetail(performanceId, genre, performanceTitle, posterImage, performancePeriod); + String performancePeriod, + int minDueDate) { // minDueDate 매개변수 추가 + return new MakerPerformanceDetail(performanceId, genre, performanceTitle, posterImage, performancePeriod, minDueDate); } } diff --git a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java index a8f48a30..b095d81a 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java +++ b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java @@ -17,7 +17,8 @@ public record PerformanceDetailResponse( String performanceContact, String performanceTeamName, List castList, - List staffList + List staffList, + int minDueDate ) { public static PerformanceDetailResponse of( Long performanceId, @@ -34,10 +35,26 @@ public static PerformanceDetailResponse of( String performanceContact, String performanceTeamName, List castList, - List staffList + List staffList, + int minDueDate ) { - return new PerformanceDetailResponse(performanceId, performanceTitle, performancePeriod, scheduleList, ticketPrice, genre, posterImage, runningTime, performanceVenue, performanceDescription, performanceAttentionNote, performanceContact, performanceTeamName, castList, staffList); + return new PerformanceDetailResponse( + performanceId, + performanceTitle, + performancePeriod, + scheduleList, + ticketPrice, + genre, + posterImage, + runningTime, + performanceVenue, + performanceDescription, + performanceAttentionNote, + performanceContact, + performanceTeamName, + castList, + staffList, + minDueDate + ); } - - } diff --git a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java index dcfe54c7..ce0808a0 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java +++ b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java @@ -5,9 +5,10 @@ public record PerformanceDetailSchedule( Long scheduleId, LocalDateTime performanceDate, - String scheduleNumber + String scheduleNumber, + int dueDate ) { - public static PerformanceDetailSchedule of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber) { - return new PerformanceDetailSchedule(scheduleId, performanceDate, scheduleNumber); + public static PerformanceDetailSchedule of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber, int dueDate) { + return new PerformanceDetailSchedule(scheduleId, performanceDate, scheduleNumber, dueDate); } } diff --git a/src/main/java/com/beat/domain/promotion/application/PromotionService.java b/src/main/java/com/beat/domain/promotion/application/PromotionService.java new file mode 100644 index 00000000..70d86270 --- /dev/null +++ b/src/main/java/com/beat/domain/promotion/application/PromotionService.java @@ -0,0 +1,44 @@ +package com.beat.domain.promotion.application; + +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.promotion.dao.PromotionRepository; +import com.beat.domain.promotion.domain.Promotion; +import com.beat.domain.schedule.application.ScheduleService; +import com.beat.domain.schedule.dao.ScheduleRepository; +import com.beat.domain.schedule.domain.Schedule; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class PromotionService { + + private final PromotionRepository promotionRepository; + private final ScheduleRepository scheduleRepository; + private final ScheduleService scheduleService; + + @Scheduled(cron = "1 0 0 * * ?") + @Transactional + public void checkAndDeleteInvalidPromotions() { + List promotions = promotionRepository.findAll(); + + for (Promotion promotion : promotions) { + Performance performance = promotion.getPerformance(); + + if (performance == null) { + return; + } + + List schedules = scheduleRepository.findByPerformanceId(performance.getId()); + int minDueDate = scheduleService.getMinDueDate(schedules); + + if (minDueDate < 0) { + promotionRepository.delete(promotion); + } + } + } +} diff --git a/src/main/java/com/beat/domain/promotion/domain/Promotion.java b/src/main/java/com/beat/domain/promotion/domain/Promotion.java index 445469ef..658c4f7b 100644 --- a/src/main/java/com/beat/domain/promotion/domain/Promotion.java +++ b/src/main/java/com/beat/domain/promotion/domain/Promotion.java @@ -20,19 +20,29 @@ public class Promotion { private String promotionPhoto; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "performance_id", nullable = false) + @JoinColumn(name = "performance_id", nullable = true) private Performance performance; + @Column(nullable = true) + private String redirectUrl; + + @Column(nullable = false) + private boolean isExternal; + @Builder - public Promotion(String promotionPhoto, Performance performance) { + public Promotion(String promotionPhoto, Performance performance, String redirectUrl, boolean isExternal) { this.promotionPhoto = promotionPhoto; this.performance = performance; + this.redirectUrl = redirectUrl; + this.isExternal = isExternal; } - public static Promotion create(String promotionPhoto, Performance performance) { + public static Promotion create(String promotionPhoto, Performance performance, String redirectUrl, boolean isExternal) { return Promotion.builder() .promotionPhoto(promotionPhoto) .performance(performance) + .redirectUrl(redirectUrl) + .isExternal(isExternal) .build(); } }