-
Notifications
You must be signed in to change notification settings - Fork 1
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
[feat]: 공연,날짜,회차에 대한 좌석 조회 API 추가 #42
Changes from 10 commits
a4b5c4a
3ca04db
2d462d1
d67ce94
5c71ae8
d00aa3b
d04118c
7aec39f
53d365b
7906643
a65dd13
af5bbe9
00ad503
b0172c6
ab37917
9fddc46
1715ae5
c4164d4
cd64c3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package dev.hooon.show; | ||
|
||
import java.time.LocalDate; | ||
|
||
import org.springframework.format.annotation.DateTimeFormat; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import dev.hooon.show.application.ShowSeatsService; | ||
import dev.hooon.show.dto.response.seats.ShowSeatsResponse; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class ShowSeatsApiController { | ||
|
||
private final ShowSeatsService showSeatsService; | ||
|
||
@GetMapping("/api/shows/{showId}/seats") | ||
public ResponseEntity<ShowSeatsResponse> getShowSeatsInfo( | ||
@PathVariable("showId") Long showId, | ||
@RequestParam("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, | ||
@RequestParam("round") int round | ||
) { | ||
ShowSeatsResponse showSeatsResponse = showSeatsService.findShowSeatsByShowIdAndDateAndRound( | ||
showId, date, round | ||
); | ||
return ResponseEntity.ok(showSeatsResponse); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package dev.hooon.show; | ||
|
||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; | ||
|
||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.test.context.jdbc.Sql; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
import org.springframework.test.web.servlet.ResultActions; | ||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | ||
|
||
import dev.hooon.common.support.ApiTestSupport; | ||
|
||
@DisplayName("[ShowSeatsApiController API 테스트]") | ||
@Sql("/sql/show_seats_dummy.sql") | ||
class ShowSeatsApiControllerTest extends ApiTestSupport { | ||
|
||
@Autowired | ||
private MockMvc mockMvc; | ||
|
||
@DisplayName("[공연 아이디, 날짜, 회차]를 통해 API 를 호출하면 해당 공연의 세부 정보를 조회할 수 있다") | ||
@Test | ||
void getShowSeatsInfoTest() throws Exception { | ||
|
||
// when | ||
ResultActions resultActions = mockMvc.perform( | ||
MockMvcRequestBuilders | ||
.get("/api/shows/1/seats?date=2024-01-01&round=2") | ||
); | ||
|
||
// then | ||
resultActions.andExpectAll( | ||
status().isOk(), | ||
|
||
jsonPath("$.seatsInfo").isArray(), | ||
jsonPath("$.seatsInfo[0].grade").isString(), | ||
jsonPath("$.seatsInfo[0].leftSeats").isNumber(), | ||
jsonPath("$.seatsInfo[0].price").isNumber(), | ||
jsonPath("$.seatsInfo[0].seats[0].id").isNumber(), | ||
jsonPath("$.seatsInfo[0].seats[0].date").isString(), | ||
jsonPath("$.seatsInfo[0].seats[0].isBookingAvailable").isString(), | ||
jsonPath("$.seatsInfo[0].seats[0].seat").isBoolean(), | ||
jsonPath("$.seatsInfo[0].seats[0].positionInfo_sector").isString(), | ||
jsonPath("$.seatsInfo[0].seats[0].positionInfo_row").isString(), | ||
jsonPath("$.seatsInfo[0].seats[0].positionInfo_col").isNumber(), | ||
|
||
jsonPath("$.seatsInfo").isArray(), | ||
jsonPath("$.seatsInfo[1].grade").isString(), | ||
jsonPath("$.seatsInfo[1].leftSeats").isNumber(), | ||
jsonPath("$.seatsInfo[1].price").isNumber(), | ||
jsonPath("$.seatsInfo[1].seats[0].id").isNumber(), | ||
jsonPath("$.seatsInfo[1].seats[0].date").isString(), | ||
jsonPath("$.seatsInfo[1].seats[0].isBookingAvailable").isString(), | ||
jsonPath("$.seatsInfo[1].seats[0].seat").isBoolean(), | ||
jsonPath("$.seatsInfo[1].seats[0].positionInfo_sector").isString(), | ||
jsonPath("$.seatsInfo[1].seats[0].positionInfo_row").isString(), | ||
jsonPath("$.seatsInfo[1].seats[0].positionInfo_col").isNumber(), | ||
|
||
jsonPath("$.seatsInfo").isArray(), | ||
jsonPath("$.seatsInfo[2].grade").isString(), | ||
jsonPath("$.seatsInfo[2].leftSeats").isNumber(), | ||
jsonPath("$.seatsInfo[2].price").isNumber(), | ||
jsonPath("$.seatsInfo[2].seats[0].id").isNumber(), | ||
jsonPath("$.seatsInfo[2].seats[0].date").isString(), | ||
jsonPath("$.seatsInfo[2].seats[0].isBookingAvailable").isString(), | ||
jsonPath("$.seatsInfo[2].seats[0].seat").isBoolean(), | ||
jsonPath("$.seatsInfo[2].seats[0].positionInfo_sector").isString(), | ||
jsonPath("$.seatsInfo[2].seats[0].positionInfo_row").isString(), | ||
jsonPath("$.seatsInfo[2].seats[0].positionInfo_col").isNumber() | ||
Comment on lines
+36
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 와우 꼼꼼하시네요 ㅋㅋㅋ 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 감사합니당 😆 |
||
); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package dev.hooon.show.application; | ||
|
||
import java.time.LocalDate; | ||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
import dev.hooon.common.exception.NotFoundException; | ||
import dev.hooon.show.domain.repository.SeatRepository; | ||
import dev.hooon.show.domain.repository.ShowRepository; | ||
import dev.hooon.show.dto.response.seats.SeatsDetailDto; | ||
import dev.hooon.show.dto.response.seats.SeatsInfoDto; | ||
import dev.hooon.show.dto.response.seats.ShowSeatsResponse; | ||
import dev.hooon.show.exception.ShowErrorCode; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ShowSeatsService { | ||
|
||
private final ShowRepository showRepository; | ||
private final SeatRepository seatRepository; | ||
|
||
public ShowSeatsResponse findShowSeatsByShowIdAndDateAndRound(Long showId, LocalDate date, int round) { | ||
|
||
throwIfShowDoesNotExist(showId); | ||
|
||
List<SeatsInfoDto> seatsInfoDtoList = seatRepository.findSeatInfoByShowIdAndDateAndRound(showId, | ||
date, round); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 파라미터를 한줄에 나열하거나 너무길면 한라인씩 분리해서 표현하는게 보기 좋을거같습니다 ..! ㅎㅎ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 반영완료했습니다! |
||
seatsInfoDtoList | ||
.forEach(it -> { | ||
List<SeatsDetailDto> seatsDetailDtoList = seatRepository.findSeatsByShowIdAndDateAndRoundAndGrade( | ||
showId, date, round, it.getGrade() | ||
); | ||
it.setSeats(seatsDetailDtoList); | ||
}); | ||
|
||
return new ShowSeatsResponse(seatsInfoDtoList); | ||
} | ||
|
||
private void throwIfShowDoesNotExist(Long showId) { | ||
showRepository.findById(showId).orElseThrow( | ||
() -> new NotFoundException(ShowErrorCode.SHOW_NOT_FOUND) | ||
); | ||
} | ||
Comment on lines
+52
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seat 에 대한 조회인데 저는 이부분에서 Show 에대한 검증이 없어도 될거같아요 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
|
||
import java.time.LocalDate; | ||
import java.time.LocalTime; | ||
import java.util.Objects; | ||
|
||
import org.springframework.util.Assert; | ||
|
||
|
@@ -33,91 +34,109 @@ | |
@NoArgsConstructor(access = PROTECTED) | ||
public class Seat extends TimeBaseEntity { | ||
|
||
private static final String SEAT = "seat"; | ||
|
||
@Id | ||
@GeneratedValue(strategy = IDENTITY) | ||
@Column(name = "seat_id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = LAZY) | ||
@JoinColumn(name = "seat_show_id", nullable = false, foreignKey = @ForeignKey(value = NO_CONSTRAINT)) | ||
private Show show; | ||
|
||
@Enumerated(STRING) | ||
@Column(name = "seat_grade", nullable = false) | ||
private SeatGrade seatGrade; | ||
|
||
@Column(name = "seat_is_seat", nullable = false) | ||
private boolean isSeat; | ||
|
||
@Embedded | ||
private SeatPositionInfo positionInfo; | ||
|
||
@Column(name = "seat_price", nullable = false) | ||
private int price; | ||
|
||
@Column(name = "seat_show_date", nullable = false) | ||
private LocalDate showDate; | ||
|
||
@Embedded | ||
private ShowRound showRound; | ||
|
||
@Enumerated(STRING) | ||
@Column(name = "seat_status", nullable = false) | ||
private SeatStatus seatStatus; | ||
|
||
private Seat( | ||
Show show, | ||
SeatGrade seatGrade, | ||
boolean isSeat, | ||
String sector, | ||
String row, | ||
int col, | ||
int price, | ||
LocalDate showDate, | ||
int round, | ||
LocalTime startTime, | ||
SeatStatus seatStatus | ||
) { | ||
Assert.notNull(show, getNotNullMessage(SEAT, "show")); | ||
Assert.notNull(seatGrade, getNotNullMessage(SEAT, "seatGrade")); | ||
Assert.hasText(sector, getNotEmptyPostfix(SEAT, "sector")); | ||
Assert.hasText(row, getNotEmptyPostfix(SEAT, "row")); | ||
Assert.notNull(showDate, getNotNullMessage(SEAT, "showDate")); | ||
Assert.notNull(startTime, getNotNullMessage(SEAT, "startTime")); | ||
Assert.notNull(seatStatus, getNotNullMessage(SEAT, "seatStatus")); | ||
this.show = show; | ||
this.seatGrade = seatGrade; | ||
this.isSeat = isSeat; | ||
this.positionInfo = new SeatPositionInfo(sector, row, col); | ||
this.price = price; | ||
this.showDate = showDate; | ||
this.showRound = new ShowRound(round, startTime); | ||
this.seatStatus = seatStatus; | ||
} | ||
|
||
public static Seat of( | ||
Show show, | ||
SeatGrade seatGrade, | ||
boolean isSeat, | ||
String sector, | ||
String row, | ||
int col, | ||
int price, | ||
LocalDate showDate, | ||
int round, | ||
LocalTime startTime, | ||
SeatStatus seatStatus | ||
) { | ||
return new Seat(show, seatGrade, isSeat, sector, row, col, price, showDate, round, startTime, seatStatus); | ||
} | ||
|
||
public int getRound() { | ||
return showRound.getRound(); | ||
} | ||
|
||
public LocalTime getStartTime() { | ||
return showRound.getStartTime(); | ||
} | ||
private static final String SEAT = "seat"; | ||
|
||
@Id | ||
@GeneratedValue(strategy = IDENTITY) | ||
@Column(name = "seat_id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = LAZY) | ||
@JoinColumn(name = "seat_show_id", nullable = false, foreignKey = @ForeignKey(value = NO_CONSTRAINT)) | ||
private Show show; | ||
|
||
@Enumerated(STRING) | ||
@Column(name = "seat_grade", nullable = false) | ||
private SeatGrade seatGrade; | ||
|
||
@Column(name = "seat_is_seat", nullable = false) | ||
private boolean isSeat; | ||
|
||
@Embedded | ||
private SeatPositionInfo positionInfo; | ||
|
||
@Column(name = "seat_price", nullable = false) | ||
private int price; | ||
|
||
@Column(name = "seat_show_date", nullable = false) | ||
private LocalDate showDate; | ||
|
||
@Embedded | ||
private ShowRound showRound; | ||
|
||
@Enumerated(STRING) | ||
@Column(name = "seat_status", nullable = false) | ||
private SeatStatus seatStatus; | ||
|
||
private Seat( | ||
Show show, | ||
SeatGrade seatGrade, | ||
boolean isSeat, | ||
String sector, | ||
String row, | ||
int col, | ||
int price, | ||
LocalDate showDate, | ||
int round, | ||
LocalTime startTime, | ||
SeatStatus seatStatus | ||
) { | ||
Assert.notNull(show, getNotNullMessage(SEAT, "show")); | ||
Assert.notNull(seatGrade, getNotNullMessage(SEAT, "seatGrade")); | ||
Assert.hasText(sector, getNotEmptyPostfix(SEAT, "sector")); | ||
Assert.hasText(row, getNotEmptyPostfix(SEAT, "row")); | ||
Assert.notNull(showDate, getNotNullMessage(SEAT, "showDate")); | ||
Assert.notNull(startTime, getNotNullMessage(SEAT, "startTime")); | ||
Assert.notNull(seatStatus, getNotNullMessage(SEAT, "seatStatus")); | ||
this.show = show; | ||
this.seatGrade = seatGrade; | ||
this.isSeat = isSeat; | ||
this.positionInfo = new SeatPositionInfo(sector, row, col); | ||
this.price = price; | ||
this.showDate = showDate; | ||
this.showRound = new ShowRound(round, startTime); | ||
this.seatStatus = seatStatus; | ||
} | ||
|
||
public static Seat of( | ||
Show show, | ||
SeatGrade seatGrade, | ||
boolean isSeat, | ||
String sector, | ||
String row, | ||
int col, | ||
int price, | ||
LocalDate showDate, | ||
int round, | ||
LocalTime startTime, | ||
SeatStatus seatStatus | ||
) { | ||
return new Seat(show, seatGrade, isSeat, sector, row, col, price, showDate, round, startTime, seatStatus); | ||
} | ||
|
||
public int getRound() { | ||
return showRound.getRound(); | ||
} | ||
|
||
public LocalTime getStartTime() { | ||
return showRound.getStartTime(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) | ||
return true; | ||
if (o == null || getClass() != o.getClass()) | ||
return false; | ||
Seat seat = (Seat)o; | ||
return isSeat == seat.isSeat && price == seat.price && Objects.equals(show, seat.show) | ||
&& seatGrade == seat.seatGrade && Objects.equals(positionInfo, seat.positionInfo) | ||
&& Objects.equals(showDate, seat.showDate) && Objects.equals(showRound, seat.showRound) | ||
&& seatStatus == seat.seatStatus; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(show, seatGrade, isSeat, positionInfo, price, showDate, showRound, seatStatus); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. id 비교도 추가하는게 좋을거같네요! |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런건 Request dto 를 만드는게 어떨까요??