-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathApplicationSubmissionService.java
More file actions
135 lines (118 loc) · 6.75 KB
/
ApplicationSubmissionService.java
File metadata and controls
135 lines (118 loc) · 6.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package com.example.solidconnection.application.service;
import static com.example.solidconnection.common.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED;
import static com.example.solidconnection.common.exception.ErrorCode.CURRENT_TERM_NOT_FOUND;
import static com.example.solidconnection.common.exception.ErrorCode.GPA_SCORE_NOT_FOUND;
import static com.example.solidconnection.common.exception.ErrorCode.INVALID_GPA_SCORE_STATUS;
import static com.example.solidconnection.common.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE;
import static com.example.solidconnection.common.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE_STATUS;
import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND;
import com.example.solidconnection.application.domain.Application;
import com.example.solidconnection.application.dto.ApplicationSubmissionResponse;
import com.example.solidconnection.application.dto.ApplyRequest;
import com.example.solidconnection.application.dto.UnivApplyInfoChoiceRequest;
import com.example.solidconnection.application.repository.ApplicationRepository;
import com.example.solidconnection.common.VerifyStatus;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.term.domain.Term;
import com.example.solidconnection.term.repository.TermRepository;
import com.example.solidconnection.university.domain.UnivApplyInfo;
import com.example.solidconnection.university.repository.UnivApplyInfoRepository;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
@Service
public class ApplicationSubmissionService {
public static final int APPLICATION_UPDATE_COUNT_LIMIT = 3;
private final ApplicationRepository applicationRepository;
private final GpaScoreRepository gpaScoreRepository;
private final LanguageTestScoreRepository languageTestScoreRepository;
private final SiteUserRepository siteUserRepository;
private final TermRepository termRepository;
private final UnivApplyInfoRepository univApplyInfoRepository;
// 학점 및 어학성적이 모두 유효한 경우에만 지원서 등록이 가능하다.
// 기존에 있던 status field 우선 APRROVED로 입력시킨다.
@Transactional
public ApplicationSubmissionResponse apply(long siteUserId, ApplyRequest applyRequest) {
SiteUser siteUser = siteUserRepository.findById(siteUserId)
.orElseThrow(() -> new CustomException(USER_NOT_FOUND));
UnivApplyInfoChoiceRequest univApplyInfoChoiceRequest = applyRequest.univApplyInfoChoiceRequest();
GpaScore gpaScore = getValidGpaScore(siteUser, applyRequest.gpaScoreId());
LanguageTestScore languageTestScore = getValidLanguageTestScore(siteUser, applyRequest.languageTestScoreId());
Term term = termRepository.findByIsCurrentTrue()
.orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND));
Long firstChoiceUnivApplyInfoId = univApplyInfoChoiceRequest.firstChoiceUnivApplyInfoId();
Long secondChoiceUnivApplyInfoId = univApplyInfoChoiceRequest.secondChoiceUnivApplyInfoId();
Long thirdChoiceUnivApplyInfoId = univApplyInfoChoiceRequest.thirdChoiceUnivApplyInfoId();
Optional<Application> existingApplication =
applicationRepository.findTopBySiteUserIdAndTermIdAndIsDeleteFalseOrderByIdDesc(siteUser.getId(), term.getId());
int updateCount = existingApplication
.map(application -> {
validateUpdateLimitNotExceed(application);
application.setIsDeleteTrue();
return application.getUpdateCount() + 1;
})
.orElse(1);
Application newApplication = new Application(
siteUser,
gpaScore.getGpa(),
languageTestScore.getLanguageTest(),
term.getId(),
updateCount,
firstChoiceUnivApplyInfoId,
secondChoiceUnivApplyInfoId,
thirdChoiceUnivApplyInfoId,
getRandomNickname()
);
newApplication.setVerifyStatus(VerifyStatus.APPROVED);
applicationRepository.save(newApplication);
List<Long> univApplyInfoIds = Stream.of(
firstChoiceUnivApplyInfoId,
secondChoiceUnivApplyInfoId,
thirdChoiceUnivApplyInfoId
)
.filter(Objects::nonNull)
.toList();
List<UnivApplyInfo> uniApplyInfos = univApplyInfoRepository.findAllByIds(univApplyInfoIds);
return ApplicationSubmissionResponse.of(APPLICATION_UPDATE_COUNT_LIMIT, newApplication, uniApplyInfos);
}
private GpaScore getValidGpaScore(SiteUser siteUser, Long gpaScoreId) {
GpaScore gpaScore = gpaScoreRepository.findGpaScoreBySiteUserIdAndId(siteUser.getId(), gpaScoreId)
.orElseThrow(() -> new CustomException(GPA_SCORE_NOT_FOUND));
if (gpaScore.getVerifyStatus() != VerifyStatus.APPROVED) {
throw new CustomException(INVALID_GPA_SCORE_STATUS);
}
return gpaScore;
}
private LanguageTestScore getValidLanguageTestScore(SiteUser siteUser, Long languageTestScoreId) {
LanguageTestScore languageTestScore = languageTestScoreRepository
.findLanguageTestScoreBySiteUserIdAndId(siteUser.getId(), languageTestScoreId)
.orElseThrow(() -> new CustomException(INVALID_LANGUAGE_TEST_SCORE));
if (languageTestScore.getVerifyStatus() != VerifyStatus.APPROVED) {
throw new CustomException(INVALID_LANGUAGE_TEST_SCORE_STATUS);
}
return languageTestScore;
}
private String getRandomNickname() {
String randomNickname = NicknameCreator.createRandomNickname();
while (applicationRepository.existsByNicknameForApply(randomNickname)) {
randomNickname = NicknameCreator.createRandomNickname();
}
return randomNickname;
}
private void validateUpdateLimitNotExceed(Application application) {
if (application.getUpdateCount() >= APPLICATION_UPDATE_COUNT_LIMIT) {
throw new CustomException(APPLY_UPDATE_LIMIT_EXCEED);
}
}
}