-
Notifications
You must be signed in to change notification settings - Fork 8
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
[BE] feat: 새로운 티켓, 티켓팅 도메인 추가 및 레거시 코드 마킹 (#1007-1) #1008
Open
seokjin8678
wants to merge
3
commits into
feat/#1007
Choose a base branch
from
feat/#1007-1
base: feat/#1007
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.festago.config; | ||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.data.redis.serializer.StringRedisSerializer; | ||
|
||
@Configuration | ||
public class RedisConfig { | ||
|
||
private final String host; | ||
private final int port; | ||
|
||
public RedisConfig( | ||
@Value("${spring.data.redis.host}") String host, | ||
@Value("${spring.data.redis.port}") int port | ||
) { | ||
this.host = host; | ||
this.port = port; | ||
} | ||
|
||
@Bean | ||
public RedisConnectionFactory redisConnectionFactory() { | ||
return new LettuceConnectionFactory(host, port); | ||
} | ||
|
||
@Bean | ||
public RedisTemplate<String, String> redisTemplate() { | ||
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>(); | ||
redisTemplate.setConnectionFactory(redisConnectionFactory()); | ||
redisTemplate.setKeySerializer(new StringRedisSerializer()); | ||
redisTemplate.setValueSerializer(new StringRedisSerializer()); | ||
return redisTemplate; | ||
} | ||
} |
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 { | ||
Comment on lines
+22
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다른 유형의 티켓을 지원하기 위한 새로운 티켓 엔티티 입니다. 만약 공연이 아닌 행사(Events? Party?)에 티켓팅이 필요하면 해당 클래스를 상속한 구현체를 사용하면 됩니다. |
||
|
||
@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; | ||
Comment on lines
+39
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 필드의 사용으로 통합 테스트 또는 부하 테스트 시 수월하게 테스트가 가능합니다. |
||
|
||
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, | ||
; | ||
} |
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
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; | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
추후 ErrorCode 정리가 필요해 보이네요. 😂