Skip to content

Commit

Permalink
[Feat] 서류 최종 결과를 이메일로 공지할 수 있다. #40 (#41)
Browse files Browse the repository at this point in the history
* feat: 결과 이메일 공지 api 개발

* docs: 결과 이메일 전송 api 명세서 완성
  • Loading branch information
birdieHyun authored Oct 27, 2023
1 parent abb4047 commit 290d648
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 2 deletions.
17 changes: 17 additions & 0 deletions src/docs/asciidoc/api/application/application.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,20 @@ include::{snippets}/admin-application-updateDocumentPass-doc/request-fields.adoc
==== HTTP Request
include::{snippets}/admin-application-updateInterviewTime-doc/http-request.adoc[]
include::{snippets}/admin-application-updateInterviewTime-doc/request-fields.adoc[]


=== 서류 합격 메일
==== HTTP Request
include::{snippets}/admin-application-sendDocumentPassEmail-doc/http-request.adoc[]

=== 서류 불합격 메일
==== HTTP Request
include::{snippets}/admin-application-sendDocumentFailEmail-doc/http-request.adoc[]

=== 최종 합격 메일
==== HTTP Request
include::{snippets}/admin-application-sendFinalPassEmail-doc/http-request.adoc[]

=== 최종 불합격 메일
==== HTTP Request
include::{snippets}/admin-application-sendFinalFailEmail-doc/http-request.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,60 @@ public ResponseEntity<CustomResponse> updateInterviewTime(@PathVariable Long id,
"연세골프 지원서 면접 시간 수정 성공"
));
}

@PostMapping("/admin/forms/documentPassEmail")
public ResponseEntity<CustomResponse> sendDocumentPassEmail() {

applicationService.sendDocumentPassEmail();

return ResponseEntity
.ok()
.body(new CustomResponse(
"success",
200,
"연세골프 지원서 서류 합격자 이메일 전송 성공"
));
}

@PostMapping("/admin/forms/finalPassEmail")
public ResponseEntity<CustomResponse> sendFinalPassEmail() {

applicationService.sendFinalPassEmail();

return ResponseEntity
.ok()
.body(new CustomResponse(
"success",
200,
"연세골프 지원서 최종 합격자 이메일 전송 성공"
));
}

@PostMapping("/admin/forms/documentFailEmail")
public ResponseEntity<CustomResponse> sendDocumentFailEmail() {

applicationService.sendDocumentFailEmail();

return ResponseEntity
.ok()
.body(new CustomResponse(
"success",
200,
"연세골프 지원서 서류 불합격자 이메일 전송 성공"
));
}

