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
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e56a150
[#257] feat(Performance): 엔티티 수정
hyerinhwang-sailin Nov 25, 2024
d5d9445
[#257] feat(PerformanceErrorCode): 유의사항, 소개 글자수 1500자로 수정
hyerinhwang-sailin Nov 25, 2024
42f9920
[#257] chore(ScheduleRequest): 코드 포맷터 적용
hyerinhwang-sailin Nov 25, 2024
c3bb5a5
[#257] feat(PerformanceDetailResponse): 공연 상세 정보 dto 수정
hyerinhwang-sailin Nov 25, 2024
5826f62
[#257] feat(PerformanceService): 공연 상세 정보 service 수정
hyerinhwang-sailin Nov 25, 2024
630bcee
[#257] feat: 공연 수정 dto 수정
hyerinhwang-sailin Nov 25, 2024
c12fc4a
[#257] feat(PerformanceModifyService): 공연 수정 service 수정
hyerinhwang-sailin Nov 25, 2024
ba35326
[#257] feat: 공연 생성 dto 수정
hyerinhwang-sailin Nov 25, 2024
0a20268
[#257] feat(PerformanceManagementService): 공연 생성 service 수정
hyerinhwang-sailin Nov 25, 2024
fd90186
[#257] chore: longtitude 오타 수정
hyerinhwang-sailin Nov 25, 2024
cae8909
[#259] feat(Booking): Booking에 필드 추가 및 setRefundInfo 메소드 추가
hyerinhwang-sailin Nov 25, 2024
3bf6f39
[#259] feat(BookingStatus): BookingStatus 값 추가
hyerinhwang-sailin Nov 25, 2024
fffafcb
[#259] feat(BookingSuccessCode): BookingSuccessCode 값 추가
hyerinhwang-sailin Nov 25, 2024
3a8d5be
[#259] feat: 예매취소요청 dto 추가
hyerinhwang-sailin Nov 25, 2024
7569aac
[#259] feat: 예매환불요청 dto 추가
hyerinhwang-sailin Nov 25, 2024
b7ea086
[#259] feat(BookingCancelService): 예매 취소, 환불요청 service 추가
hyerinhwang-sailin Nov 25, 2024
b108620
[#259] feat: 예매 취소, 환불요청 controller 추가
hyerinhwang-sailin Nov 25, 2024
45f722a
[#259] feat(SecurityConfig): 예매 취소, 환불요청 url AUTH_WHITELIST에 추가
hyerinhwang-sailin Nov 25, 2024
689e8d5
[#259] feat: booking 엔티티 변경사항 반영
hyerinhwang-sailin Nov 25, 2024
6b18618
Merge branch 'develop' into feat/#259
hyerinhwang-sailin Nov 28, 2024
8578b82
[#261] chore(modifyPerformance): conflict 해결
hyerinhwang-sailin Nov 28, 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
42 changes: 42 additions & 0 deletions src/main/java/com/beat/domain/booking/api/BookingApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;

import com.beat.domain.booking.application.dto.BookingCancelRequest;
import com.beat.domain.booking.application.dto.BookingCancelResponse;
import com.beat.domain.booking.application.dto.BookingRefundRequest;
import com.beat.domain.booking.application.dto.BookingRefundResponse;
import com.beat.domain.booking.application.dto.GuestBookingRequest;
import com.beat.domain.booking.application.dto.GuestBookingResponse;
import com.beat.domain.booking.application.dto.GuestBookingRetrieveRequest;
Expand Down Expand Up @@ -142,4 +146,42 @@ ResponseEntity<SuccessResponse<GuestBookingResponse>> createGuestBookings(
ResponseEntity<SuccessResponse<List<GuestBookingRetrieveResponse>>> getGuestBookings(
@RequestBody GuestBookingRetrieveRequest guestBookingRetrieveRequest
);

@Operation(summary = "유료공연 예매 환불 요청 API", description = "유료공연 예매자가 환불 요청하는 PATCH API입니다.")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "유료공연 예매 환불 요청이 성공적으로 완료되었습니다.",
content = @Content(schema = @Schema(implementation = SuccessResponse.class))
),
@ApiResponse(
responseCode = "404",
description = "입력하신 정보와 일치하는 예매 내역이 없습니다. 확인 후 다시 조회해주세요.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
)
}
)
ResponseEntity<SuccessResponse<BookingRefundResponse>> refundBookings(
@RequestBody BookingRefundRequest bookingRefundRequest
);

@Operation(summary = "무료공연/미입금 예매 취소 요청 API", description = "무료공연/미입금 예매자가 취소 요청하는 PATCH API입니다.")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "무료공연/미입금 예매 취소 요청이 성공적으로 완료되었습니다.",
content = @Content(schema = @Schema(implementation = SuccessResponse.class))
),
@ApiResponse(
responseCode = "404",
description = "입력하신 정보와 일치하는 예매 내역이 없습니다. 확인 후 다시 조회해주세요.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
)
}
)
ResponseEntity<SuccessResponse<BookingCancelResponse>> cancelBookings(
@RequestBody BookingCancelRequest bookingCancelRequest
);
}
27 changes: 27 additions & 0 deletions src/main/java/com/beat/domain/booking/api/BookingController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.beat.domain.booking.application.BookingCancelService;
import com.beat.domain.booking.application.GuestBookingRetrieveService;
import com.beat.domain.booking.application.GuestBookingService;
import com.beat.domain.booking.application.MemberBookingRetrieveService;
import com.beat.domain.booking.application.MemberBookingService;
import com.beat.domain.booking.application.dto.BookingCancelRequest;
import com.beat.domain.booking.application.dto.BookingCancelResponse;
import com.beat.domain.booking.application.dto.BookingRefundRequest;
import com.beat.domain.booking.application.dto.BookingRefundResponse;
import com.beat.domain.booking.application.dto.GuestBookingRequest;
import com.beat.domain.booking.application.dto.GuestBookingResponse;
import com.beat.domain.booking.application.dto.GuestBookingRetrieveRequest;
Expand All @@ -35,6 +41,7 @@ public class BookingController implements BookingApi {
private final MemberBookingRetrieveService memberBookingRetrieveService;
private final GuestBookingService guestBookingService;
private final GuestBookingRetrieveService guestBookingRetrieveService;
private final BookingCancelService bookingCancelService;

@Override
@PostMapping("/member")
Expand Down Expand Up @@ -73,4 +80,24 @@ public ResponseEntity<SuccessResponse<List<GuestBookingRetrieveResponse>>> getGu
return ResponseEntity.status(HttpStatus.OK)
.body(SuccessResponse.of(BookingSuccessCode.GUEST_BOOKING_RETRIEVE_SUCCESS, response));
}

@Override
@PatchMapping("/refund")
public ResponseEntity<SuccessResponse<BookingRefundResponse>> refundBookings(
@RequestBody BookingRefundRequest bookingRefundRequest
) {
BookingRefundResponse response = bookingCancelService.refundBooking(bookingRefundRequest);
return ResponseEntity.status(HttpStatus.OK)
.body(SuccessResponse.of(BookingSuccessCode.BOOKING_REFUND_SUCCESS, response));
}

@Override
@PatchMapping("/cancel")
public ResponseEntity<SuccessResponse<BookingCancelResponse>> cancelBookings(
@RequestBody BookingCancelRequest bookingCancelRequest
) {
BookingCancelResponse response = bookingCancelService.cancelBooking(bookingCancelRequest);
return ResponseEntity.status(HttpStatus.OK)
.body(SuccessResponse.of(BookingSuccessCode.BOOKING_CANCEL_SUCCESS, response));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.beat.domain.booking.application;

import org.springframework.stereotype.Service;

import com.beat.domain.booking.application.dto.BookingCancelRequest;
import com.beat.domain.booking.application.dto.BookingCancelResponse;
import com.beat.domain.booking.application.dto.BookingRefundRequest;
import com.beat.domain.booking.application.dto.BookingRefundResponse;
import com.beat.domain.booking.dao.BookingRepository;
import com.beat.domain.booking.domain.Booking;
import com.beat.domain.booking.domain.BookingStatus;
import com.beat.domain.booking.exception.BookingErrorCode;
import com.beat.domain.schedule.dao.ScheduleRepository;
import com.beat.domain.schedule.domain.Schedule;
import com.beat.global.common.exception.NotFoundException;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class BookingCancelService {

private final BookingRepository bookingRepository;
private final ScheduleRepository scheduleRepository;

public BookingRefundResponse refundBooking(BookingRefundRequest request) {
Booking booking = bookingRepository.findById(request.bookingId())
.orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_BOOKING_FOUND));

booking.setRefundInfo(request.bankName(), request.accountNumber(), request.accountHolder());
booking.setBookingStatus(BookingStatus.REFUND_REQUESTED);
Comment on lines +30 to +31
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에 반영하도록 하겠습니다~

bookingRepository.save(booking);

return BookingRefundResponse.of(
booking.getId(),
booking.getBookingStatus(),
booking.getBankName(),
booking.getAccountNumber(),
booking.getAccountHolder()
);
Comment on lines +34 to +40
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.

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

}

public BookingCancelResponse cancelBooking(BookingCancelRequest request) {
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 호출이 아닌 엔티티에 직접 작성한 메소드를 호출해서 사용했습니다!

bookingRepository.save(booking);

Schedule schedule = booking.getSchedule();
schedule.decreaseSoldTicketCount(booking.getPurchaseTicketCount());
scheduleRepository.save(schedule);

return BookingCancelResponse.of(
booking.getId(),
booking.getBookingStatus()
Comment on lines +54 to +56
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 객체를 넘기는 방식으로 바꾼다면 통일성을 위해 해당 부분도 바꾸는게 좋아보이는데 혜린님 생각은 어떠신가요?

);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.beat.domain.booking.application;

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

import com.beat.domain.booking.application.dto.GuestBookingRequest;
import com.beat.domain.booking.application.dto.GuestBookingResponse;
import com.beat.domain.booking.dao.BookingRepository;
Expand All @@ -15,9 +18,6 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

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

@Slf4j
@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -61,6 +61,9 @@ public GuestBookingResponse createGuestBooking(GuestBookingRequest guestBookingR
guestBookingRequest.bookingStatus(),
guestBookingRequest.birthDate(),
guestBookingRequest.password(),
null,
null,
null,
Comment on lines +64 to +66
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로 들어가게 됩니다.

schedule,
users
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.beat.domain.booking.application;

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

import com.beat.domain.booking.application.dto.MemberBookingRequest;
import com.beat.domain.booking.application.dto.MemberBookingResponse;
import com.beat.domain.booking.dao.BookingRepository;
Expand All @@ -19,9 +22,6 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

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

@Slf4j
@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -57,6 +57,9 @@ public MemberBookingResponse createMemberBooking(Long memberId, MemberBookingReq
memberBookingRequest.bookingStatus(),
null,
null,
null,
null,
null,
schedule,
user
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.beat.domain.booking.application.dto;

public record BookingCancelRequest(
long bookingId
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.beat.domain.booking.application.dto;

import com.beat.domain.booking.domain.BookingStatus;

public record BookingCancelResponse(
long bookingId,
BookingStatus bookingStatus
) {
public static BookingCancelResponse of(
long bookingId,
BookingStatus bookingStatus) {
return new BookingCancelResponse(
bookingId,
bookingStatus);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.beat.domain.booking.application.dto;

import com.beat.domain.performance.domain.BankName;

public record BookingRefundRequest(
long bookingId,
BankName bankName,
String accountNumber,
String accountHolder
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.beat.domain.booking.application.dto;

import com.beat.domain.booking.domain.BookingStatus;
import com.beat.domain.performance.domain.BankName;

public record BookingRefundResponse(
long bookingId,
BookingStatus bookingStatus,
BankName bankName,
String accountNumber,
String accountHolder
) {
public static BookingRefundResponse of(
long bookingId,
BookingStatus bookingStatus,
BankName bankName,
String accountNumber,
String accountHolder) {
return new BookingRefundResponse(
bookingId,
bookingStatus,
bankName,
accountNumber,
accountHolder);
}
}
41 changes: 33 additions & 8 deletions src/main/java/com/beat/domain/booking/domain/Booking.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package com.beat.domain.booking.domain;

import java.time.LocalDateTime;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import com.beat.domain.performance.domain.BankName;
import com.beat.domain.schedule.domain.Schedule;
import com.beat.domain.user.domain.Users;

Expand All @@ -18,11 +24,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import java.time.LocalDateTime;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand Down Expand Up @@ -57,6 +58,16 @@ public class Booking {
@Column(nullable = true)
private String password;

@Enumerated(EnumType.STRING)
@Column(nullable = true)
private BankName bankName;

@Column(nullable = true)
private String accountNumber;

@Column(nullable = true)
private String accountHolder;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "schedule_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
Expand All @@ -69,35 +80,49 @@ public class Booking {

@Builder
public Booking(int purchaseTicketCount, String bookerName, String bookerPhoneNumber, BookingStatus bookingStatus,
String birthDate, String password, Schedule schedule, Users users) {
String birthDate, String password, BankName bankName, String accountNumber, String accountHolder,
Schedule schedule, Users users) {
this.purchaseTicketCount = purchaseTicketCount;
this.bookerName = bookerName;
this.bookerPhoneNumber = bookerPhoneNumber;
this.bookingStatus = bookingStatus;
this.birthDate = birthDate;
this.password = password;
this.bankName = bankName;
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
this.schedule = schedule;
this.users = users;
}

public static Booking create(int purchaseTicketCount, String bookerName, String bookerPhoneNumber,
BookingStatus bookingStatus, String birthDate, String password, Schedule schedule, Users users) {
BookingStatus bookingStatus, String birthDate, String password,
BankName bankName, String accountNumber, String accountHolder, Schedule schedule, Users users) {
return Booking.builder()
.purchaseTicketCount(purchaseTicketCount)
.bookerName(bookerName)
.bookerPhoneNumber(bookerPhoneNumber)
.bookingStatus(bookingStatus)
.birthDate(birthDate)
.password(password)
.bankName(bankName)
.accountNumber(accountNumber)
.accountHolder(accountHolder)
.schedule(schedule)
.users(users)
.build();
}

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

public void setRefundInfo(BankName bankName, String accountNumber, String accountHolder) {
this.bankName = bankName;
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
public enum BookingStatus {
CHECKING_PAYMENT("입금확인중"),
BOOKING_CONFIRMED("예매 확정"),
BOOKING_CANCELLED("예매 취소");
BOOKING_CANCELLED("예매 취소"),
REFUND_REQUESTED("환불 요청"),
BOOKING_DELETED("예매 삭제");

private final String displayname;
}
Loading