Skip to content

Commit

Permalink
feat: 티켓팅 알림 설정 후 종료된 공연 목록, 개수 API (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
GaBaljaintheroom authored Aug 21, 2024
1 parent 58302ce commit 23cd82f
Show file tree
Hide file tree
Showing 19 changed files with 171 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ private RequestMatcher getMatcherForUserAndAdmin() {
antMatcher(HttpMethod.POST, "/api/v1/shows/{showId}/alert"),
antMatcher(HttpMethod.GET, "/api/v1/shows/alerts"),
antMatcher(HttpMethod.GET, "/api/v1/shows/{showId}/alert/reservations"),
antMatcher(HttpMethod.GET, "/api/v1/shows/terminated/ticketing/count"),
antMatcher(HttpMethod.POST, "/api/v1/genres/subscribe"),
antMatcher(HttpMethod.POST, "/api/v1/genres/unsubscribe"),
antMatcher(HttpMethod.GET, "/api/v1/genres/subscriptions"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.example.show.controller.dto.response.ShowDetailApiResponse;
import com.example.show.controller.dto.response.ShowInterestApiResponse;
import com.example.show.controller.dto.response.ShowPaginationApiParam;
import com.example.show.controller.dto.response.TerminatedTicketingShowCountApiResponse;
import com.example.show.controller.dto.response.TicketingAlertReservationApiResponse;
import com.example.show.controller.vo.TicketingApiType;
import com.example.show.service.ShowService;
Expand Down Expand Up @@ -193,6 +194,18 @@ public ResponseEntity<PaginationApiResponse<ShowSearchPaginationApiParam>> searc
);
}

@GetMapping("/terminated/ticketing/count")
@Operation(summary = "티켓팅 알림 설정 후 공연이 종료된 개수")
public ResponseEntity<TerminatedTicketingShowCountApiResponse> getNumberOfTerminatedTicketingShowCount(
@AuthenticationPrincipal AuthenticatedUser user
) {
return ResponseEntity.ok(
TerminatedTicketingShowCountApiResponse.from(
showService.countTerminatedTicketingShow(user.userId())
)
);
}

@PatchMapping("/{showId}/view")
@Operation(summary = "공연 조회수 증가")
public void view(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public record ShowAlertPaginationApiParam(
@Schema(description = "공연 이미지")
String image,

@Schema(description = "cursorID로서 공연 티켓팅 시간 ID")
UUID showTicketingTimeId,

@Schema(description = "cursorValue로서 공연 티켓팅 날짜")
LocalDateTime ticketingAt
) {
Expand All @@ -37,6 +40,7 @@ public static ShowAlertPaginationApiParam from(ShowAlertPaginationServiceParam s
DateTimeUtil.formatDate(serviceParam.endAt()),
serviceParam.location(),
serviceParam.image(),
serviceParam.showTicketingTimeId(),
serviceParam.ticketingAt()
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.show.controller.dto.request;

import com.example.show.service.dto.request.ShowAlertPaginationServiceRequest;
import com.example.show.vo.ShowTicketingAtStatusApiType;
import io.swagger.v3.oas.annotations.Parameter;
import java.time.LocalDateTime;
import java.util.UUID;
Expand All @@ -9,19 +10,24 @@ public record ShowAlertPaginationApiRequest(

@Parameter(description = "페이지네이션 데이터 개수", required = true)
int size,
@Parameter(description = "이전 페이지네이션 마지막 데이터의 ID / 최초 조회라면 null")

@Parameter(description = "공연 티켓팅 상태 타입", required = true)
ShowTicketingAtStatusApiType type,

@Parameter(description = "이전 페이지네이션 마지막 데이터의 showTicketingTimeId / 최초 조회라면 null")
UUID cursorId,

@Parameter(description = "이전 페이지네이션 마지막 데이터의 ticketingAt / 최초 조회라면 null")
LocalDateTime curSorValue
LocalDateTime cursorValue
) {

public ShowAlertPaginationServiceRequest toServiceRequest(UUID userId) {
return ShowAlertPaginationServiceRequest.builder()
.userId(userId)
.size(size)
.type(type)
.cursorId(cursorId)
.cursorValue(curSorValue)
.cursorValue(cursorValue)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.show.controller.dto.response;

import com.example.show.service.dto.response.TerminatedTicketingShowCountServiceResponse;
import io.swagger.v3.oas.annotations.media.Schema;

public record TerminatedTicketingShowCountApiResponse(
@Schema(description = "개수")
long count
) {

public static TerminatedTicketingShowCountApiResponse from(
TerminatedTicketingShowCountServiceResponse response
) {
return new TerminatedTicketingShowCountApiResponse(response.count());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
import com.example.show.service.dto.response.ShowDetailServiceResponse;
import com.example.show.service.dto.response.ShowInterestServiceResponse;
import com.example.show.service.dto.response.ShowPaginationServiceResponse;
import com.example.show.service.dto.response.TerminatedTicketingShowCountServiceResponse;
import com.example.show.service.dto.response.TicketingAlertReservationAvailabilityServiceResponse;
import com.example.show.service.dto.response.TicketingAlertReservationServiceResponse;
import com.example.show.service.dto.response.TicketingAlertReservationStatusServiceResponse;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
Expand All @@ -35,7 +37,6 @@
import org.example.exception.BusinessException;
import org.example.usecase.TicketingAlertUseCase;
import org.example.usecase.UserShowUseCase;
import org.example.usecase.show.ShowTicketingTimeUseCase;
import org.example.usecase.show.ShowUseCase;
import org.springframework.stereotype.Service;

Expand All @@ -44,7 +45,6 @@
public class ShowService {

private final ShowUseCase showUseCase;
private final ShowTicketingTimeUseCase showTicketingTimeUseCase;
private final TicketingAlertUseCase ticketingAlertUseCase;
private final UserShowUseCase userShowUseCase;
private final MessagePublisher messagePublisher;
Expand Down Expand Up @@ -164,19 +164,35 @@ public void alertReservation(
public PaginationServiceResponse<ShowAlertPaginationServiceParam> findAlertShows(
ShowAlertPaginationServiceRequest request
) {
List<TicketingAlert> ticketingAlerts = ticketingAlertUseCase.findTicketingAlertsByUserId(
request.userId());
List<TicketingAlert> ticketingAlerts = ticketingAlertUseCase.findTicketingAlertsByUserId(request.userId());
List<UUID> showIdsToAlert = ticketingAlerts.stream()
.map(TicketingAlert::getShowId).distinct()
.map(TicketingAlert::getShowId)
.distinct()
.toList();

ShowAlertPaginationDomainResponse alertShows = showTicketingTimeUseCase.findAlertShows(
request.toDomainRequest(showIdsToAlert));
ShowAlertPaginationDomainResponse alertShows = showUseCase.findAlertShows(
request.toDomainRequest(showIdsToAlert, LocalDateTime.now()));

return PaginationServiceResponse.of(alertShows.data().stream()
.map(ShowAlertPaginationServiceParam::from)
.toList(),
alertShows.hasNext()
);
}

public TerminatedTicketingShowCountServiceResponse countTerminatedTicketingShow(UUID userId) {
List<TicketingAlert> ticketingAlerts = ticketingAlertUseCase.findTicketingAlertsByUserId(userId);
List<UUID> showIdsToAlert = ticketingAlerts.stream()
.map(TicketingAlert::getShowId)
.distinct()
.toList();

if (showIdsToAlert.isEmpty()) {
return TerminatedTicketingShowCountServiceResponse.noCount();
}

return TerminatedTicketingShowCountServiceResponse.from(
showUseCase.findTerminatedTicketingShowsCount(showIdsToAlert, LocalDateTime.now())
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public record ShowAlertPaginationServiceParam(
LocalDate endAt,
String location,
String image,
UUID showTicketingTimeId,
LocalDateTime ticketingAt
) {

Expand All @@ -25,6 +26,7 @@ public static ShowAlertPaginationServiceParam from(ShowAlertDomainResponse alert
.endAt(alertShow.endAt())
.location(alertShow.location())
.image(alertShow.image())
.showTicketingTimeId(alertShow.showTicketingTimeId())
.ticketingAt(alertShow.ticketingAt())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.show.service.dto.request;

import com.example.show.vo.ShowTicketingAtStatusApiType;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
Expand All @@ -10,17 +11,23 @@
public record ShowAlertPaginationServiceRequest(
UUID userId,
int size,
ShowTicketingAtStatusApiType type,
UUID cursorId,
LocalDateTime cursorValue
) {

public ShowAlertPaginationDomainRequest toDomainRequest(List<UUID> showIds) {
public ShowAlertPaginationDomainRequest toDomainRequest(
List<UUID> showIds,
LocalDateTime now
) {
return ShowAlertPaginationDomainRequest.builder()
.showIds(showIds)
.userId(userId)
.size(size)
.type(type.toDomainType())
.cursorId(cursorId)
.cursorValue(cursorValue)
.now(now)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.show.service.dto.response;

public record TerminatedTicketingShowCountServiceResponse(
long count
) {
public static TerminatedTicketingShowCountServiceResponse noCount() {
return new TerminatedTicketingShowCountServiceResponse(0);
}

public static TerminatedTicketingShowCountServiceResponse from(long count) {
return new TerminatedTicketingShowCountServiceResponse(count);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.show.vo;

import org.example.vo.ShowTicketingAtStatus;

public enum ShowTicketingAtStatusApiType {

TERMINATED,
CONTINUED;

public ShowTicketingAtStatus toDomainType() {
return switch (this) {
case TERMINATED -> ShowTicketingAtStatus.TERMINATED;
case CONTINUED -> ShowTicketingAtStatus.CONTINUED;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.assertj.core.api.SoftAssertions;
import org.example.usecase.TicketingAlertUseCase;
import org.example.usecase.UserShowUseCase;
import org.example.usecase.show.ShowTicketingTimeUseCase;
import org.example.usecase.show.ShowUseCase;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand All @@ -18,13 +17,11 @@
class ShowServiceTest {

private final ShowUseCase showUseCase = mock(ShowUseCase.class);
private final ShowTicketingTimeUseCase showTicketingTimeUseCase = mock(ShowTicketingTimeUseCase.class);
private final UserShowUseCase userShowUseCase = mock(UserShowUseCase.class);
private final TicketingAlertUseCase ticketingAlertUseCase = mock(TicketingAlertUseCase.class);
private final MessagePublisher messagePublisher = mock(MessagePublisher.class);
private final ShowService showService = new ShowService(
showUseCase,
showTicketingTimeUseCase,
ticketingAlertUseCase,
userShowUseCase,
messagePublisher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
import java.util.List;
import java.util.UUID;
import lombok.Builder;
import org.example.vo.ShowTicketingAtStatus;

@Builder
public record ShowAlertPaginationDomainRequest(
List<UUID> showIds,
UUID userId,
int size,
ShowTicketingAtStatus type,
UUID cursorId,
LocalDateTime cursorValue
LocalDateTime cursorValue,
LocalDateTime now
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public record ShowAlertDomainResponse(
LocalDate endAt,
String location,
String image,
UUID showTicketingTimeId,
LocalDateTime ticketingAt
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.example.dto.show.response.ShowInfoDomainResponse;
import org.example.dto.show.response.ShowPaginationDomainResponse;
import org.example.dto.show.response.ShowWithTicketingTimesDomainResponse;
import org.example.entity.show.Show;

public interface ShowQuerydslRepository {

Expand All @@ -21,5 +20,5 @@ public interface ShowQuerydslRepository {

Optional<ShowInfoDomainResponse> findShowInfoById(UUID id);

List<Show> findNotFinishedShowsIn(List<UUID> showIds, LocalDateTime now);
long findTerminatedTicketingShowsCount(List<UUID> showIds, LocalDateTime now);
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,22 @@ public ShowPaginationDomainResponse findShows(ShowPaginationDomainRequest reques
}

@Override
public List<Show> findNotFinishedShowsIn(List<UUID> showIds, LocalDateTime now) {
return jpaQueryFactory
.selectFrom(show)
public long findTerminatedTicketingShowsCount(List<UUID> showIds, LocalDateTime now) {
Long result = jpaQueryFactory
.select(show.id.countDistinct())
.from(show)
.where(
show.isDeleted.isFalse()
.and(show.id.in(showIds))
.and(show.lastTicketingAt.after(now))
.and(show.lastTicketingAt.before(now))
)
.fetch();
.fetchFirst();

return result == null ? 0 : result;
}

private List<ShowDetailDomainResponse> findShowsByPopularity(ShowPaginationDomainRequest request) {
private List<ShowDetailDomainResponse> findShowsByPopularity(
ShowPaginationDomainRequest request) {
BooleanExpression whereExpression = show.isDeleted.isFalse();

if (request.cursorId() != null) {
Expand Down Expand Up @@ -169,7 +173,8 @@ private List<ShowDetailDomainResponse> findShowsByPopularity(ShowPaginationDomai
.toList();
}

private List<ShowDetailDomainResponse> findShowsByClosestTicketingAt(ShowPaginationDomainRequest request) {
private List<ShowDetailDomainResponse> findShowsByClosestTicketingAt(
ShowPaginationDomainRequest request) {
JPAQuery<LocalDateTime> closestTicketingTimeQuery = jpaQueryFactory
.select(showTicketingTime.ticketingAt.min())
.from(showTicketingTime)
Expand All @@ -181,8 +186,10 @@ private List<ShowDetailDomainResponse> findShowsByClosestTicketingAt(ShowPaginat

if (request.cursorId() != null) {
whereExpression.and(
closestTicketingTimeQuery.gt(DateTimeUtil.parseDateTime(request.cursorValue().toString()))
.or(closestTicketingTimeQuery.eq(DateTimeUtil.parseDateTime(request.cursorValue().toString()))
closestTicketingTimeQuery.gt(
DateTimeUtil.parseDateTime(request.cursorValue().toString()))
.or(closestTicketingTimeQuery.eq(
DateTimeUtil.parseDateTime(request.cursorValue().toString()))
.and(show.id.gt(request.cursorId()))
)
);
Expand All @@ -196,7 +203,8 @@ private List<ShowDetailDomainResponse> findShowsByClosestTicketingAt(ShowPaginat
.selectFrom(show)
.leftJoin(showGenre).on(show.id.eq(showGenre.showId).and(showGenre.isDeleted.isFalse()))
.leftJoin(genre).on(showGenre.genreId.eq(genre.id).and(genre.isDeleted.isFalse()))
.leftJoin(showArtist).on(show.id.eq(showArtist.showId).and(showArtist.isDeleted.isFalse()))
.leftJoin(showArtist)
.on(show.id.eq(showArtist.showId).and(showArtist.isDeleted.isFalse()))
.leftJoin(artist).on(showArtist.artistId.eq(artist.id).and(artist.isDeleted.isFalse()))
.leftJoin(showTicketingTime)
.on(show.id.eq(showTicketingTime.show.id).and(showTicketingTime.isDeleted.isFalse()))
Expand Down
Loading

0 comments on commit 23cd82f

Please sign in to comment.