@PostMapping("/admin/forms/finalFailEmail")
public ResponseEntity<CustomResponse> sendFinalFailEmail() {

applicationService.sendFinalFailEmail();

return ResponseEntity
.ok()
.body(new CustomResponse(
"success",
200,
"연세골프 지원서 최종 불합격자 이메일 전송 성공"
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import yonseigolf.server.apply.dto.response.SingleApplicationResult;
import yonseigolf.server.apply.entity.Application;

import java.util.List;

public interface ApplicationRepositoryCustom {

Page<SingleApplicationResult> getApplicationResults(Boolean documentPass, Boolean finalPass, Pageable pageable);

List<Application> findApplicationsForEmail(Boolean documentPass, Boolean finalPass);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.springframework.data.domain.Pageable;
import yonseigolf.server.apply.dto.response.QSingleApplicationResult;
import yonseigolf.server.apply.dto.response.SingleApplicationResult;
import yonseigolf.server.apply.entity.Application;

import java.util.List;

Expand Down Expand Up @@ -47,6 +48,17 @@ public Page<SingleApplicationResult> getApplicationResults(Boolean documentPass,
return new PageImpl<>(results, pageable, total);
}

@Override
public List<Application> findApplicationsForEmail(Boolean documentPass, Boolean finalPass) {

return queryFactory.selectFrom(application)
.where(
documentPassEq(documentPass),
finalPassEq(finalPass)
)
.fetch();
}

private BooleanExpression documentPassEq(Boolean documentPass) {

if (documentPass == null) {
Expand Down
65 changes: 64 additions & 1 deletion src/main/java/yonseigolf/server/apply/service/ApplyService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@
import yonseigolf.server.apply.entity.EmailAlarm;
import yonseigolf.server.apply.repository.ApplicationRepository;
import yonseigolf.server.apply.repository.EmailRepository;
import yonseigolf.server.email.service.EmailService;

import java.time.LocalDateTime;
import java.util.List;


@Service
public class ApplyService {

private final ApplicationRepository applicationRepository;
private final EmailRepository emailRepository;
private final EmailService emailService;

@Autowired
public ApplyService(ApplicationRepository applicationRepository, EmailRepository emailRepository) {
public ApplyService(ApplicationRepository applicationRepository, EmailRepository emailRepository, EmailService emailService) {

this.applicationRepository = applicationRepository;
this.emailRepository = emailRepository;
this.emailService = emailService;
}

public void apply(ApplicationRequest request) {
Expand Down Expand Up @@ -68,6 +72,65 @@ public void updateInterviewTime(Long id, LocalDateTime time) {
findById(id).updateInterviewTime(time);
}


// TODO: ENUM 활용해서 코드 개선 가능할듯 보인다
public void sendDocumentPassEmail() {
List<Application> applications = findApplicationsByPassFail(true, null);

applications.stream()
.forEach(application -> emailService.sendEmail(application.getEmail(),
"안녕하세요. 연세대학교 골프동아리 결과 메일입니다.",
application.getName() +"님 서류 합격 축하드립니다. \n" +
"면접 일정은 추후 공지될 예정입니다. \n" +
"감사합니다."));
}

public void sendFinalPassEmail() {
List<Application> applications = findApplicationsByPassFail(true, true);

applications.stream()
.forEach(application -> emailService.sendEmail(application.getEmail(),
"안녕하세요. 연세대학교 골프동아리 결과 메일입니다.",
application.getName() +"님 최종 합격 축하드립니다. \n" +
"추후 일정은 문자로 공지될 예정입니다. \n" +
"감사합니다."));
}

public void sendDocumentFailEmail() {
List<Application> applications = findApplicationsByPassFail(false, null);

applications.stream()
.forEach(application -> emailService.sendEmail(application.getEmail(),
"안녕하세요. 연세대학교 골프동아리 결과 메일입니다.",
application.getName() + "님 연세골프에 지원해주셔서 감사합니다. \n\n\n" +
"안타깝게도 " + application.getName() + "님께 이번 연골 모집에서 합격의 소식을 전해드리지 못하게 되었습니다." +
application.getName() + "님의 뛰어난 열정에도 불구하고, 연세골프는 한정된 인원으로만 운영되는 만큼 아쉽게도 이런 소식을 전해드리게 됐습니다." +
"비록 이번 모집에서 " + application.getName() +"님과 함께하지 못하지만, 다음에 함께 할 수 있기를 바라겠습니다. \n\n" +
"바쁘신 와중에 지원해주셔서 감사합니다. \n\n" +
"연세 골프 운영진 드림")
);
}

public void sendFinalFailEmail() {
List<Application> applications = findApplicationsByPassFail(true, false);

applications.stream()
.forEach(application -> emailService.sendEmail(application.getEmail(),
"안녕하세요. 연세대학교 골프동아리 결과 메일입니다.",
application.getName() + "님 연세골프에 지원해주셔서 감사합니다. \n\n\n" +
"안타깝게도 " + application.getName() + "님께 이번 연골 모집에서 합격의 소식을 전해드리지 못하게 되었습니다." +
application.getName() + "님의 뛰어난 열정에도 불구하고, 연세골프는 한정된 인원으로만 운영되는 만큼 아쉽게도 이런 소식을 전해드리게 됐습니다." +
"비록 이번 모집에서 " + application.getName() +"님과 함께하지 못하지만, 다음에 함께 할 수 있기를 바라겠습니다. \n\n" +
"바쁘신 와중에 지원해주셔서 감사합니다. \n\n" +
"연세 골프 운영진 드림")
);
}

private List<Application> findApplicationsByPassFail(Boolean docuemntPass, Boolean finalPass) {

return applicationRepository.findApplicationsForEmail(docuemntPass, finalPass);
}

private Application findById(Long id) {

return applicationRepository.findById(id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ public void sendApplyStartAlert() {
emailRepository.deleteAll();
}


private List<EmailAlarm> findAllAlert() {

return emailRepository.findAll();
}

private void sendEmail(String to, String subject, String text) {
public void sendEmail(String to, String subject, String text) {

SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,4 +464,80 @@ void updateInterviewTimeTest() throws Exception {
)
);
}

@Test
@DisplayName("서류 합격자들에게 합격 이메일을 전송할 수 있다.")
void sendDocumentPassEmailTest() throws Exception {
// given
doNothing().when(applyService).sendDocumentPassEmail();

// when
applyService.sendDocumentPassEmail();

// then
mockMvc.perform(post("/admin/forms/documentPassEmail"))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("admin-application-sendDocumentPassEmail-doc",
getDocumentRequest(),
getDocumentResponse()
));
}

@Test
@DisplayName("서류 불합격자들에게 불합격 이메일을 전송할 수 있다.")
void sendDocumentFailEmailTest() throws Exception {
// given
doNothing().when(applyService).sendDocumentFailEmail();

// when
applyService.sendDocumentFailEmail();

// then
mockMvc.perform(post("/admin/forms/documentFailEmail"))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("admin-application-sendDocumentFailEmail-doc",
getDocumentRequest(),
getDocumentResponse()
));
}

@Test
@DisplayName("최종 합격자들에게 합격 이메일을 전송할 수 있다.")
void sendFinalPassEmailTest() throws Exception {
// given
doNothing().when(applyService).sendFinalPassEmail();

// when
applyService.sendFinalPassEmail();

// then
mockMvc.perform(post("/admin/forms/finalPassEmail"))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("admin-application-sendFinalPassEmail-doc",
getDocumentRequest(),
getDocumentResponse()
));
}

@Test
@DisplayName("최종 불합격자들에게 불합격 이메일을 전송할 수 있다.")
void sendFinalFailEmailTest() throws Exception {
// given
doNothing().when(applyService).sendFinalFailEmail();

// when
applyService.sendFinalFailEmail();

// then
mockMvc.perform(post("/admin/forms/finalPassEmail"))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("admin-application-sendFinalFailEmail-doc",
getDocumentRequest(),
getDocumentResponse()
));
}
}

0 comments on commit 290d648

Please sign in to comment.