Skip to content

Commit 26dd439

Browse files
committed
feat: issue ticket for a booked seat
1 parent 959411f commit 26dd439

37 files changed

Lines changed: 1495 additions & 0 deletions
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.github.booking.application.ticket;
2+
3+
import com.github.booking.application.ticket.command.RedeemTicketCommand;
4+
import org.springframework.transaction.annotation.Transactional;
5+
6+
@Transactional
7+
public interface TicketCommandHandler {
8+
9+
void redeemTicket(RedeemTicketCommand command);
10+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.github.booking.application.ticket;
2+
3+
import com.github.booking.application.ticket.command.RedeemTicketCommand;
4+
import com.github.booking.domain.ticket.TicketException;
5+
import com.github.booking.domain.ticket.TicketId;
6+
import com.github.booking.domain.ticket.TicketRepository;
7+
import org.springframework.stereotype.Service;
8+
9+
import java.util.Objects;
10+
11+
@Service
12+
public class TicketCommandHandlerImpl implements TicketCommandHandler {
13+
14+
private final TicketRepository ticketRepository;
15+
16+
public TicketCommandHandlerImpl(final TicketRepository ticketRepository) {
17+
this.ticketRepository = Objects.requireNonNull(ticketRepository);
18+
}
19+
20+
@Override
21+
public void redeemTicket(final RedeemTicketCommand command) {
22+
final var ticket = ticketRepository.findByTicketId(new TicketId(command.ticketId()))
23+
.orElseThrow(TicketException::notFound);
24+
25+
ticket.redeem();
26+
ticketRepository.save(ticket);
27+
}
28+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.github.booking.application.ticket;
2+
3+
import com.github.booking.domain.show.SeatBooked;
4+
import com.github.booking.domain.show.ShowException;
5+
import com.github.booking.domain.show.ShowRepository;
6+
import com.github.booking.domain.ticket.TicketRepository;
7+
import org.springframework.context.event.EventListener;
8+
import org.springframework.stereotype.Service;
9+
import org.springframework.transaction.annotation.Transactional;
10+
11+
import java.util.Objects;
12+
13+
@Service
14+
@Transactional
15+
public class TicketEventHandler {
16+
17+
private final TicketRepository ticketRepository;
18+
private final ShowRepository showRepository;
19+
20+
public TicketEventHandler(final TicketRepository ticketRepository, final ShowRepository showRepository) {
21+
this.ticketRepository = Objects.requireNonNull(ticketRepository);
22+
this.showRepository = Objects.requireNonNull(showRepository);
23+
}
24+
25+
@EventListener
26+
public void onSeatBooked(final SeatBooked event) {
27+
final var show = showRepository.findByShowId(event.showId())
28+
.orElseThrow(ShowException::notFound);
29+
final var ticket = show.issueTicket(ticketRepository.nextTicketId(), event.seatNumber());
30+
31+
ticketRepository.save(ticket);
32+
}
33+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.github.booking.application.ticket;
2+
3+
import com.github.booking.application.ticket.query.GetTicketQuery;
4+
import com.github.booking.application.ticket.query.ListTicketsQuery;
5+
import com.github.booking.application.ticket.query.TicketDetailView;
6+
import com.github.booking.application.ticket.query.TicketSummaryView;
7+
import org.springframework.transaction.annotation.Transactional;
8+
9+
import java.util.List;
10+
11+
@Transactional(readOnly = true)
12+
public interface TicketQueryHandler {
13+
14+
TicketDetailView getTicket(GetTicketQuery query);
15+
16+
List<TicketSummaryView> listTickets(ListTicketsQuery query);
17+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.github.booking.application.ticket.command;
2+
3+
public record RedeemTicketCommand(String ticketId) {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.github.booking.application.ticket.query;
2+
3+
public record GetTicketQuery(String ticketId) {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.github.booking.application.ticket.query;
2+
3+
public record ListTicketsQuery(long offset, int limit) {
4+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.github.booking.application.ticket.query;
2+
3+
import java.time.Instant;
4+
5+
public record SeatAssignmentView(String movieTitle,
6+
String hallName,
7+
Instant scheduledAt,
8+
String seatNumber) {
9+
10+
public static SeatAssignmentView of(final String movieTitle,
11+
final String hallName,
12+
final Instant scheduledAt,
13+
final String seatNumber) {
14+
return new SeatAssignmentView(movieTitle, hallName, scheduledAt, seatNumber);
15+
}
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.github.booking.application.ticket.query;
2+
3+
public record TicketBookingView(String bookingId, String status) {
4+
5+
public static TicketBookingView of(final String bookingId, final String status) {
6+
if (bookingId == null) {
7+
return null;
8+
}
9+
10+
return new TicketBookingView(bookingId, status);
11+
}
12+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.github.booking.application.ticket.query;
2+
3+
import java.time.Instant;
4+
5+
public record TicketDetailView(String ticketId,
6+
String status,
7+
TicketBookingView booking,
8+
SeatAssignmentView seatAssignment) {
9+
10+
public TicketDetailView(final String ticketId,
11+
final String status,
12+
final String bookingId,
13+
final String bookingStatus,
14+
final String seatAssignmentMovieTitle,
15+
final String seatAssignmentHallName,
16+
final Instant seatAssignmentScheduledAt,
17+
final String seatAssignmentSeatNumber) {
18+
this(
19+
ticketId,
20+
status,
21+
TicketBookingView.of(bookingId, bookingStatus),
22+
SeatAssignmentView.of(seatAssignmentMovieTitle, seatAssignmentHallName, seatAssignmentScheduledAt, seatAssignmentSeatNumber));
23+
}
24+
}

0 commit comments

Comments
 (0)