From 95fa95041542406ef5eafe541cd4364b2c7881c2 Mon Sep 17 00:00:00 2001 From: Stefan Niclas Heun Date: Sat, 21 Sep 2024 13:31:08 +0200 Subject: [PATCH] removed thesistrack from server and database --- .../ThesisApplicationController.java | 144 ------------- .../payload/ThesisApplicationAssessment.java | 12 -- .../java/prompt/ls1/model/ThesisAdvisor.java | 36 ---- .../prompt/ls1/model/ThesisApplication.java | 98 --------- .../prompt/ls1/model/enums/ResearchArea.java | 15 -- .../repository/ThesisAdvisorRepository.java | 13 -- .../ThesisApplicationRepository.java | 15 -- .../prompt/ls1/service/MailingService.java | 160 -------------- .../ls1/service/ThesisApplicationService.java | 196 ------------------ .../resources/db/changelog/changes/v0022.sql | 18 ++ .../db/changelog/db.changelog-master.xml | 1 + 11 files changed, 19 insertions(+), 689 deletions(-) delete mode 100644 server/src/main/java/prompt/ls1/controller/ThesisApplicationController.java delete mode 100644 server/src/main/java/prompt/ls1/controller/payload/ThesisApplicationAssessment.java delete mode 100644 server/src/main/java/prompt/ls1/model/ThesisAdvisor.java delete mode 100644 server/src/main/java/prompt/ls1/model/ThesisApplication.java delete mode 100644 server/src/main/java/prompt/ls1/model/enums/ResearchArea.java delete mode 100644 server/src/main/java/prompt/ls1/repository/ThesisAdvisorRepository.java delete mode 100644 server/src/main/java/prompt/ls1/repository/ThesisApplicationRepository.java delete mode 100644 server/src/main/java/prompt/ls1/service/ThesisApplicationService.java create mode 100644 server/src/main/resources/db/changelog/changes/v0022.sql diff --git a/server/src/main/java/prompt/ls1/controller/ThesisApplicationController.java b/server/src/main/java/prompt/ls1/controller/ThesisApplicationController.java deleted file mode 100644 index 667efd34..00000000 --- a/server/src/main/java/prompt/ls1/controller/ThesisApplicationController.java +++ /dev/null @@ -1,144 +0,0 @@ -package prompt.ls1.controller; - -import io.github.bucket4j.Bandwidth; -import io.github.bucket4j.Bucket; -import io.github.bucket4j.Refill; -import jakarta.mail.MessagingException; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; -import prompt.ls1.controller.payload.ThesisApplicationAssessment; -import prompt.ls1.model.ThesisAdvisor; -import prompt.ls1.model.ThesisApplication; -import prompt.ls1.service.MailingService; -import prompt.ls1.service.ThesisApplicationService; - -import java.io.IOException; -import java.time.Duration; -import java.util.List; -import java.util.UUID; - -@Slf4j -@RestController -@RequestMapping("/thesis-applications") -public class ThesisApplicationController { - private final Bucket bucket; - private final ThesisApplicationService thesisApplicationService; - private final MailingService mailingService; - - @Autowired - public ThesisApplicationController(final ThesisApplicationService thesisApplicationService, - final MailingService mailingService) { - Bandwidth limit = Bandwidth.classic(100, Refill.greedy(100, Duration.ofMinutes(1))); - this.bucket = Bucket.builder() - .addLimit(limit) - .build(); - this.thesisApplicationService = thesisApplicationService; - this.mailingService = mailingService; - } - - @GetMapping - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity> getAll() { - return ResponseEntity.ok(thesisApplicationService.getAll()); - } - - @GetMapping("/not-assessed") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity> getAllNotAssessed() { - return ResponseEntity.ok(thesisApplicationService.getAllNotAssessed()); - } - - @GetMapping("/{thesisApplicationId}/examination-report") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity getExaminationReport(@PathVariable final UUID thesisApplicationId) { - return ResponseEntity.ok() - .contentType(MediaType.APPLICATION_PDF) - .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=examination_report_%s.pdf", thesisApplicationId)) - .body(thesisApplicationService.getExaminationReport(thesisApplicationId)); - } - - @GetMapping("/{thesisApplicationId}/cv") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity getCV(@PathVariable final UUID thesisApplicationId) { - return ResponseEntity.ok() - .contentType(MediaType.APPLICATION_PDF) - .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=cv_%s.pdf", thesisApplicationId)) - .body(thesisApplicationService.getCV(thesisApplicationId)); - } - - @GetMapping("/{thesisApplicationId}/bachelor-report") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity getBachelorReport(@PathVariable final UUID thesisApplicationId) { - return ResponseEntity.ok() - .contentType(MediaType.APPLICATION_PDF) - .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=bachelor_report_%s.pdf", thesisApplicationId)) - .body(thesisApplicationService.getBachelorReport(thesisApplicationId)); - } - - @RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity create(@RequestPart("thesisApplication") final ThesisApplication thesisApplication, - @RequestPart(value = "examinationReport") final MultipartFile examinationReport, - @RequestPart(value = "cv") final MultipartFile cv, - @RequestPart(value = "bachelorReport", required = false) final MultipartFile bachelorReport) throws MessagingException, IOException { - if (bucket.tryConsume(1)) { - final ThesisApplication application = thesisApplicationService - .create(thesisApplication, examinationReport, cv, bachelorReport); - mailingService.thesisApplicationCreatedEmail(application.getStudent(), application); - mailingService.sendThesisApplicationConfirmationEmail(application.getStudent(), application); - return ResponseEntity.ok(application); - } - - log.error("Post request on /thesis-applications was rejected due to exceeded request velocity."); - return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).build(); - } - - @PostMapping("/{thesisApplicationId}/assessment") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity assess(@PathVariable final UUID thesisApplicationId, - @RequestBody final ThesisApplicationAssessment assessment) { - return ResponseEntity.ok(thesisApplicationService.assess(thesisApplicationId, assessment.getStatus(), assessment.getAssessmentComment())); - } - - @GetMapping("/thesis-advisors") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity> getAllThesisAdvisors() { - return ResponseEntity.ok(thesisApplicationService.getAllThesisAdvisors()); - } - - @PutMapping("/thesis-advisors") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity> updateThesisAdvisorList(@RequestBody final ThesisAdvisor thesisAdvisor) { - return ResponseEntity.ok(thesisApplicationService.updateThesisAdvisorList(thesisAdvisor)); - } - - @PostMapping("/{thesisApplicationId}/thesis-advisor/{thesisAdvisorId}") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity assignThesisAdvisor(@PathVariable final UUID thesisApplicationId, - @PathVariable final UUID thesisAdvisorId) { - return ResponseEntity.ok(thesisApplicationService.assignThesisAdvisor(thesisApplicationId, thesisAdvisorId)); - } - - @PostMapping("/{thesisApplicationId}/accept") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity acceptThesisApplication( - @PathVariable final UUID thesisApplicationId, - @RequestParam(required = false, defaultValue = "true") final boolean notifyStudent) { - return ResponseEntity.ok(thesisApplicationService.accept(thesisApplicationId, notifyStudent)); - } - - @PostMapping("/{thesisApplicationId}/reject") - @PreAuthorize("hasRole('chair-member') || hasRole('prompt-admin')") - public ResponseEntity rejectThesisApplication( - @PathVariable final UUID thesisApplicationId, - @RequestParam(required = false, defaultValue = "true") final boolean notifyStudent) { - return ResponseEntity.ok(thesisApplicationService.reject(thesisApplicationId, notifyStudent)); - } -} diff --git a/server/src/main/java/prompt/ls1/controller/payload/ThesisApplicationAssessment.java b/server/src/main/java/prompt/ls1/controller/payload/ThesisApplicationAssessment.java deleted file mode 100644 index 87c2a768..00000000 --- a/server/src/main/java/prompt/ls1/controller/payload/ThesisApplicationAssessment.java +++ /dev/null @@ -1,12 +0,0 @@ -package prompt.ls1.controller.payload; - -import lombok.Getter; -import lombok.Setter; -import prompt.ls1.model.enums.ApplicationStatus; - -@Getter -@Setter -public class ThesisApplicationAssessment { - private ApplicationStatus status; - private String assessmentComment; -} diff --git a/server/src/main/java/prompt/ls1/model/ThesisAdvisor.java b/server/src/main/java/prompt/ls1/model/ThesisAdvisor.java deleted file mode 100644 index 4c6c6682..00000000 --- a/server/src/main/java/prompt/ls1/model/ThesisAdvisor.java +++ /dev/null @@ -1,36 +0,0 @@ -package prompt.ls1.model; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.Email; -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import java.util.UUID; - -@Data -@Entity -@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "email" }), - @UniqueConstraint(columnNames = { "tumId" }) }) -public class ThesisAdvisor { - - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private UUID id; - - private String firstName; - - private String lastName; - - @Column(length = 50) - @Length(max = 50) - private String tumId; - @Email - @Column(unique = true) - private String email; -} diff --git a/server/src/main/java/prompt/ls1/model/ThesisApplication.java b/server/src/main/java/prompt/ls1/model/ThesisApplication.java deleted file mode 100644 index f86857ef..00000000 --- a/server/src/main/java/prompt/ls1/model/ThesisApplication.java +++ /dev/null @@ -1,98 +0,0 @@ -package prompt.ls1.model; - -import jakarta.persistence.*; -import jakarta.validation.constraints.Max; -import jakarta.validation.constraints.Min; -import lombok.Data; -import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.UpdateTimestamp; -import prompt.ls1.model.enums.ApplicationStatus; -import prompt.ls1.model.enums.Course; -import prompt.ls1.model.enums.FocusTopic; -import prompt.ls1.model.enums.ResearchArea; -import prompt.ls1.model.enums.StudyDegree; -import prompt.ls1.model.enums.StudyProgram; - -import java.io.Serializable; -import java.time.LocalDateTime; -import java.util.Date; -import java.util.Set; -import java.util.UUID; - -@Data -@Entity -@Table -@org.hibernate.annotations.NamedQueries({ - @org.hibernate.annotations.NamedQuery( - name = "ThesisApplication.findAllNotAssessed", - query = "SELECT ta FROM ThesisApplication ta " + - "WHERE ta.applicationStatus = prompt.ls1.model.enums.ApplicationStatus.NOT_ASSESSED" - ) -}) -public class ThesisApplication implements Serializable { - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private UUID id; - - @CreationTimestamp - private LocalDateTime createdAt; - - @UpdateTimestamp - private LocalDateTime updatedAt; - - @ManyToOne - @JoinColumn(name = "student_id", referencedColumnName = "id") - private Student student; - - @Min(1) - @Max(99) - private Short currentSemester; - - @Enumerated(EnumType.STRING) - private StudyDegree studyDegree; - - @Enumerated(EnumType.STRING) - private StudyProgram studyProgram; - - @Column(columnDefinition = "DATE") - private Date desiredThesisStart; - - private String thesisTitle; - - @Column(length = 1000) - private String interests; - - @Column(length = 1000) - private String projects; - - @Column(length = 1000) - private String specialSkills; - - @Column(length = 500) - private String motivation; - - @Enumerated(EnumType.STRING) - private Set coursesTaken; - - @Enumerated(EnumType.STRING) - private Set researchAreas; - - @Enumerated(EnumType.STRING) - private Set focusTopics; - - @Enumerated(EnumType.STRING) - private ApplicationStatus applicationStatus; - - @Column(length = 2000) - private String assessmentComment; - - private String examinationReportFilename; - - private String cvFilename; - - private String bachelorReportFilename; - - @ManyToOne - @JoinColumn(name = "thesis_advisor_id") - private ThesisAdvisor thesisAdvisor; -} diff --git a/server/src/main/java/prompt/ls1/model/enums/ResearchArea.java b/server/src/main/java/prompt/ls1/model/enums/ResearchArea.java deleted file mode 100644 index 141a6c77..00000000 --- a/server/src/main/java/prompt/ls1/model/enums/ResearchArea.java +++ /dev/null @@ -1,15 +0,0 @@ -package prompt.ls1.model.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public enum ResearchArea { - EDUCATION_TECHNOLOGIES("Education Technologies"), - HUMAN_COMPUTER_INTERACTION("Human Computer Interaction"), - ROBOTIC("Robotic"), - SOFTWARE_ENGINEERING("Software Engineering"); - - private String value; -} diff --git a/server/src/main/java/prompt/ls1/repository/ThesisAdvisorRepository.java b/server/src/main/java/prompt/ls1/repository/ThesisAdvisorRepository.java deleted file mode 100644 index d9032e3a..00000000 --- a/server/src/main/java/prompt/ls1/repository/ThesisAdvisorRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package prompt.ls1.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import prompt.ls1.model.ThesisAdvisor; - -import java.util.Optional; -import java.util.UUID; - -@Repository -public interface ThesisAdvisorRepository extends JpaRepository { - Optional findByTumId(final String tumId); -} diff --git a/server/src/main/java/prompt/ls1/repository/ThesisApplicationRepository.java b/server/src/main/java/prompt/ls1/repository/ThesisApplicationRepository.java deleted file mode 100644 index 6a7e1ac2..00000000 --- a/server/src/main/java/prompt/ls1/repository/ThesisApplicationRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package prompt.ls1.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; -import prompt.ls1.model.ThesisApplication; - -import java.util.List; -import java.util.UUID; - -@Repository -public interface ThesisApplicationRepository extends JpaRepository { - @Transactional - List findAllNotAssessed(); -} diff --git a/server/src/main/java/prompt/ls1/service/MailingService.java b/server/src/main/java/prompt/ls1/service/MailingService.java index b5eb5d1e..d189886a 100644 --- a/server/src/main/java/prompt/ls1/service/MailingService.java +++ b/server/src/main/java/prompt/ls1/service/MailingService.java @@ -14,11 +14,7 @@ import prompt.ls1.model.CourseIteration; import prompt.ls1.model.DeveloperApplication; import prompt.ls1.model.Student; -import prompt.ls1.model.ThesisAdvisor; -import prompt.ls1.model.ThesisApplication; import prompt.ls1.model.TutorApplication; -import prompt.ls1.model.enums.FocusTopic; -import prompt.ls1.model.enums.ResearchArea; import java.io.File; import java.io.IOException; @@ -61,88 +57,6 @@ public void updateMailTemplate(final String filename, final String htmlContents) storageService.writeToFile(rootLocation, filename + ".html", htmlContents); } - public void thesisApplicationCreatedEmail(final Student student, - final ThesisApplication thesisApplication) throws MessagingException, IOException { - MimeMessage message = javaMailSender.createMimeMessage(); - - message.setFrom(sender); - Arrays.asList(chairMemberRecipientsList.split(";")).forEach(recipient -> { - try { - message.addRecipients(MimeMessage.RecipientType.TO, recipient); - } catch (MessagingException e) { - throw new RuntimeException(e); - } - }); - - message.setSubject("PROMPT | New Thesis Application"); - - String template = storageService.readFromFile(rootLocation, "thesis-application-created.html"); - template = fillStudentPlaceholders(template, student); - template = fillThesisApplicationPlaceholders(template, thesisApplication); - - Multipart multipart = new MimeMultipart(); - - BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setContent(template, "text/html; charset=utf-8"); - multipart.addBodyPart(messageBodyPart); - - MimeBodyPart examinationReportAttachment = new MimeBodyPart(); - examinationReportAttachment.attachFile(new File("thesis_application_uploads/" + thesisApplication.getExaminationReportFilename())); - multipart.addBodyPart(examinationReportAttachment); - - MimeBodyPart cvAttachment = new MimeBodyPart(); - cvAttachment.attachFile(new File("thesis_application_uploads/" + thesisApplication.getCvFilename())); - multipart.addBodyPart(cvAttachment); - - if (thesisApplication.getBachelorReportFilename() != null && !thesisApplication.getBachelorReportFilename().isBlank()) { - MimeBodyPart bachelorReportAttachment = new MimeBodyPart(); - bachelorReportAttachment.attachFile(new File("thesis_application_uploads/" + thesisApplication.getBachelorReportFilename())); - multipart.addBodyPart(bachelorReportAttachment); - } - - message.setContent(multipart); - - javaMailSender.send(message); - } - - public void sendThesisApplicationConfirmationEmail(final Student student, - final ThesisApplication thesisApplication) throws MessagingException, IOException { - MimeMessage message = javaMailSender.createMimeMessage(); - - message.setFrom(sender); - message.setRecipients(MimeMessage.RecipientType.TO, student.getEmail()); - - message.setSubject("PROMPT | Thesis Application Confirmation"); - - String template = storageService.readFromFile(rootLocation, "thesis-application-confirmation.html"); - template = fillStudentPlaceholders(template, student); - template = fillThesisApplicationPlaceholders(template, thesisApplication); - - Multipart multipart = new MimeMultipart(); - - BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setContent(template, "text/html; charset=utf-8"); - multipart.addBodyPart(messageBodyPart); - - MimeBodyPart examinationReportAttachment = new MimeBodyPart(); - examinationReportAttachment.attachFile(new File("thesis_application_uploads/" + thesisApplication.getExaminationReportFilename())); - multipart.addBodyPart(examinationReportAttachment); - - MimeBodyPart cvAttachment = new MimeBodyPart(); - cvAttachment.attachFile(new File("thesis_application_uploads/" + thesisApplication.getCvFilename())); - multipart.addBodyPart(cvAttachment); - - if (thesisApplication.getBachelorReportFilename() != null && !thesisApplication.getBachelorReportFilename().isBlank()) { - MimeBodyPart bachelorReportAttachment = new MimeBodyPart(); - bachelorReportAttachment.attachFile(new File("thesis_application_uploads/" + thesisApplication.getBachelorReportFilename())); - multipart.addBodyPart(bachelorReportAttachment); - } - - message.setContent(multipart); - - javaMailSender.send(message); - } - public void sendDeveloperApplicationConfirmationEmail(final Student student, final DeveloperApplication developerApplication, final CourseIteration courseIteration) throws MessagingException { @@ -352,55 +266,6 @@ public void sendTechnicalDetailsSubmissionInvitationEmail(final Student student, javaMailSender.send(message); } - public void sendThesisAcceptanceEmail(final Student student, - final ThesisApplication thesisApplication, - final ThesisAdvisor thesisAdvisor) throws MessagingException { - MimeMessage message = javaMailSender.createMimeMessage(); - - message.setFrom(sender); - message.setRecipients(MimeMessage.RecipientType.TO, student.getEmail()); - if (environment.equals("prod")) { - message.addRecipients(MimeMessage.RecipientType.CC, "krusche@tum.de"); - } - message.addRecipients(MimeMessage.RecipientType.BCC, "valeryia.andraichuk@tum.de"); - message.setSubject("Thesis Application Acceptance"); - - String template; - if (!thesisAdvisor.getEmail().equals("krusche@tum.de")) { - message.addRecipients(MimeMessage.RecipientType.CC, thesisAdvisor.getEmail()); - - template = storageService.readFromFile(rootLocation, "thesis-application-acceptance.html"); - template = fillThesisAdvisorPlaceholders(template, thesisAdvisor); - } else { - template = storageService.readFromFile(rootLocation, "thesis-application-acceptance-no-advisor.html"); - } - template = fillStudentPlaceholders(template, student); - template = fillThesisApplicationPlaceholders(template, thesisApplication); - message.setContent(template, "text/html; charset=utf-8"); - - javaMailSender.send(message); - } - - public void sendThesisRejectionEmail(final Student student, final ThesisApplication thesisApplication) throws MessagingException { - MimeMessage message = javaMailSender.createMimeMessage(); - - message.setFrom(sender); - message.setRecipients(MimeMessage.RecipientType.TO, student.getEmail()); - if (environment.equals("prod")) { - message.addRecipients(MimeMessage.RecipientType.BCC, "krusche@tum.de"); - } - message.addRecipients(MimeMessage.RecipientType.BCC, "valeryia.andraichuk@tum.de"); - message.setSubject("Thesis Application Rejection"); - - String template = storageService.readFromFile(rootLocation, "thesis-application-rejection.html"); - template = fillStudentPlaceholders(template, student); - template = fillThesisApplicationPlaceholders(template, thesisApplication); - - message.setContent(template, "text/html; charset=utf-8"); - - javaMailSender.send(message); - } - public String fillCourseIterationPlaceholders(final String template, final CourseIteration courseIteration) { String pattern = "dd. MMM yyyy"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); @@ -474,29 +339,4 @@ private String fillStudentPlaceholders(final String template, final Student stud .replace("{{student.nationality}}", student.getNationality()) .replace("{{student.isExchangeStudent}}", student.getIsExchangeStudent().toString()); } - - private String fillThesisApplicationPlaceholders(final String template, final ThesisApplication thesisApplication) { - String pattern = "dd. MMM yyyy"; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); - - return template.replace("{{application.studyProgram}}", thesisApplication.getStudyProgram().getValue()) - .replace("{{application.studyDegree}}", thesisApplication.getStudyDegree().getValue()) - .replace("{{application.currentSemester}}", thesisApplication.getCurrentSemester().toString()) - .replace("{{application.desiredThesisStart}}", simpleDateFormat.format(thesisApplication.getDesiredThesisStart())) - .replace("{{application.specialSkills}}", thesisApplication.getSpecialSkills()) - .replace("{{application.motivation}}", thesisApplication.getMotivation()) - .replace("{{application.interests}}", thesisApplication.getInterests()) - .replace("{{application.projects}}", thesisApplication.getProjects()) - .replace("{{application.specialSkills}}", thesisApplication.getSpecialSkills()) - .replace("{{application.thesisTitle}}", thesisApplication.getThesisTitle()) - .replace("{{application.researchAreas}}", String.join(", ", thesisApplication.getResearchAreas().stream().map(ResearchArea::getValue).toList())) - .replace("{{application.focusTopics}}", String.join(", ", thesisApplication.getFocusTopics().stream().map(FocusTopic::getValue).toList())); - } - - private String fillThesisAdvisorPlaceholders(final String template, final ThesisAdvisor thesisAdvisor) { - return template.replace("{{advisor.firstName}}", thesisAdvisor.getFirstName()) - .replace("{{advisor.lastName}}", thesisAdvisor.getLastName()) - .replace("{{advisor.email}}", thesisAdvisor.getEmail()) - .replace("{{advisor.tumId}}", thesisAdvisor.getTumId()); - } } diff --git a/server/src/main/java/prompt/ls1/service/ThesisApplicationService.java b/server/src/main/java/prompt/ls1/service/ThesisApplicationService.java deleted file mode 100644 index 0539ed09..00000000 --- a/server/src/main/java/prompt/ls1/service/ThesisApplicationService.java +++ /dev/null @@ -1,196 +0,0 @@ -package prompt.ls1.service; - -import jakarta.mail.MessagingException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.Resource; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; -import prompt.ls1.exception.FailedMailSend; -import prompt.ls1.exception.ResourceInvalidParametersException; -import prompt.ls1.model.Student; -import prompt.ls1.model.ThesisAdvisor; -import prompt.ls1.model.ThesisApplication; -import prompt.ls1.model.enums.ApplicationStatus; -import prompt.ls1.repository.StudentRepository; -import prompt.ls1.repository.ThesisAdvisorRepository; -import prompt.ls1.repository.ThesisApplicationRepository; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Service -public class ThesisApplicationService { - private final ThesisApplicationRepository thesisApplicationRepository; - private final StudentRepository studentRepository; - private final ThesisAdvisorRepository thesisAdvisorRepository; - private final FileSystemStorageService storageService; - private final MailingService mailingService; - private final Path rootLocation; - - @Autowired - public ThesisApplicationService(final ThesisApplicationRepository thesisApplicationRepository, - final StudentRepository studentRepository, - final ThesisAdvisorRepository thesisAdvisorRepository, - final FileSystemStorageService storageService, - final MailingService mailingService, - @Value("${prompt.storage.theses-application-uploads-location}") String thesesApplicationsUploadsLocation) { - this.thesisApplicationRepository = thesisApplicationRepository; - this.studentRepository = studentRepository; - this.thesisAdvisorRepository = thesisAdvisorRepository; - this.storageService = storageService; - this.mailingService = mailingService; - this.rootLocation = Paths.get(thesesApplicationsUploadsLocation); - } - - public List getAll() { - return thesisApplicationRepository.findAll(); - } - - public List getAllNotAssessed() { - return thesisApplicationRepository.findAllNotAssessed(); - } - - public Resource getExaminationReport(final UUID thesisApplicationId) { - final ThesisApplication thesisApplication = findById(thesisApplicationId); - return storageService.load(rootLocation, thesisApplication.getExaminationReportFilename()); - } - - public Resource getCV(final UUID thesisApplicationId) { - final ThesisApplication thesisApplication = findById(thesisApplicationId); - return storageService.load(rootLocation, thesisApplication.getCvFilename()); - } - - public Resource getBachelorReport(final UUID thesisApplicationId) { - final ThesisApplication thesisApplication = findById(thesisApplicationId); - return storageService.load(rootLocation, thesisApplication.getBachelorReportFilename()); - } - - public ThesisApplication create(final ThesisApplication thesisApplication, - final MultipartFile transcriptOfRecords, - final MultipartFile cv, - final MultipartFile bachelorReport) { - final Student student = thesisApplication.getStudent(); - if (student == null || - (student.getTumId() == null && student.getMatriculationNumber() == null && student.getEmail() == null)) { - throw new IllegalArgumentException( - "Student identification information must be provided: tum ID, matriculation number or email address."); - } - Optional existingStudent = findStudent(student.getTumId(), student.getMatriculationNumber(), student.getEmail()); - - if (existingStudent.isEmpty()) { - studentRepository.save(student); - } else { - thesisApplication.setStudent(checkAndUpdateStudent(existingStudent.get(), thesisApplication.getStudent())); - } - - final String examinationReportFilename = storageService.store(rootLocation, transcriptOfRecords); - thesisApplication.setExaminationReportFilename(examinationReportFilename); - final String cvFilename = storageService.store(rootLocation, cv); - thesisApplication.setCvFilename(cvFilename); - if (bachelorReport != null && !bachelorReport.isEmpty()) { - final String bachelorReportFilename = storageService.store(rootLocation, bachelorReport); - thesisApplication.setBachelorReportFilename(bachelorReportFilename); - } - - thesisApplication.setApplicationStatus(ApplicationStatus.NOT_ASSESSED); - return thesisApplicationRepository.save(thesisApplication); - } - - public ThesisApplication assess(final UUID thesisApplicationId, - final ApplicationStatus status, - final String assessmentComment) { - final ThesisApplication thesisApplication = findById(thesisApplicationId); - thesisApplication.setApplicationStatus(status); - thesisApplication.setAssessmentComment(assessmentComment); - return thesisApplicationRepository.save(thesisApplication); - } - - public ThesisApplication assignThesisAdvisor(final UUID thesisApplicationId, final UUID thesisAdvisorId) { - final ThesisApplication thesisApplication = findById(thesisApplicationId); - final ThesisAdvisor thesisAdvisor = thesisAdvisorRepository.findById(thesisAdvisorId) - .orElseThrow(() -> new ResourceInvalidParametersException( - String.format("Thesis advisor with id %s not found.", thesisAdvisorId))); - thesisApplication.setThesisAdvisor(thesisAdvisor); - return thesisApplicationRepository.save(thesisApplication); - } - - public ThesisApplication accept(final UUID thesisApplicationId, final boolean notifyStudent) { - final ThesisApplication thesisApplication = findById(thesisApplicationId); - if (thesisApplication.getThesisAdvisor() == null) { - throw new ResourceInvalidParametersException("Thesis advisor must be assigned before accepting a thesis application."); - } - - thesisApplication.setApplicationStatus(ApplicationStatus.ACCEPTED); - - if (notifyStudent) { - try { - mailingService.sendThesisAcceptanceEmail( - thesisApplication.getStudent(), thesisApplication, thesisApplication.getThesisAdvisor()); - } catch (MessagingException e) { - throw new FailedMailSend("Failed to send thesis acceptance email."); - } - } - - return thesisApplicationRepository.save(thesisApplication); - } - - public ThesisApplication reject(final UUID thesisApplicationId, final boolean notifyStudent) { - final ThesisApplication thesisApplication = findById(thesisApplicationId); - thesisApplication.setApplicationStatus(ApplicationStatus.REJECTED); - - if (notifyStudent) { - try { - mailingService.sendThesisRejectionEmail(thesisApplication.getStudent(), thesisApplication); - } catch (MessagingException e) { - throw new FailedMailSend("Failed to send thesis rejection email."); - } - } - - return thesisApplicationRepository.save(thesisApplication); - } - - public List getAllThesisAdvisors() { - return thesisAdvisorRepository.findAll(); - } - - public List updateThesisAdvisorList(final ThesisAdvisor thesisAdvisor) { - if (thesisAdvisor.getTumId() != null && !thesisAdvisor.getTumId().isBlank()) { - if (thesisAdvisorRepository.findByTumId(thesisAdvisor.getTumId()).isEmpty()) { - thesisAdvisorRepository.save(thesisAdvisor); - } - } - - return thesisAdvisorRepository.findAll(); - } - - private ThesisApplication findById(final UUID thesisApplicationId) { - return thesisApplicationRepository.findById(thesisApplicationId) - .orElseThrow(() -> new ResourceInvalidParametersException( - String.format("Thesis application with id %s not found.", thesisApplicationId))); - } - - private Optional findStudent(final String tumId, final String matriculationNumber, final String email) { - if ((tumId != null && !tumId.isBlank()) || (matriculationNumber != null && !matriculationNumber.isBlank())) { - return studentRepository.findByTumIdOrMatriculationNumber(tumId, matriculationNumber); - } - return studentRepository.findByEmail(email); - } - - private Student checkAndUpdateStudent(final Student existingStudent, final Student updatedStudent) { - if (((existingStudent.getTumId() != null && !existingStudent.getTumId().isBlank()) && !existingStudent.getTumId().equals(updatedStudent.getTumId())) || - (existingStudent.getMatriculationNumber() != null && !existingStudent.getMatriculationNumber().isBlank()) && !existingStudent.getMatriculationNumber().equals(updatedStudent.getMatriculationNumber())) { - throw new ResourceInvalidParametersException("Provided TUM ID does not match with the matriculation number you submitted. " + - "If You are sure the data is entered correct, please contact the Program Management."); - } - existingStudent.setGender(updatedStudent.getGender()); - existingStudent.setFirstName(updatedStudent.getFirstName()); - existingStudent.setLastName(updatedStudent.getLastName()); - existingStudent.setEmail(updatedStudent.getEmail()); - - return studentRepository.save(existingStudent); - } -} diff --git a/server/src/main/resources/db/changelog/changes/v0022.sql b/server/src/main/resources/db/changelog/changes/v0022.sql new file mode 100644 index 00000000..6f133d1a --- /dev/null +++ b/server/src/main/resources/db/changelog/changes/v0022.sql @@ -0,0 +1,18 @@ +--liquibase formatted sql + +--changeset author:niclasheun + +-- Drop CAST from focus_topic +DROP CAST IF EXISTS (varchar AS focus_topic); + +-- Drop focus_topic ENUM +DROP TYPE IF EXISTS focus_topic CASCADE; + +DROP CAST IF EXISTS (varchar AS research_area); +DROP TYPE IF EXISTS research_area CASCADE; + +-- Drop thesis_application table +DROP TABLE IF EXISTS thesis_application CASCADE; + +-- Drop the thesis_advisor table (if necessary) +DROP TABLE IF EXISTS thesis_advisor CASCADE; \ No newline at end of file diff --git a/server/src/main/resources/db/changelog/db.changelog-master.xml b/server/src/main/resources/db/changelog/db.changelog-master.xml index 242e0e8e..35ea6e14 100644 --- a/server/src/main/resources/db/changelog/db.changelog-master.xml +++ b/server/src/main/resources/db/changelog/db.changelog-master.xml @@ -23,4 +23,5 @@ + \ No newline at end of file