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

[3 - 4단계 방탈출 예약 대기] 카피(김상혁) 미션 제출합니다. #107

Merged
merged 47 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
9d1798e
fix: 불필요 ddl 컬럼 삭제
tkdgur0906 May 20, 2024
f5047da
refactor: jpa 자동 ddl 생성 none 설정
tkdgur0906 May 20, 2024
ae81820
feat: 3단계 클라이언트 코드 추가
tkdgur0906 May 20, 2024
f2b0572
chore: jpa ddl auto를 validate로 변경
tkdgur0906 May 20, 2024
a14d4ed
refactor: 예약 여부 객체 이름 명확히 변경
tkdgur0906 May 20, 2024
fa12a9b
feat: 예약 엔티티에 예약 상태 필드 추가 및 예약 생성 시 예약,대기 여부 받도록 변경
tkdgur0906 May 20, 2024
711f902
feat: 예약 대기 요청 api 구현
tkdgur0906 May 21, 2024
f3921df
feat: 예약 상태 출력 시 예약, 예약대기를 구분하여 출력하는 기능 구현
tkdgur0906 May 21, 2024
c34818a
feat: 이미 요청한 예약, 예약대기가 존재하는지 검증하는 기능 구현
tkdgur0906 May 21, 2024
105b664
feat: 예약페이지 시간 출력 시 시,분만 출력되도록 기능 추가
tkdgur0906 May 21, 2024
61eff92
feat: 기본 예약 대기 데이터 추가
tkdgur0906 May 21, 2024
4ffdea9
feat: 예약 대기 취소 api 구현
tkdgur0906 May 21, 2024
f537c88
refactor: 예약 대기 api 엔드포인트 waitings로 변경
tkdgur0906 May 21, 2024
904e2b5
refactor: 예약 삭제 api 메서드 명 올바르게 수정
tkdgur0906 May 21, 2024
b8efcd6
feat: 모든 엔티티 생성시간 저장하도록 컬럼 추가
tkdgur0906 May 21, 2024
300be37
refactor: 작성 쿼리 가독성있게 변경
tkdgur0906 May 21, 2024
b7cf143
feat: 내 예약 목록의 예약 대기 상태에 몇번째 대기인지 포함하는 기능 구현
tkdgur0906 May 22, 2024
aee0764
feat: 4단계 예약 대기 관리 기능 클라이언트 코드 추가
tkdgur0906 May 22, 2024
c68f262
feat: 예약 대기 관리 페이지 렌더링 기능 구현
tkdgur0906 May 22, 2024
94255cb
refactor: 예약대기 엔드포인트 waiting 으로 변경
tkdgur0906 May 22, 2024
8af3ed5
feat: 예약 대기 목록 조회하는 api 구현
tkdgur0906 May 22, 2024
2a92b00
feat: 어드민 예약 대기 조회 페이지 네비게이션 바 추가
tkdgur0906 May 22, 2024
f5234a0
feat: 예약 대기 취소 api 구현
tkdgur0906 May 22, 2024
8d5500d
feat: 예약 취소 발생시 예약 대기 자동으로 승인하는 기능 구현
tkdgur0906 May 22, 2024
2a06d47
style: 전체 코드 가독성 있게 줄바꿈 적용
tkdgur0906 May 23, 2024
71d23b4
refactor: api 엔드포인트 맨앞에 /api를 붙여 구분하도록 변경
tkdgur0906 May 23, 2024
4488375
feat: 예약 삭제를 관리자만 가능하도록 기능 추가
tkdgur0906 May 23, 2024
952c1a6
feat: 예약 시간 추가, 삭제를 관리자만 가능하도록 기능 추가
tkdgur0906 May 23, 2024
dd60fc5
feat: 테마 추가, 삭제를 관리자만 가능하도록 기능 추가
tkdgur0906 May 23, 2024
8f0f7bd
test: 실패하는 테스트 수정
tkdgur0906 May 23, 2024
72340aa
feat: 예약 대기 삭제 시 본인, 관리자만 삭제할 수 있도록 기능 추가
tkdgur0906 May 23, 2024
e6922d2
refactor: 특정 날짜, 테마의 시간 별 예약 여부를 찾는 메서드 이름 명확히 변경
tkdgur0906 May 24, 2024
90b837e
refactor: 예약 상태 변경 메서드 파라미터 받아서 적용하도록 변경
tkdgur0906 May 24, 2024
e30e447
refactor: enum 비교 ==로 하도록 변경
tkdgur0906 May 24, 2024
91161ad
refactor: User를 Member로 명명 통일
tkdgur0906 May 24, 2024
a1df0cf
refactor: 서비스 CRD로 분류하지 않고 하나로 통일
tkdgur0906 May 26, 2024
a439eec
refactor: 예약, 대기 요청 여부을 클라이언트에서 request로 넘기도록 변경하여 하나의 예약 api에서 처리하도록 변경
tkdgur0906 May 26, 2024
3e8fe2c
feat: 사용자가 예약 삭제 시 예약 대기만 삭제할 수 있도록 검증
tkdgur0906 May 26, 2024
aeb44de
refactor: 사용자 예약 대기 취소 api 엔드포인트 reservations으로 변경
tkdgur0906 May 26, 2024
26b29a6
fix: 잘못된 테마 삭제 엔드포인트 수정
tkdgur0906 May 26, 2024
e3498d6
refactor: 모든 예약, 예약 대기 삭제 api를 예약 삭제 api 하나로 통일
tkdgur0906 May 26, 2024
0ea3648
refactor: 관리자 예약 목록 리스트 조회 api 엔드포인트 리소스를 예약으로 변경
tkdgur0906 May 26, 2024
fa306e2
refactor: 중복되는 api RequestMapping으로 공통 처리
tkdgur0906 May 26, 2024
f4e466e
refactor: 예약 대기 목록 조회 메서드 대신 예약 상태에 따라 조회할 수 있도록 변경
tkdgur0906 May 26, 2024
4ce74c0
refactor: 예약 여부 반환하는 메서드 equals 대신 contains 사용
tkdgur0906 May 26, 2024
17c2c6a
style: sql 들여쓰기
tkdgur0906 May 26, 2024
15083f8
refactor: reservation 버튼 클릭시 홈으로 가지 않고 예약 페이지로 이동하도록 변경
tkdgur0906 May 26, 2024
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
2 changes: 2 additions & 0 deletions src/main/java/roomescape/RoomescapeApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
public class RoomescapeApplication {
public static void main(String[] args) {
SpringApplication.run(RoomescapeApplication.class, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import roomescape.auth.AuthenticatedMember;
import roomescape.domain.Member;
import roomescape.domain.Reservation;
import roomescape.domain.ReservationStatus;
import roomescape.domain.ReservationWaitingWithRank;
import roomescape.service.dto.request.ReservationSaveRequest;
import roomescape.service.dto.response.ReservationResponse;
import roomescape.service.dto.response.UserReservationResponse;
Expand Down Expand Up @@ -51,9 +53,9 @@ public ResponseEntity<List<ReservationResponse>> getReservations() {

@GetMapping("/reservations-mine")
public ResponseEntity<List<UserReservationResponse>> getUserReservations(@AuthenticatedMember Member member) {
List<Reservation> userReservations = reservationFindService.findUserReservations(member.getId());
List<ReservationWaitingWithRank> reservationWaitingWithRanks = reservationFindService.findMemberReservations(member.getId());

Choose a reason for hiding this comment

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

한줄에 120자는 넘지 않도록 해주세요!
다른곳들도 챙겨봐주세요 많은 곳들이 120자를 넘는것 같네요

Copy link
Member Author

Choose a reason for hiding this comment

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

구현에만 급급해서 가독성 측면에서 많이 부족했던 것 같습니다😅
전체적으로 수정해보았는데 다시 한번 확인해주실 수 있을까요?
파라미터 여러개 존재 하는 경우, 120자가 넘어가는 경우에 줄바꿈을 해주었습니다!

return ResponseEntity.ok(
userReservations.stream()
reservationWaitingWithRanks.stream()
.map(UserReservationResponse::new)
.toList()
);
Expand All @@ -62,7 +64,7 @@ public ResponseEntity<List<UserReservationResponse>> getUserReservations(@Authen
@PostMapping("/reservations")
public ResponseEntity<ReservationResponse> addReservationByUser(@RequestBody @Valid ReservationSaveRequest request,
@AuthenticatedMember Member member) {
Reservation newReservation = reservationCreateService.createReservation(request, member);
Reservation newReservation = reservationCreateService.createReservation(request, member, ReservationStatus.RESERVED);
return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId()))
.body(new ReservationResponse(newReservation));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import roomescape.domain.ReservationStatus;
import roomescape.domain.BookingStatus;
import roomescape.domain.ReservationTime;
import roomescape.service.dto.request.ReservationTimeSaveRequest;
import roomescape.service.dto.response.ReservationStatusResponse;
import roomescape.service.dto.response.BookingStatusResponse;
import roomescape.service.dto.response.ReservationTimeResponse;
import roomescape.service.reservationtime.ReservationTimeCreateService;
import roomescape.service.reservationtime.ReservationTimeDeleteService;
Expand Down Expand Up @@ -51,15 +51,15 @@ public ResponseEntity<List<ReservationTimeResponse>> getReservationTimes() {
}

@GetMapping("/times/available")
public ResponseEntity<List<ReservationStatusResponse>> getReservationTimesIsBooked(
public ResponseEntity<List<BookingStatusResponse>> getReservationTimesIsBooked(
@RequestParam LocalDate date,
@RequestParam @Positive(message = "1 이상의 값만 입력해주세요.") long themeId) {
ReservationStatus reservationStatus = reservationTimeFindService.findIsBooked(date, themeId);
BookingStatus bookingStatus = reservationTimeFindService.findIsBooked(date, themeId);
return ResponseEntity.ok(
reservationStatus.getReservationStatus()
bookingStatus.getReservationStatus()
.entrySet()
.stream()
.map(status -> new ReservationStatusResponse(
.map(status -> new BookingStatusResponse(
status.getKey(),
status.getValue()
)
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/roomescape/controller/api/WaitingApiController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package roomescape.controller.api;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import roomescape.auth.AuthenticatedMember;
import roomescape.domain.Member;
import roomescape.domain.Reservation;
import roomescape.domain.ReservationStatus;
import roomescape.service.dto.request.ReservationSaveRequest;
import roomescape.service.dto.response.ReservationResponse;
import roomescape.service.reservation.ReservationCreateService;
import roomescape.service.reservation.ReservationDeleteService;

import java.net.URI;

@RestController
public class WaitingApiController {

private final ReservationCreateService reservationCreateService;
private final ReservationDeleteService reservationDeleteService;


public WaitingApiController(ReservationCreateService reservationCreateService,
ReservationDeleteService reservationDeleteService) {
this.reservationCreateService = reservationCreateService;
this.reservationDeleteService = reservationDeleteService;
}

@PostMapping("/waiting")
public ResponseEntity<ReservationResponse> addWaiting(@RequestBody @Valid ReservationSaveRequest request,
@AuthenticatedMember Member member) {
Reservation newReservation = reservationCreateService.createReservation(request, member, ReservationStatus.WAITING);

Choose a reason for hiding this comment

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

service 를 create, delete, find 로 나누시게 된 이유가 어떤걸까요??

Copy link
Member Author

Choose a reason for hiding this comment

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

service 하나에서 모든 행동을 수행한다면 service가 너무 뚱뚱해지고 유지보수도 어려울 것이라 생각했습니다!
CRD로 나눔으로써 관리할 포인트를 세분화할 수 있을 것 같습니다.
현재 프로젝트는 크지 않아 비교적 필요성이 적을 수 있지만, 적용해본다는 측면해서 나누어 보았습니다!

Choose a reason for hiding this comment

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

범용적인 방법은 아니기 때문에 다른 사람들과 함께 작업을 한다면
굉장히 불편할것 같습니다🤔
read db와 write db가 다르게 관리되는경우 CQRS로 관리하는 경우는 있지만 어디까지나 read db, write db가 분리되는 상황에서나 적용할법한 내묭일것 같습니다

Copy link
Member Author

@tkdgur0906 tkdgur0906 May 26, 2024

Choose a reason for hiding this comment

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

일반적으로 사용되는 패턴이 아니기 때문에 팀원들에게 이해와 설명이 필요할 것 같습니다.
말씀하신 CQRS를 알아보았는데, 이 패턴이 결국 프로젝트가 커졌을 때 command와 query로 서비스를 분리하고 db를 추가하면서 부하도 줄일 수 있는 방법이겠네요!

CRD로 나누지 않고 하나의 클래스로 통일했습니다!

return ResponseEntity.created(URI.create("/waiting/" + newReservation.getId()))
.body(new ReservationResponse(newReservation));
}

@DeleteMapping("/waiting/{id}")
public ResponseEntity<Void> deleteWaiting(@PathVariable
@Positive(message = "1 이상의 값만 입력해주세요.") long id) {

Choose a reason for hiding this comment

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

아무나 id를 알면 지울 수 있을것 같아요🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

예약 대기는 예약자, 관리자만 삭제할 수 있도록 검증 로직을 추가하였습니다!
추가로 테마, 예약 시간의 생성 삭제를 관리자만 할 수 있도록 권한 검증을 하도록 수정하였고,
예약 삭제는 관리자만 가능하도록 하였습니다!

reservationDeleteService.deleteReservation(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package roomescape.controller.api.admin;

import jakarta.validation.constraints.Positive;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import roomescape.auth.AuthenticatedMember;
import roomescape.domain.Member;
import roomescape.domain.Reservation;
import roomescape.service.dto.response.WaitingResponse;
import roomescape.service.reservation.ReservationDeleteService;
import roomescape.service.reservation.ReservationFindService;

import java.util.List;

@RestController
public class AdminWaitingApiController {

Choose a reason for hiding this comment

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

여기도 AdminReservationApiController로 처리할 수 있지 않을까요?


private final ReservationFindService reservationFindService;
private final ReservationDeleteService reservationDeleteService;

public AdminWaitingApiController(ReservationFindService reservationFindService,
ReservationDeleteService reservationDeleteService) {
this.reservationFindService = reservationFindService;
this.reservationDeleteService = reservationDeleteService;
}

@GetMapping("/admin/waitings")

Choose a reason for hiding this comment

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

이 클래스는 watings 인데 다른 클래스는 waiting이네요!
통일하는게 좋을것 같습니다

Copy link
Member Author

@tkdgur0906 tkdgur0906 May 23, 2024

Choose a reason for hiding this comment

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

기존의 뼈대 코드에서 view를 반환하는 컨트롤러의 엔드포인트가 단수여서, api 컨트롤러는 복수로 만들어 놓았습니다.
저도 통일하는 것이 좋다는 것에 동의하였고, 리소스이기 때문에 복수로 표현되어야한다고 생각하여 모두 복수로 통일하였습니다!

하지만 view 랜더링하는 컨트롤러의 엔드포인트와 api의 엔드포인트가 동일하게 되어, 둘을 명확히 구분하여 호출하고 중복을 피하기 위해 맨앞에 /api를 붙여 구분하게 하였습니다!

public ResponseEntity<List<WaitingResponse>> getWaiting(@AuthenticatedMember Member member) {
List<Reservation> waitings = reservationFindService.findWaitings();

Choose a reason for hiding this comment

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

findByStatus(status) 형태로
처리하면 더 유연할것 같네요!

return ResponseEntity.ok(
waitings.stream()
.map(WaitingResponse::new)
.toList()
);
}

@DeleteMapping("/admin/waitings/{id}")
public ResponseEntity<Void> deleteReservation(
@AuthenticatedMember Member member,
@PathVariable
@Positive(message = "1 이상의 값만 입력해주세요.") long id) {

Choose a reason for hiding this comment

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

Suggested change
@PathVariable
@Positive(message = "1 이상의 값만 입력해주세요.") long id) {
@PathVariable long id) {

Positive 는 동작안할것 같네요

Copy link
Member Author

@tkdgur0906 tkdgur0906 May 23, 2024

Choose a reason for hiding this comment

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

클래스 레벨에 @Validated를 안붙여서 동작 안한다고 말씀하신 건가요?
아니면 어플리케이션 플로우에서 일어나지 않는다는 것을 의미하신건가요?

Choose a reason for hiding this comment

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

애플리케이션 플로우에서 검증이 동작할 일이 없을것 같습니다
명시적으로 적는것도 id라 표현할 필요가 없을것 같고요
불필요한 어노테이션일것 같다는 뜻으로 남겼어요🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

애플리케이션 플로우에서 동작할 일이 없다는 것은 이해를 했습니다!

다만 궁금한 것은 postman을 통해 해당 delete 메서드의 path의 id에 명시적으로 0을 입력한 경우 @Positive가 동작하는 것을 확인했습니다. 물론 어노테이션이 없더라도 서비스의 검증 로직에서 잡히긴 합니다.
이런 상황을 검증하는 것에 대한 불필요성 인 것 인가요?

그리고 ReservationTimeApiControllergetReservationTimesIsBooked 메서드에서 @Positive로 requestParam으로 들어오는 id를 검증하고 있습니다. delete 메서드의 id 검증처럼 get 메서드에서 사용되는 id의 검증도 마찬가지로 불필요하다고 생각하시나요?

Choose a reason for hiding this comment

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

제가 해봤을때는 500에러가 나는데 "1이상의 값만 입력해주세요" 라는 에러가 뜨는건가요?
이 에러는 실제 사용자가 아닌 클라이언트 개발자가 잘못 입력했기때문에 (너무 말도 안되는 실수기도 하죠)
구체적인 에러 메세지를 담아서 처리할 필요는 없을것 같고요!

reservationDeleteService.deleteReservation(id);
return ResponseEntity.noContent().build();
}
}
5 changes: 5 additions & 0 deletions src/main/java/roomescape/controller/web/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ public String reservationAdminPage() {
public String themeAdminPage() {
return "admin/theme";
}

@GetMapping("/admin/waiting")
public String waitingAdminPage() {
return "admin/waiting";
}
}
16 changes: 16 additions & 0 deletions src/main/java/roomescape/domain/BaseTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package roomescape.domain;

import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTime {

@CreatedDate
private LocalDateTime createdAt;

Choose a reason for hiding this comment

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

LocalDateTime 으로 시간을 관리하면
여러 국가에서 사용하면 어떤 문제가 있을까요?

Copy link
Member Author

Choose a reason for hiding this comment

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

LocalDateTime은 타임존을 반영하지 않기 때문에 특정 지역의 시간대를 나타낼 수 없습니다.
그래서 ZoneDateTime이라는 타임존에 따라 다른 시간을 나타내는 클래스가 있다고 합니다.

그런데 LocalDateTime이든 ZoneDateTime이든 결국 시간을 관리하기 위해서는 db에 저장을 해야할 것 같습니다.
그렇다고 여러 국가의 타임존마다 시간을 모두 저장하는 것은 좋은 방법이 아닌 것 같습니다.

그래서 현재 생각나는 방식은 db에 UTC를 기준으로 저장하고, 클라이언트의 요청에 저장된 타임존 정보를 db에 저장되어있는 시간에 반영하여 반환해주는 방식을 생각해보았습니다.

실제로는 어떤 방식으로 관리를 하는지 궁금합니다!

Choose a reason for hiding this comment

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

Instant 타입에 대해서 학습해보면 좋을것 같습니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

Instant 타입은 UTC 기반의 절대 시간을 나타내고, 타임존 정보가 없습니다.
따라서 Instant 타입으로 시간을 저장하고, 요청하는 사용자의 타임존에 맞게 변경하여 보여주면 여러 국가에서 사용할 수 있을 것 같습니다!

}
49 changes: 49 additions & 0 deletions src/main/java/roomescape/domain/BookingStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package roomescape.domain;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class BookingStatus {

private final Map<ReservationTime, Boolean> reservationStatus;

private BookingStatus(Map<ReservationTime, Boolean> reservationStatus) {
this.reservationStatus = reservationStatus;
}

public static BookingStatus of(List<ReservationTime> reservedTimes, List<ReservationTime> reservationTimes) {
Map<ReservationTime, Boolean> reservationStatus = new HashMap<>();
for (ReservationTime reservationTime : reservationTimes) {
reservationStatus.put(reservationTime, isReserved(reservedTimes, reservationTime));
}
return new BookingStatus(reservationStatus);
}

private static boolean isReserved(List<ReservationTime> reservedTimes, ReservationTime reservationTime) {
return reservedTimes.stream()
.anyMatch(reservedTime -> reservedTime.equals(reservationTime));

Choose a reason for hiding this comment

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

contains로 충분히 처리 가능하지 않을까요??

Copy link
Member Author

Choose a reason for hiding this comment

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

훨씬 간단하게 표현할 수 있군요! 반영하였습니다!

}

public Map<ReservationTime, Boolean> getReservationStatus() {
return reservationStatus;
}

@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
BookingStatus that = (BookingStatus) object;
return Objects.equals(reservationStatus, that.reservationStatus);
}

@Override
public int hashCode() {
return Objects.hash(reservationStatus);
}
}
2 changes: 1 addition & 1 deletion src/main/java/roomescape/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import java.util.Objects;

@Entity
public class Member {
public class Member extends BaseTime {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
36 changes: 30 additions & 6 deletions src/main/java/roomescape/domain/Reservation.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package roomescape.domain;

import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
Expand All @@ -11,7 +13,7 @@
import java.util.Objects;

@Entity
public class Reservation {
public class Reservation extends BaseTime {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -28,23 +30,30 @@ public class Reservation {
@ManyToOne(fetch = FetchType.LAZY)
private Theme theme;

public Reservation(Long id, Member member, LocalDate date, ReservationTime reservationTime, Theme theme) {
validate(member, date, reservationTime, theme);
@Enumerated(EnumType.STRING)
private ReservationStatus reservationStatus;

public Reservation(Long id, Member member, LocalDate date, ReservationTime reservationTime,
Theme theme, ReservationStatus reservationStatus) {

Choose a reason for hiding this comment

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

Suggested change
public Reservation(Long id, Member member, LocalDate date, ReservationTime reservationTime,
Theme theme, ReservationStatus reservationStatus) {
public Reservation(
Long id,
Member member,
LocalDate date,
ReservationTime reservationTime,
Theme theme,
ReservationStatus reservationStatus
) {

지금 방법은 어떤 파라미터가 있는지 파악하기 힘든것 같아요ㅠ
파라미터가 여러개라서 120자를 넘어간다면 각 파라미터마다 개행을 하는걸 추천드립니다

Copy link
Member Author

Choose a reason for hiding this comment

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

이 부분도 반영했습니다!

validate(member, date, reservationTime, theme, reservationStatus);
this.id = id;
this.member = member;
this.date = date;
this.reservationTime = reservationTime;
this.theme = theme;
this.reservationStatus = reservationStatus;
}

public Reservation(Member member, LocalDate date, ReservationTime reservationTime, Theme theme) {
this(null, member, date, reservationTime, theme);
public Reservation(Member member, LocalDate date, ReservationTime reservationTime,
Theme theme, ReservationStatus reservationStatus) {
this(null, member, date, reservationTime, theme, reservationStatus);
}

protected Reservation() {
}

private void validate(Member member, LocalDate date, ReservationTime reservationTime, Theme theme) {
private void validate(Member member, LocalDate date, ReservationTime reservationTime,
Theme theme, ReservationStatus reservationStatus) {
if (member == null) {
throw new IllegalArgumentException("예약하려는 사용자를 선택해주세요.");
}
Expand All @@ -57,6 +66,17 @@ private void validate(Member member, LocalDate date, ReservationTime reservation
if (theme == null) {
throw new IllegalArgumentException("예약하려는 테마를 선택해주세요.");
}
if (reservationStatus == null) {
throw new IllegalArgumentException("예약상태가 지정되지 않았습니다.");
}
}

public boolean isReserved() {
return reservationStatus.isReserved();
}

public void changeWaitingToReserved() {
this.reservationStatus = ReservationStatus.RESERVED;

Choose a reason for hiding this comment

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

state 를 받아서 변경하도록 하는게 좀 더 유연할것 같네요!

}

public Long getId() {
Expand All @@ -79,6 +99,10 @@ public Theme getTheme() {
return theme;
}

public ReservationStatus getReservationStatus() {
return reservationStatus;
}

@Override
public boolean equals(Object object) {
if (this == object) {
Expand Down
Loading