Skip to content
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package com.example.solidconnection.admin.university.controller;

import com.example.solidconnection.admin.university.dto.AdminUnivApplyInfoCreateRequest;
import com.example.solidconnection.admin.university.dto.AdminUnivApplyInfoResponse;
import com.example.solidconnection.admin.university.dto.AdminUnivApplyInfoUpdateRequest;
import com.example.solidconnection.admin.university.dto.UnivApplyInfoFieldResponse;
import com.example.solidconnection.admin.university.dto.UnivApplyInfoImportRequest;
import com.example.solidconnection.admin.university.dto.UnivApplyInfoImportResponse;
import com.example.solidconnection.admin.university.service.AdminUnivApplyInfoService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
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.RequestMapping;
Expand All @@ -25,10 +31,33 @@ public ResponseEntity<UnivApplyInfoFieldResponse> getFields() {
return ResponseEntity.ok(adminUnivApplyInfoService.getFields());
}

@PostMapping
@PostMapping("/import")
public ResponseEntity<UnivApplyInfoImportResponse> importUnivApplyInfos(
@Valid @RequestBody UnivApplyInfoImportRequest request
) {
return ResponseEntity.ok(adminUnivApplyInfoService.importUnivApplyInfos(request));
}

@PostMapping
public ResponseEntity<AdminUnivApplyInfoResponse> createUnivApplyInfo(
@Valid @RequestBody AdminUnivApplyInfoCreateRequest request
) {
return ResponseEntity.ok(adminUnivApplyInfoService.createUnivApplyInfo(request));
}

