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

[Feature] Step-2 잔여 좌석 조회 API 개발 #65

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.picketing.www.business.domain.show.seatgrade;
package com.picketing.www.business.domain.show.seat.grade;

import com.picketing.www.persistence.table.BaseEntity;

Expand All @@ -8,10 +8,12 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "SEATS")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
pollra marked this conversation as resolved.
Show resolved Hide resolved
public class Seat extends BaseEntity {
@Id
Expand All @@ -21,7 +23,4 @@ public class Seat extends BaseEntity {
@ManyToOne
@JoinColumn(name = "SEAT_GRADE_ID")
private SeatGrade seatGrade;

// TODO 23.09.13: Time schedule id mapping. @ManyToOne
private Long timeScheduleId;
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package com.picketing.www.business.domain.show.seatgrade;
package com.picketing.www.business.domain.show.seat.grade;

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

import com.picketing.www.business.domain.show.Show;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "SEAT_GRADES")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
pollra marked this conversation as resolved.
Show resolved Hide resolved
@Getter(AccessLevel.PROTECTED)
public class SeatGrade {

@Id
Expand All @@ -23,4 +32,11 @@ public class SeatGrade {
@ManyToOne
@JoinColumn(name = "SHOW_ID")
private Show show;

@OneToMany(mappedBy = "seatGrade", fetch = FetchType.LAZY)
private List<Seat> seats = new ArrayList<>();

private Long timeScheduleId;

private Long remainingSeatCount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.picketing.www.business.domain.show.seat.grade;

import java.util.List;

import org.springframework.stereotype.Component;

import com.picketing.www.presentation.dto.response.show.seat.grade.RemainingSeatCountResponse;

@Component
public class SeatGradeFactory {
public List<RemainingSeatCountResponse> toRemainingSeatCountResponses(List<SeatGrade> seatGrades) {
return seatGrades.stream()
.map(seatGrade -> {
return new RemainingSeatCountResponse(seatGrade.getId(), seatGrade.getName(),
seatGrade.getRemainingSeatCount());
})
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import org.springframework.stereotype.Service;

import com.picketing.www.business.domain.show.Show;
import com.picketing.www.business.domain.show.seat.grade.SeatGrade;
import com.picketing.www.business.service.show.seat.grade.SeatGradeService;
import com.picketing.www.business.type.Genre;
import com.picketing.www.business.type.SubGenre;
import com.picketing.www.persistence.repository.show.ShowRepository;
Expand All @@ -17,8 +19,13 @@
public class ShowService {

private final ShowRepository showRepository;
private final SeatGradeService seatGradeService;

public List<Show> getShowList(Genre genre, SubGenre subGenre, Pageable pageable) {
return showRepository.findShowsByGenreAndSubGenre(genre, subGenre, pageable);
}

public List<SeatGrade> getRemainingSeatCounts(Long showId, Long timeScheduleId) {
return seatGradeService.getRemainingSeatGradeCount(showId, timeScheduleId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.picketing.www.business.service.show.seat.grade;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.picketing.www.business.domain.show.seat.grade.SeatGrade;
import com.picketing.www.persistence.repository.show.seat.grade.SeatGradeRepository;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class SeatGradeService {

private final SeatGradeRepository seatGradeRepository;

@Transactional(readOnly = true)
public List<SeatGrade> getRemainingSeatGradeCount(Long showId, Long timeScheduleId) {
return seatGradeRepository.findAllByShowIdAndTimeScheduleId(showId,
timeScheduleId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.picketing.www.persistence.repository.show.seat.grade;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.picketing.www.business.domain.show.seat.grade.SeatGrade;

public interface SeatGradeRepository extends JpaRepository<SeatGrade, Long> {
List<SeatGrade> findAllByShowIdAndTimeScheduleId(Long showId, Long timeScheduleId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.picketing.www.business.domain.show.Show;
import com.picketing.www.business.domain.show.ShowFactory;
import com.picketing.www.business.domain.show.seat.grade.SeatGrade;
import com.picketing.www.business.domain.show.seat.grade.SeatGradeFactory;
import com.picketing.www.business.service.show.ShowService;
import com.picketing.www.business.type.Genre;
import com.picketing.www.business.type.SubGenre;
import com.picketing.www.presentation.dto.response.show.ShowMainResponse;
import com.picketing.www.presentation.dto.response.show.seat.grade.RemainingSeatCountResponse;

import lombok.RequiredArgsConstructor;

Expand All @@ -28,6 +32,7 @@
public class ShowController {

private final ShowFactory showFactory;
private final SeatGradeFactory seatGradeFactory;

private final ShowService showService;

Expand All @@ -42,4 +47,12 @@ public Page<ShowMainResponse> getShowListWithPagination(
.collect(Collectors.toList());
return new PageImpl<>(response, pageable, response.size());
}

@GetMapping("/{showId}/schedule/times/{timeScheduleId}/seats/grades/remaining-counts")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 api의 경우 날짜를 누른후, 공연시간 내부에서 등극별 남은좌석수를 조회하는 기능이군요.
그렇다면 아래 화면에서 보여야 되는군요

image
  1. client에서 넣어주어야 하는 timeScheduleId는 어떻게 알 수 있을까요?
    바로 직전화면인 montly 정보를 보여주는 화면은 /{showId}/schedules 을 통해 구성되는데 이때는 timeScheduleId를 알 수 없습니다.

  2. url path는 리소스의 접근을 의미하고 / 하나마다 리소스의 계층을 의미한다고 보면 매우 복잡한 구조를 사용한걸로 보입니다.
    화면구성에서 유저의 Input은 "날짜의 선택" 이었습니다. 이를 통해 더 간단하게 설계해 볼 수 있을까요?

public List<RemainingSeatCountResponse> getRemainingSeatCountsInShow(
@PathVariable Long showId, @PathVariable Long timeScheduleId
) {
List<SeatGrade> remainingSeatCounts = showService.getRemainingSeatCounts(showId, timeScheduleId);
return seatGradeFactory.toRemainingSeatCountResponses(remainingSeatCounts);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.picketing.www.presentation.dto.response.show.seat.grade;

public record RemainingSeatCountResponse(
Long id,
String name,
Long remainingSeatCount
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,33 @@ void hasGenreAndSubGenreSearchQuery() throws Exception {
.andExpect(status().isOk());
}
}

@Nested
@DisplayName("SeatGrade 남은 좌석 조회")
class GetRemainingSeatCountsInShow {

@Test
@DisplayName("데이터가 존재하지 않는 경우 정상 조회")
void noDataButOk() throws Exception {
MockHttpSession session = new MockHttpSession();
session.setAttribute("login_user", 1L);

Integer showId = 1;
Integer timeScheduleId = 1;
String url = String.format(
"/api/shows/%s/schedule/times/%s/seats/grades/remaining-counts",
showId, timeScheduleId
);

System.out.println("url: " + url);

mockMvc.perform(
MockMvcRequestBuilders
.get(url)
.session(session)
.accept(MediaType.APPLICATION_JSON)
).andDo(print())
.andExpect(status().isOk());
}
}
}
Loading