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: 구역의 좌석목록을 조회하는 API를 구현한다. #35

Merged
merged 13 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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
12 changes: 10 additions & 2 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ operation::member-controller-test/create-member[snippets='http-response,response

= 공연(Performance)

= 장소(Place)

= 좌석(Seat)

== 관리자 좌석 등급 생성 API
Expand All @@ -43,6 +41,16 @@ operation::admin-seat-controller-test/create-seats[snippets='http-request,path-p

operation::admin-seat-controller-test/create-seat-grades[snippets='http-response']

== 구역의 좌석 목록 조회

=== request

operation::seat-controller-test/get-zones[snippets='http-request,path-parameters']

=== response

operation::seat-controller-test/get-zones[snippets='http-response,response-fields']

= 티켓(Ticket)

= API 문서화 예시
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@AllArgsConstructor
public class ItemResult<T> {

private List<T> item;
private List<T> items;
seminchoi marked this conversation as resolved.
Show resolved Hide resolved

public static <T> ItemResult<T> of(List<T> items) {
return new ItemResult<T>(items);
Expand Down
14 changes: 10 additions & 4 deletions src/main/java/com/thirdparty/ticketing/domain/seat/Seat.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import jakarta.persistence.*;

import com.thirdparty.ticketing.domain.BaseEntity;
import com.thirdparty.ticketing.domain.member.Member;
import com.thirdparty.ticketing.domain.zone.Zone;

import lombok.AccessLevel;
Expand All @@ -23,19 +24,24 @@ public class Seat extends BaseEntity {
private Long seatId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "zone_id")
@JoinColumn(name = "zone_id", nullable = false)
private Zone zone;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "seat_Grade")
@JoinColumn(name = "seat_Grade", nullable = false)
private SeatGrade seatGrade;

@Column(length = 32)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

@Column(length = 32, nullable = false)
private String seatCode;

@Enumerated(EnumType.STRING)
@Builder.Default
private SeatStatus seatStatus = SeatStatus.AVAILABLE;
@Column(length = 16, nullable = false)
private SeatStatus seatStatus = SeatStatus.SELECTABLE;

public Seat(String seatCode, SeatStatus seatStatus) {
this.seatCode = seatCode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.thirdparty.ticketing.domain.seat;

public enum SeatStatus {
AVAILABLE,
SELECTABLE,
SELECTED,
PENDING_PAYMENT,
PAID
PAID;

public boolean isSelectable() {
return this == SELECTABLE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.thirdparty.ticketing.domain.seat.dto.SeatCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.SeatGradeCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatGradeCreationRequest;
import com.thirdparty.ticketing.domain.seat.service.AdminSeatService;

import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.thirdparty.ticketing.domain.seat.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.thirdparty.ticketing.domain.ItemResult;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatElement;
import com.thirdparty.ticketing.domain.seat.service.SeatService;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class SeatController {
private final SeatService seatService;

@GetMapping("/performances/{performanceId}/zones/{zoneId}/seats")
public ResponseEntity<ItemResult<SeatElement>> getSeats(@PathVariable("zoneId") long zoneId) {
ItemResult<SeatElement> seats = seatService.getSeats(zoneId);
return ResponseEntity.ok().body(seats);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.thirdparty.ticketing.domain.seat.dto;
package com.thirdparty.ticketing.domain.seat.dto.request;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.thirdparty.ticketing.domain.seat.dto;
package com.thirdparty.ticketing.domain.seat.dto.request;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.thirdparty.ticketing.domain.seat.dto;
package com.thirdparty.ticketing.domain.seat.dto.request;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.thirdparty.ticketing.domain.seat.dto;
package com.thirdparty.ticketing.domain.seat.dto.request;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.thirdparty.ticketing.domain.seat.dto.response;

import com.thirdparty.ticketing.domain.seat.Seat;

import lombok.Data;

@Data
public class SeatElement {
private final long seatId;
private final String seatCode;
private final boolean seatAvailable;

public static SeatElement of(Seat seat) {
boolean isSeatAvailable = seat.getSeatStatus().isSelectable();
seminchoi marked this conversation as resolved.
Show resolved Hide resolved
return new SeatElement(seat.getSeatId(), seat.getSeatCode(), isSeatAvailable);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.thirdparty.ticketing.domain.seat.repository;

import java.util.List;

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

import com.thirdparty.ticketing.domain.seat.Seat;
import com.thirdparty.ticketing.domain.zone.Zone;

@Repository
public interface SeatRepository extends JpaRepository<Seat, Long> {}
public interface SeatRepository extends JpaRepository<Seat, Long> {
List<Seat> findByZone(Zone zone);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import com.thirdparty.ticketing.domain.performance.repository.PerformanceRepository;
import com.thirdparty.ticketing.domain.seat.Seat;
import com.thirdparty.ticketing.domain.seat.SeatGrade;
import com.thirdparty.ticketing.domain.seat.dto.SeatCreationElement;
import com.thirdparty.ticketing.domain.seat.dto.SeatCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.SeatGradeCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatCreationElement;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatGradeCreationRequest;
import com.thirdparty.ticketing.domain.seat.repository.SeatGradeRepository;
import com.thirdparty.ticketing.domain.seat.repository.SeatRepository;
import com.thirdparty.ticketing.domain.zone.Zone;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.thirdparty.ticketing.domain.seat.service;

import java.util.List;

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

import com.thirdparty.ticketing.domain.ItemResult;
import com.thirdparty.ticketing.domain.common.TicketingException;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatElement;
import com.thirdparty.ticketing.domain.seat.repository.SeatRepository;
import com.thirdparty.ticketing.domain.zone.Zone;
import com.thirdparty.ticketing.domain.zone.repository.ZoneRepository;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class SeatService {
private final ZoneRepository zoneRepository;
private final SeatRepository seatRepository;

@Transactional(readOnly = true)
public ItemResult<SeatElement> getSeats(Long zoneId) {
Zone zone = zoneRepository.findById(zoneId).orElseThrow(() -> new TicketingException(""));
List<SeatElement> seats =
seatRepository.findByZone(zone).stream().map(SeatElement::of).toList();

return ItemResult.of(seats);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.thirdparty.ticketing.domain.zone.service;

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

import com.thirdparty.ticketing.domain.ItemResult;
import com.thirdparty.ticketing.domain.common.TicketingException;
import com.thirdparty.ticketing.domain.performance.Performance;
import com.thirdparty.ticketing.domain.performance.repository.PerformanceRepository;
import com.thirdparty.ticketing.domain.zone.dto.ZoneElement;
Expand All @@ -17,8 +19,12 @@ public class UserZoneService {
private final ZoneRepository zoneRepository;
private final PerformanceRepository performanceRepository;

@Transactional(readOnly = true)
public ItemResult<ZoneElement> getZones(Long performanceId) {
Performance performance = performanceRepository.findById(performanceId).orElseThrow();
Performance performance =
performanceRepository
.findById(performanceId)
.orElseThrow(() -> new TicketingException(""));
return ItemResult.of(
zoneRepository.findByPerformance(performance).stream()
.map(ZoneElement::of)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
Expand All @@ -18,7 +17,6 @@
import org.springframework.test.web.servlet.ResultActions;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.thirdparty.ticketing.domain.performance.dto.request.PerformanceCreationRequest;
import com.thirdparty.ticketing.domain.performance.service.AdminPerformanceService;
import com.thirdparty.ticketing.support.BaseControllerTest;
Expand All @@ -29,8 +27,6 @@ class AdminPerformanceControllerTest extends BaseControllerTest {

@MockBean private AdminPerformanceService adminPerformanceService;

@Autowired private ObjectMapper objectMapper;

@Test
@DisplayName("POST /api/performances")
void createPerformance() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ void getPerformances() throws Exception {
.andDo(
restDocs.document(
responseFields(
fieldWithPath("item").description("공연 목록"),
fieldWithPath("item[].performanceId").description("공연 ID"),
fieldWithPath("item[].performanceName")
fieldWithPath("items").description("공연 목록"),
fieldWithPath("items[].performanceId").description("공연 ID"),
fieldWithPath("items[].performanceName")
.description("공연 이름"),
fieldWithPath("item[].performancePlace")
fieldWithPath("items[].performancePlace")
.description("공연 장소"),
fieldWithPath("item[].performanceShowtime")
fieldWithPath("items[].performanceShowtime")
.description("공연 시간"))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void getPerformances_Success() {
userPerformanceService.getPerformances();

// Then
assertThat(performanceElements.getItem())
assertThat(performanceElements.getItems())
.isNotEmpty()
.hasSize(2)
.satisfies(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
Expand All @@ -20,11 +19,10 @@
import org.springframework.test.web.servlet.ResultActions;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.thirdparty.ticketing.domain.seat.dto.SeatCreationElement;
import com.thirdparty.ticketing.domain.seat.dto.SeatCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.SeatGradeCreationElement;
import com.thirdparty.ticketing.domain.seat.dto.SeatGradeCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatCreationElement;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatCreationRequest;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatGradeCreationElement;
import com.thirdparty.ticketing.domain.seat.dto.request.SeatGradeCreationRequest;
import com.thirdparty.ticketing.domain.seat.service.AdminSeatService;
import com.thirdparty.ticketing.support.BaseControllerTest;

Expand All @@ -34,8 +32,6 @@ public class AdminSeatControllerTest extends BaseControllerTest {

@MockBean private AdminSeatService adminSeatService;

@Autowired private ObjectMapper objectMapper;

@Test
@DisplayName("관리자 좌석 생성 API")
void createSeats() throws Exception {
Expand Down
Loading
Loading