@PatchMapping("/{id}")
public ResponseEntity<AdminUnivApplyInfoResponse> updateUnivApplyInfo(
@PathVariable long id,
@Valid @RequestBody AdminUnivApplyInfoUpdateRequest request
) {
return ResponseEntity.ok(adminUnivApplyInfoService.updateUnivApplyInfo(id, request));
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUnivApplyInfo(
@PathVariable long id
) {
adminUnivApplyInfoService.deleteUnivApplyInfo(id);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.solidconnection.admin.university.dto;

import com.example.solidconnection.university.domain.SemesterAvailableForDispatch;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

public record AdminUnivApplyInfoCreateRequest(
@NotNull Long termId,
@NotNull Long homeUniversityId,
@NotNull Long hostUniversityId,
Integer studentCapacity,
SemesterAvailableForDispatch semesterAvailableForDispatch,
String semesterRequirement,
String detailsForLanguage,
String gpaRequirement,
String gpaRequirementCriteria,
String detailsForAccommodation,
Map<String, String> extraInfo,
@Valid List<@NotNull AdminUnivApplyInfoLanguageRequirementRequest> languageRequirements
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.solidconnection.admin.university.dto;

import com.example.solidconnection.university.domain.LanguageTestType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

public record AdminUnivApplyInfoLanguageRequirementRequest(
@NotNull LanguageTestType languageTestType,
@NotBlank String minScore
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.example.solidconnection.admin.university.dto;

import com.example.solidconnection.university.domain.SemesterAvailableForDispatch;
import com.example.solidconnection.university.domain.UnivApplyInfo;
import com.example.solidconnection.university.dto.LanguageRequirementResponse;
import java.util.List;
import java.util.Map;

public record AdminUnivApplyInfoResponse(
long id,
long termId,
Long homeUniversityId,
long hostUniversityId,
String koreanName,
Integer studentCapacity,
SemesterAvailableForDispatch semesterAvailableForDispatch,
String semesterRequirement,
String detailsForLanguage,
String gpaRequirement,
String gpaRequirementCriteria,
String detailsForAccommodation,
Map<String, String> extraInfo,
List<LanguageRequirementResponse> languageRequirements
) {

public static AdminUnivApplyInfoResponse from(UnivApplyInfo univApplyInfo) {
return new AdminUnivApplyInfoResponse(
univApplyInfo.getId(),
univApplyInfo.getTermId(),
univApplyInfo.getHomeUniversity() != null ? univApplyInfo.getHomeUniversity().getId() : null,
univApplyInfo.getUniversity().getId(),
univApplyInfo.getKoreanName(),
univApplyInfo.getStudentCapacity(),
univApplyInfo.getSemesterAvailableForDispatch(),
univApplyInfo.getSemesterRequirement(),
univApplyInfo.getDetailsForLanguage(),
univApplyInfo.getGpaRequirement(),
univApplyInfo.getGpaRequirementCriteria(),
univApplyInfo.getDetailsForAccommodation(),
univApplyInfo.getExtraInfo(),
univApplyInfo.getLanguageRequirements().stream()
.map(LanguageRequirementResponse::from)
.sorted()
.toList()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.solidconnection.admin.university.dto;

import com.example.solidconnection.university.domain.SemesterAvailableForDispatch;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

public record AdminUnivApplyInfoUpdateRequest(
Integer studentCapacity,
SemesterAvailableForDispatch semesterAvailableForDispatch,
String semesterRequirement,
String detailsForLanguage,
String gpaRequirement,
String gpaRequirementCriteria,
String detailsForAccommodation,
Map<String, String> extraInfo,
@Valid List<@NotNull AdminUnivApplyInfoLanguageRequirementRequest> languageRequirements
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,31 @@
import static com.example.solidconnection.common.exception.ErrorCode.HOME_UNIVERSITY_NOT_FOUND;
import static com.example.solidconnection.common.exception.ErrorCode.INVALID_INPUT;
import static com.example.solidconnection.common.exception.ErrorCode.TERM_NOT_FOUND;
import static com.example.solidconnection.common.exception.ErrorCode.UNIV_APPLY_INFO_HAS_REFERENCES;
import static com.example.solidconnection.common.exception.ErrorCode.UNIV_APPLY_INFO_NOT_FOUND;
import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_NOT_FOUND;

import com.example.solidconnection.admin.university.dto.AdminUnivApplyInfoCreateRequest;
import com.example.solidconnection.admin.university.dto.AdminUnivApplyInfoResponse;
import com.example.solidconnection.admin.university.dto.AdminUnivApplyInfoUpdateRequest;
import com.example.solidconnection.admin.university.dto.UnivApplyInfoFieldResponse;
import com.example.solidconnection.admin.university.dto.UnivApplyInfoImportRequest;
import com.example.solidconnection.admin.university.dto.UnivApplyInfoImportResponse;
import com.example.solidconnection.application.repository.ApplicationRepository;
import com.example.solidconnection.cache.annotation.DefaultCacheOut;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.common.util.MarkdownTableParser;
import com.example.solidconnection.term.repository.TermRepository;
import com.example.solidconnection.university.domain.HomeUniversity;
import com.example.solidconnection.university.domain.HostUniversity;
import com.example.solidconnection.university.domain.LanguageRequirement;
import com.example.solidconnection.university.domain.UnivApplyInfo;
import com.example.solidconnection.university.repository.HomeUniversityRepository;
import com.example.solidconnection.university.repository.HostUniversityRepository;
import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository;
import com.example.solidconnection.university.repository.UnivApplyInfoRepository;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
Expand All @@ -28,6 +42,10 @@ public class AdminUnivApplyInfoService {
private final HomeUniversityRepository homeUniversityRepository;
private final MarkdownTableParser markdownTableParser;
private final AdminUnivApplyInfoRowSaver rowSaver;
private final UnivApplyInfoRepository univApplyInfoRepository;
private final HostUniversityRepository hostUniversityRepository;
private final LikedUnivApplyInfoRepository likedUnivApplyInfoRepository;
private final ApplicationRepository applicationRepository;

public UnivApplyInfoFieldResponse getFields() {
return UnivApplyInfoFieldResponse.of();
Expand Down Expand Up @@ -75,4 +93,106 @@ private HomeUniversity findHomeUniversity(Long homeUniversityId) {
return homeUniversityRepository.findById(homeUniversityId)
.orElseThrow(() -> new CustomException(HOME_UNIVERSITY_NOT_FOUND));
}

@Transactional
@DefaultCacheOut(
key = {"univApplyInfoTextSearch", "university:recommend:general"},
cacheManager = "customCacheManager",
prefix = true
)
public AdminUnivApplyInfoResponse createUnivApplyInfo(AdminUnivApplyInfoCreateRequest request) {
validateTermExists(request.termId());
HomeUniversity homeUniversity = findHomeUniversity(request.homeUniversityId());
HostUniversity hostUniversity = findHostUniversity(request.hostUniversityId());

UnivApplyInfo univApplyInfo = new UnivApplyInfo(
null,
request.termId(),
homeUniversity,
hostUniversity.getKoreanName(),
request.studentCapacity(),
request.semesterAvailableForDispatch(),
request.semesterRequirement(),
request.detailsForLanguage(),
request.gpaRequirement(),
request.gpaRequirementCriteria(),
request.detailsForAccommodation(),
request.extraInfo(),
new HashSet<>(),
hostUniversity
);

UnivApplyInfo saved = univApplyInfoRepository.save(univApplyInfo);

if (request.languageRequirements() != null) {
request.languageRequirements().forEach(lr -> {
LanguageRequirement languageRequirement = new LanguageRequirement(
null, lr.languageTestType(), lr.minScore(), saved
);
saved.addLanguageRequirements(languageRequirement);
});
}

return AdminUnivApplyInfoResponse.from(saved);
}

private HostUniversity findHostUniversity(Long hostUniversityId) {
return hostUniversityRepository.findById(hostUniversityId)
.orElseThrow(() -> new CustomException(UNIVERSITY_NOT_FOUND));
}

@Transactional
@DefaultCacheOut(
key = {"univApplyInfoTextSearch", "university:recommend:general"},
Comment thread
whqtker marked this conversation as resolved.
cacheManager = "customCacheManager",
prefix = true
)
public AdminUnivApplyInfoResponse updateUnivApplyInfo(long id, AdminUnivApplyInfoUpdateRequest request) {
UnivApplyInfo univApplyInfo = univApplyInfoRepository.findById(id)
.orElseThrow(() -> new CustomException(UNIV_APPLY_INFO_NOT_FOUND));

univApplyInfo.update(
request.studentCapacity(),
request.semesterAvailableForDispatch(),
request.semesterRequirement(),
request.detailsForLanguage(),
request.gpaRequirement(),
request.gpaRequirementCriteria(),
request.detailsForAccommodation(),
request.extraInfo()
);

if (request.languageRequirements() != null) {
univApplyInfo.clearLanguageRequirements();
request.languageRequirements().forEach(lr -> {
LanguageRequirement languageRequirement = new LanguageRequirement(
null, lr.languageTestType(), lr.minScore(), univApplyInfo
);
univApplyInfo.addLanguageRequirements(languageRequirement);
});
}

return AdminUnivApplyInfoResponse.from(univApplyInfo);
}

@Transactional
@DefaultCacheOut(
key = {"univApplyInfoTextSearch", "university:recommend:general"},
cacheManager = "customCacheManager",
prefix = true
)
public void deleteUnivApplyInfo(long id) {
UnivApplyInfo univApplyInfo = univApplyInfoRepository.findById(id)
.orElseThrow(() -> new CustomException(UNIV_APPLY_INFO_NOT_FOUND));
validateNoReferences(id);
univApplyInfoRepository.delete(univApplyInfo);
}

private void validateNoReferences(long id) {
if (likedUnivApplyInfoRepository.existsByUnivApplyInfoId(id)
|| applicationRepository.existsByChoicesUnivApplyInfoId(id)) {
throw new CustomException(UNIV_APPLY_INFO_HAS_REFERENCES);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,13 @@ default Application getApplicationBySiteUserIdAndTermId(long siteUserId, long te
.orElseThrow(() -> new CustomException(APPLICATION_NOT_FOUND));
}

@Query("""
SELECT CASE WHEN COUNT(a) > 0 THEN true ELSE false END
FROM Application a
JOIN a.choices c
WHERE c.univApplyInfoId = :univApplyInfoId
""")
boolean existsByChoicesUnivApplyInfoId(@Param("univApplyInfoId") long univApplyInfoId);

void deleteAllBySiteUserId(long siteUserId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public enum ErrorCode {
// data not found
UNIV_APPLY_INFO_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "존재하지 않는 대학교 지원 정보입니다."),
UNIV_APPLY_INFO_NOT_FOUND_FOR_TERM(HttpStatus.NOT_FOUND.value(), "해당하는 대학교가 이번 모집 기간에 열리지 않았습니다."),
UNIV_APPLY_INFO_HAS_REFERENCES(HttpStatus.CONFLICT.value(), "해당 대학 지원 정보를 참조하는 데이터가 존재합니다."),
APPLICATION_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "사용자의 대학 지원 정보를 찾을 수 없습니다."),
USER_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "회원을 찾을 수 없습니다."),
UNIVERSITY_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "대학교를 찾을 수 없습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,12 @@ public ResponseEntity<UnivApplyInfoDetailResponse> getUnivApplyInfoDetails(

@GetMapping("/search/text")
public ResponseEntity<UnivApplyInfoPreviewResponses> searchUnivApplyInfoByText(
@RequestParam(required = false) String value
@RequestParam(required = false) String value,
@RequestParam(required = false) Long homeUniversityId,
@RequestParam(required = false) Long termId
) {
UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(value);
UnivApplyInfoPreviewResponses response =
univApplyInfoQueryService.searchUnivApplyInfoByText(value, homeUniversityId, termId);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,30 @@ public void addLanguageRequirements(LanguageRequirement languageRequirements) {
this.languageRequirements.add(languageRequirements);
}

public void update(
Integer studentCapacity,
SemesterAvailableForDispatch semesterAvailableForDispatch,
String semesterRequirement,
String detailsForLanguage,
String gpaRequirement,
String gpaRequirementCriteria,
String detailsForAccommodation,
Map<String, String> extraInfo
) {
if (studentCapacity != null) this.studentCapacity = studentCapacity;
if (semesterAvailableForDispatch != null) this.semesterAvailableForDispatch = semesterAvailableForDispatch;
if (semesterRequirement != null) this.semesterRequirement = semesterRequirement;
if (detailsForLanguage != null) this.detailsForLanguage = detailsForLanguage;
if (gpaRequirement != null) this.gpaRequirement = gpaRequirement;
if (gpaRequirementCriteria != null) this.gpaRequirementCriteria = gpaRequirementCriteria;
if (detailsForAccommodation != null) this.detailsForAccommodation = detailsForAccommodation;
if (extraInfo != null) this.extraInfo = extraInfo;
}
Comment thread
whqtker marked this conversation as resolved.

public void clearLanguageRequirements() {
this.languageRequirements.clear();
}
Comment thread
whqtker marked this conversation as resolved.

public void updateExtraInfo(Map<String, String> extraInfo) {
this.extraInfo = extraInfo;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ public interface LikedUnivApplyInfoRepository extends JpaRepository<LikedUnivApp

boolean existsBySiteUserIdAndUnivApplyInfoId(long siteUserId, long univApplyInfoId);

boolean existsByUnivApplyInfoId(long univApplyInfoId);

void deleteAllBySiteUserId(long siteUserId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ public interface UnivApplyInfoFilterRepository {

List<UnivApplyInfo> findAllByRegionCodeAndKeywordsAndTermId(String regionCode, List<String> keywords, Long term);

List<UnivApplyInfo> findAllByText(String text, Long termId);
List<UnivApplyInfo> findAllByText(String text, Long termId, Long homeUniversityId);
}
Loading
Loading