Skip to content
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package org.truve.platform.ticketing.service.booking.controller;

import java.time.LocalDate;
import java.util.List;
import java.util.UUID;

import org.springframework.web.bind.annotation.GetMapping;
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.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.truve.platform.ticketing.service.booking.dto.BookingRequest;
import org.truve.platform.ticketing.service.booking.dto.BookingResponse;
import org.truve.platform.ticketing.service.booking.service.BookingService;

import java.util.UUID;

import com.truve.platform.common.response.ApiResult;

import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -34,6 +38,32 @@ public ApiResult<BookingResponse.Create> create(
return ApiResult.ok(bookingService.create(userId, request));
}

@Operation(summary = "예매 주문 정보 조회", description = "좌석 선택 후 생성된 예매 주문 정보를 조회합니다.")
@GetMapping("/{reservation_number}/order")
public ApiResult<BookingResponse.Order> getOrder(
@PathVariable("reservation_number") String reservationNumber
) {
return ApiResult.ok(bookingService.getOrder(reservationNumber));
}

@Operation(summary = "예매 상세 정보 조회")
@GetMapping("/{reservation_number}")
public ApiResult<BookingResponse.ReservationDetail> getDetail(
@PathVariable("reservation_number") String reservationNumber
) {
return ApiResult.ok(bookingService.getDetail(reservationNumber));
}

@Operation(summary = "예매 목록 조회", description = "날짜로 필터링된 예매 목록을 조회합니다.")
@GetMapping()
public ApiResult<List<BookingResponse.Summary>> getSummaries(
@RequestHeader(USER_ID_HEADER) UUID userId,
@RequestParam(required = false) LocalDate from,
@RequestParam(required = false) LocalDate to
) {
return ApiResult.ok(bookingService.getSummaries(userId, from, to));
}

@Operation(summary = "예매 결제 준비",
description = "예매 상태를 결제 대기 중으로 변경하고, 예약자 정보를 저장한 후 결제 정보를 생성합니다.")
@PostMapping("/{reservationNumber}/payment-ready")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.truve.platform.ticketing.service.booking.domain.constant.ReservationStatus;

Expand Down Expand Up @@ -41,6 +44,9 @@ public class Reservation extends BaseEntity {
@Column(nullable = false)
private Long serviceFee;

@Column(nullable = false)
private Long refundFee;

@Column(nullable = false)
private String gradeSummary;

Expand All @@ -54,6 +60,9 @@ public class Reservation extends BaseEntity {
@Column
private LocalDateTime paidAt;

@Column
private LocalDateTime canceledAt;

@Embedded
private VirtualAccount virtualAccount;

Expand All @@ -70,12 +79,14 @@ public class Reservation extends BaseEntity {
private List<Ticket> tickets = new ArrayList<>();

@Builder
private Reservation(UUID userId, String number, String gradeSummary, ShowInfo showInfo) {
private Reservation(UUID userId, String number, String gradeSummary,
ShowInfo showInfo) {

this.userId = userId;
this.number = number;
this.totalAmount = 0L;
this.serviceFee = 0L;
this.refundFee = 0L;
this.gradeSummary = gradeSummary;
this.showInfo = showInfo;
this.status = ReservationStatus.CREATED;
Expand Down Expand Up @@ -133,4 +144,51 @@ public void depositReceive(LocalDateTime paidAt) {
this.paidAt = paidAt;
this.status = ReservationStatus.CONFIRMED;
}

public boolean isCancelable() {
return status == ReservationStatus.CONFIRMED;
}

public boolean isCanceled() {
return status == ReservationStatus.CANCELED || status == ReservationStatus.PARTIAL_CANCELED;
}

public boolean isReviewable() {
return status == ReservationStatus.COMPLETED;
}

public boolean isWaitingDeposit() {
return status == ReservationStatus.PENDING_DEPOSIT;
}

public List<Long> getTicketPrices() {
return tickets.stream().map(Ticket::getPriceSnapshot).toList();
}

public Map<String, List<Ticket>> getTicketsGroupedByGrade() {
return Collections.unmodifiableMap(
tickets.stream().collect(Collectors.groupingBy(Ticket::getGrade))
);
}

public List<Ticket> getCancelTickets() {
return tickets.stream().filter(Ticket::isCanceled).toList();
}

public List<String> getCanceledSeatDetails() {
return getCancelTickets().stream().map(Ticket::getSeatDetail).toList();
}

public Long getRefundAmount() {
Long canceledTicketPrice = getCancelTickets().stream().mapToLong(Ticket::getPriceSnapshot).sum();
return canceledTicketPrice - refundFee;
}

public LocalDateTime getDeadline() {
if (isCancelable())
return showInfo.getStartAt();
if (isWaitingDeposit())
return virtualAccount.getDueDate();
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,8 @@ public static Ticket create(
.seatDetail(seatDetail)
.build();
}

public boolean isCanceled() {
return status == TicketStatus.CANCELED;
}
}
Loading