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

[feat] #259 - Booking 엔티티 수정 및 환불/취소 요청 API 구현 #260

Merged
merged 21 commits into from
Nov 28, 2024

Conversation

hyerinhwang-sailin
Copy link
Collaborator

@hyerinhwang-sailin hyerinhwang-sailin commented Nov 25, 2024

Related issue 🛠

Work Description ✏️

  • Booking 엔티티에 필요 필드 추가
  • BookingStatus에 값 추가
  • 입금완료 예매자 환불 요청 API 구현
  • 미입금/무료공연 예매자 취소 요청 API 구현

Trouble Shooting ⚽️

Related ScreenShot 📷

  • 유료공연 입금완료 예매자 환불 요청 API 구현
    image
    정상적으로 bookingStatus가 변경된 것을 확인했습니다.
    환불요청의 경우 메이커가 환불처리를 해야 예매취소상태로 변경되기 때문에 schedule의 soldTicketCount는 변하지 않습니다.

  • 미입금/무료공연 예매자 취소 요청 API 구현
    image
    정상적으로 bookingStatus가 변경된 것을 확인했습니다.
    취소요청의 경우 즉각적으로 예매취소상태로 변경되기 때문에 취소 시 schedule의 soldTicketCount도 바뀌도록 구현했습니다.

Uncompleted Tasks 😅

To Reviewers 📢

  • 예매 취소/환불 요청 모두 회원, 비회원에게 모두 허용되는 서비스이기 때문에 AUTH_WHITELIST에 url을 추가해두었습니다.
  • 기존 booking 관련 서비스가 guest/member로 나뉘어있었으나 취소/환불 요청의 경우 회원 비회원 모두가 접근 가능한 서비스이므로 Service class를 새로 만드는 것이 적합하다고 판단해 BookingCancelService를 새로 만들었습니다.
  • class나 method 네이밍이 적합한가에 대한 확신이 부족해 더 나은 네이밍이 있다면 추천해주세요!
  • 확인해보니 이전 pr과 커밋이 같이 합쳐진 듯합니다.. 이전 pr 머지 후 이 pr 머지하면 해결될 것 같습니다..!!

Copy link
Member

@hoonyworld hoonyworld left a comment

Choose a reason for hiding this comment

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

고생하셨습니다 혜린님!!

몇가지 코멘트 남겼습니다~

Comment on lines +30 to +31
booking.setRefundInfo(request.bankName(), request.accountNumber(), request.accountHolder());
booking.setBookingStatus(BookingStatus.REFUND_REQUESTED);
Copy link
Member

Choose a reason for hiding this comment

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

해당 부분 setter를 호출하지 않고 Booking 엔티티에서 refund라는 도메인 메서드에서 해당 비즈니스 로직을 적고. booking.refund() 형식으로 외부에서 호출하는 것이 나아보입니다!

Copy link
Collaborator Author

@hyerinhwang-sailin hyerinhwang-sailin Nov 27, 2024

Choose a reason for hiding this comment

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

setter 호출이 아닌 엔티티에 직접 작성한 메소드를 호출했습니다!

Booking.java

	public void setBookingStatus(BookingStatus bookingStatus) {
		this.bookingStatus = bookingStatus;
		if (bookingStatus == BookingStatus.BOOKING_CANCELLED || bookingStatus == BookingStatus.BOOKING_DELETED) {
			this.cancellationDate = LocalDateTime.now();
		}
	}

Copy link
Member

Choose a reason for hiding this comment

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

비즈니스 로직을 담고 있더라도 네이밍을 setter로 짓는것은 수정자로 오해를 줄 수 있을 것 같습니다.

setRefundInfosetBookingStatus 모두에 해당하는 말입니다!

Copy link
Member

Choose a reason for hiding this comment

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

booking.setRefundInfo(request.bankName(), request.accountNumber(), request.accountHolder());
booking.setBookingStatus(BookingStatus.REFUND_REQUESTED);

해당 메서드들을 refund()라는 도메인 비즈니스 메서드에서 처리를 하도록 하는게 어떨까요?
그리고 해당 메서드에 대한 예외 처는 도메인 비즈니스 메서드에서 해주면 될 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

네이밍 바꾸는 게 더 좋겠네요! 최신 pr에 반영하도록 하겠습니다~

Comment on lines +34 to +40
return BookingRefundResponse.of(
booking.getId(),
booking.getBookingStatus(),
booking.getBankName(),
booking.getAccountNumber(),
booking.getAccountHolder()
);
Copy link
Member

