-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6c29b0b
commit 9503869
Showing
18 changed files
with
1,361 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
backend/src/main/java/com/festago/ticket/domain/NewTicket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package com.festago.ticket.domain; | ||
|
||
import com.festago.common.domain.BaseTimeEntity; | ||
import com.festago.common.util.Validator; | ||
import com.festago.ticketing.domain.Booker; | ||
import com.festago.ticketing.domain.ReserveTicket; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Inheritance; | ||
import jakarta.persistence.InheritanceType; | ||
import java.time.LocalDateTime; | ||
import java.util.Objects; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
// TODO NewTicket -> Ticket 이름 변경할 것 | ||
@Entity | ||
@Inheritance(strategy = InheritanceType.JOINED) | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public abstract class NewTicket extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
protected Long id; | ||
|
||
protected Long schoolId; | ||
|
||
@Enumerated(EnumType.STRING) | ||
@Column(columnDefinition = "varchar") | ||
protected TicketExclusive ticketExclusive; | ||
|
||
protected int amount = 0; | ||
|
||
/** | ||
* 사용자가 최대 예매할 수 있는 티켓의 개수 | ||
*/ | ||
protected int maxReserveAmount = 1; | ||
|
||
protected NewTicket(Long id, Long schoolId, TicketExclusive ticketExclusive) { | ||
Validator.notNull(schoolId, "schoolId"); | ||
Validator.notNull(ticketExclusive, "ticketExclusive"); | ||
this.id = id; | ||
this.schoolId = schoolId; | ||
this.ticketExclusive = ticketExclusive; | ||
} | ||
|
||
protected void changeAmount(int amount) { | ||
Validator.notNegative(amount, "amount"); | ||
this.amount = amount; | ||
} | ||
|
||
public boolean isStudentOnly() { | ||
return ticketExclusive == TicketExclusive.STUDENT; | ||
} | ||
|
||
public boolean isSchoolStudent(Booker booker) { | ||
return Objects.equals(this.schoolId, booker.getSchoolId()); | ||
} | ||
|
||
public void changeMaxReserveAmount(int maxReserveAmount) { | ||
Validator.minValue(maxReserveAmount, 1, "maxReserveAmount"); | ||
this.maxReserveAmount = maxReserveAmount; | ||
} | ||
|
||
public abstract void validateReserve(Booker booker, LocalDateTime currentTime); | ||
|
||
/** | ||
* 티켓을 예매한다. 해당 메서드를 호출하기 전 반드시 validateReserve() 메서드를 호출해야 한다.<br/> 반환된 ReserveTicket은 영속되지 않았으므로, 반드시 영속시켜야 한다. | ||
* | ||
* @param booker 예매할 사용자 | ||
* @param sequence 예매할 티켓의 순번 | ||
* @return 영속되지 않은 상태의 ReserveTicket | ||
*/ | ||
public abstract ReserveTicket reserve(Booker booker, int sequence); | ||
|
||
public abstract LocalDateTime getTicketingEndTime(); | ||
|
||
public boolean isEmptyAmount() { | ||
return amount <= 0; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Long getSchoolId() { | ||
return schoolId; | ||
} | ||
|
||
public TicketExclusive getTicketExclusive() { | ||
return ticketExclusive; | ||
} | ||
|
||
public int getAmount() { | ||
return amount; | ||
} | ||
|
||
public int getMaxReserveAmount() { | ||
return maxReserveAmount; | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
backend/src/main/java/com/festago/ticket/domain/NewTicketType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.festago.ticket.domain; | ||
|
||
// TODO NewTicket -> Ticket 이름 변경할 것 | ||
|
||
/** | ||
* NewTicket의 구현체의 DiscriminatorValue 어노테이션의 속성의 이름과 반드시 똑같이 할 것! | ||
*/ | ||
public enum NewTicketType { | ||
STAGE, | ||
; | ||
} |
117 changes: 117 additions & 0 deletions
117
backend/src/main/java/com/festago/ticket/domain/StageTicket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package com.festago.ticket.domain; | ||
|
||
import com.festago.common.exception.BadRequestException; | ||
import com.festago.common.exception.ErrorCode; | ||
import com.festago.common.exception.UnauthorizedException; | ||
import com.festago.common.util.Validator; | ||
import com.festago.stage.domain.Stage; | ||
import com.festago.ticketing.domain.Booker; | ||
import com.festago.ticketing.domain.ReserveTicket; | ||
import jakarta.persistence.DiscriminatorValue; | ||
import jakarta.persistence.Embedded; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.ManyToOne; | ||
import java.time.LocalDateTime; | ||
import java.util.Objects; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@DiscriminatorValue("STAGE") | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class StageTicket extends NewTicket { | ||
|
||
private static final int EARLY_ENTRY_LIMIT = 12; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
private Stage stage; | ||
|
||
@Embedded | ||
private StageTicketEntryTimes ticketEntryTimes = new StageTicketEntryTimes(); | ||
|
||
public StageTicket(Long schoolId, TicketExclusive ticketType, Stage stage) { | ||
this(null, schoolId, ticketType, stage); | ||
} | ||
|
||
public StageTicket(Long id, Long schoolId, TicketExclusive ticketType, Stage stage) { | ||
super(id, schoolId, ticketType); | ||
validate(schoolId, stage); | ||
this.stage = stage; | ||
} | ||
|
||
private void validate(Long schoolId, Stage stage) { | ||
Validator.notNull(stage, "stage"); | ||
if (!stage.isSchoolStage(schoolId)) { | ||
throw new UnauthorizedException(ErrorCode.NOT_ENOUGH_PERMISSION); | ||
} | ||
} | ||
|
||
@Override | ||
public LocalDateTime getTicketingEndTime() { | ||
return stage.getStartTime(); | ||
} | ||
|
||
@Override | ||
public void validateReserve(Booker booker, LocalDateTime currentTime) { | ||
if (isStudentOnly() && !isSchoolStudent(booker)) { | ||
throw new BadRequestException(ErrorCode.RESERVE_TICKET_NOT_SCHOOL_STUDENT); | ||
} | ||
if (stage.isStart(currentTime)) { | ||
throw new BadRequestException(ErrorCode.TICKET_CANNOT_RESERVE_STAGE_START); | ||
} | ||
if (stage.isBeforeTicketOpenTime(currentTime)) { | ||
throw new BadRequestException(ErrorCode.RESERVE_TICKET_BEFORE_TICKET_OPEN_TIME); | ||
} | ||
} | ||
|
||
@Override | ||
public ReserveTicket reserve(Booker booker, int sequence) { | ||
LocalDateTime entryTime = ticketEntryTimes.calculateEntryTime(sequence); | ||
return new ReserveTicket(booker.getMemberId(), NewTicketType.STAGE, id, sequence, entryTime); | ||
} | ||
|
||
public void addTicketEntryTime(Long schoolId, LocalDateTime currentTime, LocalDateTime entryTime, int amount) { | ||
validateSchoolOwner(schoolId); | ||
validateEntryTime(currentTime, entryTime); | ||
ticketEntryTimes.add(new StageTicketEntryTime(id, entryTime, amount)); | ||
changeAmount(ticketEntryTimes.getTotalAmount()); | ||
} | ||
|
||
private void validateSchoolOwner(Long schoolId) { | ||
if (!Objects.equals(this.schoolId, schoolId)) { | ||
throw new UnauthorizedException(ErrorCode.NOT_ENOUGH_PERMISSION); | ||
} | ||
} | ||
|
||
private void validateEntryTime(LocalDateTime currentTime, LocalDateTime entryTime) { | ||
if (!stage.isBeforeTicketOpenTime(currentTime)) { | ||
throw new BadRequestException(ErrorCode.INVALID_TICKET_CREATE_TIME); | ||
} | ||
if (stage.isBeforeTicketOpenTime(entryTime)) { | ||
throw new BadRequestException(ErrorCode.EARLY_TICKET_ENTRY_THAN_OPEN); | ||
} | ||
if (stage.isStart(entryTime)) { | ||
throw new BadRequestException(ErrorCode.LATE_TICKET_ENTRY_TIME); | ||
} | ||
if (!stage.isStart(entryTime.plusHours(EARLY_ENTRY_LIMIT))) { | ||
throw new BadRequestException(ErrorCode.EARLY_TICKET_ENTRY_TIME); | ||
} | ||
} | ||
|
||
public boolean deleteTicketEntryTime(Long schoolId, LocalDateTime currentTime, LocalDateTime entryTime) { | ||
validateSchoolOwner(schoolId); | ||
if (!stage.isBeforeTicketOpenTime(currentTime)) { | ||
throw new BadRequestException(ErrorCode.STAGE_TICKET_DELETE_CONSTRAINT_TICKET_OPEN_TIME); | ||
} | ||
boolean isDeleted = ticketEntryTimes.remove(entryTime); | ||
if (isDeleted) { | ||
changeAmount(ticketEntryTimes.getTotalAmount()); | ||
} | ||
return isDeleted; | ||
} | ||
|
||
public Stage getStage() { | ||
return stage; | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
backend/src/main/java/com/festago/ticket/domain/StageTicketEntryTime.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.festago.ticket.domain; | ||
|
||
import com.festago.common.domain.BaseTimeEntity; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import java.time.LocalDateTime; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class StageTicketEntryTime extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
private Long stageTicketId; | ||
|
||
private LocalDateTime entryTime; | ||
|
||
private int amount; | ||
|
||
public StageTicketEntryTime(Long stageTicketId, LocalDateTime entryTime, int amount) { | ||
this(null, stageTicketId, entryTime, amount); | ||
} | ||
|
||
public StageTicketEntryTime(Long id, Long stageTicketId, LocalDateTime entryTime, int amount) { | ||
this.id = id; | ||
this.stageTicketId = stageTicketId; | ||
this.entryTime = entryTime; | ||
this.amount = amount; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Long getStageTicketId() { | ||
return stageTicketId; | ||
} | ||
|
||
public LocalDateTime getEntryTime() { | ||
return entryTime; | ||
} | ||
|
||
public int getAmount() { | ||
return amount; | ||
} | ||
} |
Oops, something went wrong.