Choose a reason for hiding this comment

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

이 부분은 메서드의 인자로 필요한 매개변수 대신 객체를 넘겨주고 해당 getter 들을 DTO에서 처리하는거에 대해서는 어떻게 생각하시나요?

return BookingRefundResponse.of(booking);

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

저는 개인적으로 dto는 데이터 전달에만 집중해야한다고 생각해 get을 dto에서 하는 것이 적합한 것 같지 않습니다..!! response는 클라이언트와 controller 사이의 dto이므로 response에 도메인쪽 import를 추가하지 않는 게 낫지 않을까요?

Copy link
Member

Choose a reason for hiding this comment

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

혜린님 말씀대로 "dto는 데이터 전달에만 집중해야한다!" 라는 말에 동의합니다.
"dto의 매개변수를 객체로 줄것인가 or 필요한 필드만 줄것인가"에 있어서는 혜린님이 말씀해주신 관점이 더 와닿는 같습니다 ㅎㅎ

제가 말씀드렸던 이유는 getter zone이 Service 계층에서 발생하는게 객체지향적이지 못한 코드라고 생각이 들었습니다. 도메인 객체의 내부 상태를 서비스 계층에서 과도하게 노출하는 게 아닌가? 라는 생각이 들기도 합니다.

그렇다면 getter 없이 DTO가 데이터 전달에만 집중해서 사용하는 방법에는 어떤게 있을 지 찾아봤는데, MapStruct나 커스텀 매퍼 클래스를 사용하는 방법이 있더라고요!
이 방법 더 찾아보고 추가 코멘트 남겨보도록 하겠습니다.

Copy link
Collaborator Author

@hyerinhwang-sailin hyerinhwang-sailin Nov 28, 2024

Choose a reason for hiding this comment

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

저도 최근 이 부분에 대해서 공부하는 중입니다!
https://github.com/Nexters/gaetteok-backend
엔티티와 도메인 분리 및 mapper 사용한 팀의 코드를 참고해서
SOPT-all/35-COLLABORATION-SERVER-SAFETYREPORT#8
최근 이런 방식으로 다른 프로젝트의 코드를 구성해봤었습니다~
https://github.com/AND-SOPT-SERVER/yeongju.cho/tree/seminar2-daehwan
이 코드의

  • 일기 작성
  • 일기 상세 조회
  • 전체 일기 목록 조회
    api 구현에서 controller 부터 아래로 가는 흐름, 도메인간 분리, 예외 처리 부분도 보시면 좋은 참고가 될 것 같습니다 :)

Copy link
Member

Choose a reason for hiding this comment

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

공부해서 추후 리팩토링 하면 좋을 것 같네요 😊

Booking booking = bookingRepository.findById(request.bookingId())
.orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_BOOKING_FOUND));

booking.setBookingStatus(BookingStatus.BOOKING_CANCELLED);
Copy link
Member

Choose a reason for hiding this comment

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

setter를 호출하는 대신 booking.cancelBooking() 이라는 메서드를 만들고 해당 메서드 내부에서 BookingStatus를 BOOKING_CANCELLED로 바꾸어주면 좀더 캡슐화된 코드를 작성할 수 있을 것 같아요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

상단 답변 코멘트와 마찬가지로 setter 호출이 아닌 엔티티에 직접 작성한 메소드를 호출해서 사용했습니다!

Comment on lines +54 to +56
return BookingCancelResponse.of(
booking.getId(),
booking.getBookingStatus()
Copy link
Member

Choose a reason for hiding this comment

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

이 부분은 매개변수 개수가 2개 밖에 없어서 매개변수를 넘겨도 될 것 같긴하나, 만약 위에서 booking 객체를 넘기는 방식으로 바꾼다면 통일성을 위해 해당 부분도 바꾸는게 좋아보이는데 혜린님 생각은 어떠신가요?

Comment on lines +64 to +66
null,
null,
null,
Copy link
Member

Choose a reason for hiding this comment

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

null 처리하신 이유가 궁금합니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

환불계좌 정보는 환불요청했을 시에만 예매자가 등록하게 되기 때문에 처음 booking을 생성할 때는 null로 들어가게 됩니다.

hoonyworld
hoonyworld previously approved these changes Nov 28, 2024
@hyerinhwang-sailin hyerinhwang-sailin merged commit 9aae2b3 into develop Nov 28, 2024
1 check passed
@hoonyworld hoonyworld deleted the feat/#259 branch January 13, 2025 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] Booking 엔티티 수정 및 환불/취소 요청 API 구현
2 participants