From c20344ca5646999c47e985781d9839bd585fe05f Mon Sep 17 00:00:00 2001
From: Timur Oberhuber <t.oberhuber@student.tudelft.nl>
Date: Mon, 29 Jan 2024 13:29:46 +0100
Subject: [PATCH] :sparkles: Add Coordinator Notification Emails

---
 CHANGELOG.md                                  |  1 +
 .../java/nl/tudelft/tam/cron/CronService.java | 29 +++++++++++++------
 .../dto/patch/CoordinatorDefaultPatchDTO.java |  3 ++
 .../tudelft/tam/model/CoordinatorDefault.java |  2 ++
 .../service/CoordinatorDefaultService.java    |  4 ++-
 src/main/resources/messages.properties        |  2 ++
 src/main/resources/migrations.yaml            | 18 ++++++++----
 .../templates/coordinator/defaults.html       | 13 +++++++++
 .../CoordinatorDefaultServiceTest.java        |  8 ++++-
 9 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e686a044a..7064932ab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Raise request updates are sent to the requestee upon approval/rejection @toberhuber
 - Button for coordinator to remind teachers of unhandled applications @toberhuber
 - Automated emails to remind teachers of unhandled applications/declarations after deadline @toberhuber
+- Add a separate email address field for coordinators to receive notifications on @toberhuber
 
 ### Changed
 - Job offer applications are sorted based on the time of application @dsavvidi
diff --git a/src/main/java/nl/tudelft/tam/cron/CronService.java b/src/main/java/nl/tudelft/tam/cron/CronService.java
index 51fb41961..f14dbce10 100644
--- a/src/main/java/nl/tudelft/tam/cron/CronService.java
+++ b/src/main/java/nl/tudelft/tam/cron/CronService.java
@@ -36,6 +36,7 @@ import nl.tudelft.tam.dto.view.summary.ExtraWorkSummaryDTO;
 import nl.tudelft.tam.dto.view.summary.JobOfferSummaryDTO;
 import nl.tudelft.tam.enums.NotificationFrequency;
 import nl.tudelft.tam.model.Coordinator;
+import nl.tudelft.tam.model.CoordinatorDefault;
 import nl.tudelft.tam.model.Profile;
 import nl.tudelft.tam.service.*;
 
@@ -75,6 +76,9 @@ public class CronService {
 	@Autowired
 	private CoordinatorService coordinatorService;
 
+	@Autowired
+	private CoordinatorDefaultService coordinatorDefaultService;
+
 	@Autowired
 	private PersonService personService;
 
@@ -123,16 +127,23 @@ public class CronService {
 					.map(Coordinator::getId).toList();
 			List<PersonSummaryDTO> coordinators = personService.getPeopleById(coordinatorIds);
 
-			coordinators.forEach(coordinator -> {
-				profileService.findById(coordinator.getId()).ifPresent(profile -> {
-					if (profile.getEmailNotifications()
-							&& profile.getEmailNotificationFrequency().equals(frequency)) {
-						coordinatorEmailToDisplayName.put(
-								personService.getPersonById(profile.getId()).getEmail(),
-								coordinator.getDisplayName());
-					}
+			CoordinatorDefault coordinatorDefault = coordinatorDefaultService.findByIdOrThrow(programId);
+			String notificationEmail = coordinatorDefault.getCoordinatorNotificationEmail();
+
+			if (notificationEmail != null && !notificationEmail.isBlank()) {
+				coordinatorEmailToDisplayName.put(notificationEmail, "Coordinator");
+			} else {
+				coordinators.forEach(coordinator -> {
+					profileService.findById(coordinator.getId()).ifPresent(profile -> {
+						if (profile.getEmailNotifications()
+								&& profile.getEmailNotificationFrequency().equals(frequency)) {
+							coordinatorEmailToDisplayName.put(
+									personService.getPersonById(profile.getId()).getEmail(),
+									coordinator.getDisplayName());
+						}
+					});
 				});
-			});
+			}
 		}
 
 		// Send Emails
diff --git a/src/main/java/nl/tudelft/tam/dto/patch/CoordinatorDefaultPatchDTO.java b/src/main/java/nl/tudelft/tam/dto/patch/CoordinatorDefaultPatchDTO.java
index 7a5b0eeaa..d5b02ec1e 100644
--- a/src/main/java/nl/tudelft/tam/dto/patch/CoordinatorDefaultPatchDTO.java
+++ b/src/main/java/nl/tudelft/tam/dto/patch/CoordinatorDefaultPatchDTO.java
@@ -44,6 +44,8 @@ public class CoordinatorDefaultPatchDTO extends Patch<CoordinatorDefault> {
 
 	private String coordinatorContractEmail;
 
+	private String coordinatorNotificationEmail;
+
 	@Override
 	protected void applyOneToOne() {
 		data.setJobOfferDefault(jobOfferDefaultPatchDTO.apply(data.getJobOfferDefault()));
@@ -51,6 +53,7 @@ public class CoordinatorDefaultPatchDTO extends Patch<CoordinatorDefault> {
 
 		data.setCoordinatorContractName(coordinatorContractName);
 		data.setCoordinatorContractEmail(coordinatorContractEmail);
+		data.setCoordinatorNotificationEmail(coordinatorNotificationEmail);
 	}
 
 	@Override
diff --git a/src/main/java/nl/tudelft/tam/model/CoordinatorDefault.java b/src/main/java/nl/tudelft/tam/model/CoordinatorDefault.java
index de00ff375..9f3cf871a 100644
--- a/src/main/java/nl/tudelft/tam/model/CoordinatorDefault.java
+++ b/src/main/java/nl/tudelft/tam/model/CoordinatorDefault.java
@@ -59,4 +59,6 @@ public class CoordinatorDefault {
 
 	private String coordinatorContractEmail;
 
+	private String coordinatorNotificationEmail;
+
 }
diff --git a/src/main/java/nl/tudelft/tam/service/CoordinatorDefaultService.java b/src/main/java/nl/tudelft/tam/service/CoordinatorDefaultService.java
index 66b3855f4..e67bd080e 100644
--- a/src/main/java/nl/tudelft/tam/service/CoordinatorDefaultService.java
+++ b/src/main/java/nl/tudelft/tam/service/CoordinatorDefaultService.java
@@ -71,7 +71,8 @@ public class CoordinatorDefaultService {
 					.contractBaanCode("").build();
 			CoordinatorDefault coordinatorDefault = CoordinatorDefault.builder().programId(id)
 					.jobOfferDefault(jobOfferDefault).extraWorkDefault(extraWorkDefault)
-					.coordinatorContractEmail("").coordinatorContractName("").build();
+					.coordinatorContractEmail("").coordinatorNotificationEmail("").coordinatorContractName("")
+					.build();
 			return repository.save(coordinatorDefault);
 		}
 	}
@@ -127,6 +128,7 @@ public class CoordinatorDefaultService {
 						.build())
 				.coordinatorContractName(cd.getCoordinatorContractName())
 				.coordinatorContractEmail(cd.getCoordinatorContractEmail())
+				.coordinatorNotificationEmail(cd.getCoordinatorNotificationEmail())
 				.build();
 	}
 }
diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties
index 0fb938317..b9f6700d2 100644
--- a/src/main/resources/messages.properties
+++ b/src/main/resources/messages.properties
@@ -438,6 +438,8 @@ coordinator.defaults.coordinatorContractName = Coordinator Contract Name
 coordinator.defaults.coordinatorContractName.enter = Enter the coordinator name for contracts...
 coordinator.defaults.coordinatorContractEmail = Coordinator Contract Email
 coordinator.defaults.coordinatorContractEmail.enter = Enter the coordinator's email for contracts...
+coordinator.defaults.coordinatorNotificationEmail = Coordinator Notification Email
+coordinator.defaults.coordinatorNotificationEmail.enter = Enter the coordinator's email for notifications from TAM...
 # Defaults - Job Offers / Extra Work
 coordinator.defaults.contractName = Contract Name
 coordinator.defaults.contractBaan = Baan Code
diff --git a/src/main/resources/migrations.yaml b/src/main/resources/migrations.yaml
index 7cd384dd8..c762ec019 100644
--- a/src/main/resources/migrations.yaml
+++ b/src/main/resources/migrations.yaml
@@ -515,8 +515,7 @@ databaseChangeLog:
                 type: BOOLEAN
                 defaultValueBoolean: true
           tableName: job_offer
-
- # Batches for declarations
+# Batches for declarations
 - changeSet:
     id: 1700147047216-1
     author: ruben (generated)
@@ -606,8 +605,6 @@ databaseChangeLog:
           referencedColumnNames: id
           referencedTableName: declaration
           validate: true
-
-
 # Adding AcademicLevel and AcademicPeriod
 - changeSet:
     id: academicLevelAndPeriod-1
@@ -659,4 +656,15 @@ databaseChangeLog:
     author: Timur
     changes:
       - sql:
-          sql: "UPDATE job_offer SET period = APFROMDATES(contract_start_date, contract_end_date) WHERE period = 0;"
\ No newline at end of file
+          sql: "UPDATE job_offer SET period = APFROMDATES(contract_start_date, contract_end_date) WHERE period = 0;"
+# Adding Coordinator Notification Email
+- changeSet:
+    id: coordinatorNotificationEmail-1
+    author: Timur
+    changes:
+      - addColumn:
+          columns:
+            - column:
+                name: coordinator_notification_email
+                type: VARCHAR(255)
+          tableName: coordinator_default
\ No newline at end of file
diff --git a/src/main/resources/templates/coordinator/defaults.html b/src/main/resources/templates/coordinator/defaults.html
index fd3ef4abc..d4121f5ae 100644
--- a/src/main/resources/templates/coordinator/defaults.html
+++ b/src/main/resources/templates/coordinator/defaults.html
@@ -78,6 +78,19 @@
                         th:field="*{coordinatorContractEmail}"
                         data-style="variant"
                         class="textfield" />
+
+                    <label
+                        for="default-coordinator-notification-email"
+                        th:text="#{coordinator.defaults.coordinatorNotificationEmail}"></label>
+                    <input
+                        id="default-coordinator-notification-email"
+                        th:name="coordinatorNotificationEmail"
+                        th:placeholder="#{coordinator.defaults.coordinatorNotificationEmail.enter}"
+                        type="text"
+                        th:form="patch-form"
+                        th:field="*{coordinatorNotificationEmail}"
+                        data-style="variant"
+                        class="textfield" />
                 </div>
             </div>
 
diff --git a/src/test/java/nl/tudelft/tam/service/CoordinatorDefaultServiceTest.java b/src/test/java/nl/tudelft/tam/service/CoordinatorDefaultServiceTest.java
index 4811664f8..3328289e5 100644
--- a/src/test/java/nl/tudelft/tam/service/CoordinatorDefaultServiceTest.java
+++ b/src/test/java/nl/tudelft/tam/service/CoordinatorDefaultServiceTest.java
@@ -101,6 +101,7 @@ public class CoordinatorDefaultServiceTest {
 								ExtraWorkDefault.builder().contractBaanCode("").contractName("").build())
 						.coordinatorContractName("")
 						.coordinatorContractEmail("")
+						.coordinatorNotificationEmail("")
 						.build());
 	}
 
@@ -133,7 +134,8 @@ public class CoordinatorDefaultServiceTest {
 				"patched baan EW", date);
 
 		CoordinatorDefaultPatchDTO patchDto = new CoordinatorDefaultPatchDTO(joPatchDto, ewPatchDto,
-				"patched coordinator name", "patched coordinator email");
+				"patched coordinator name", "patched coordinator email",
+				"patched coordinator notification email");
 
 		CoordinatorDefault prev = service.findByIdOrThrow(CSE_DEFAULT_ID);
 
@@ -150,6 +152,8 @@ public class CoordinatorDefaultServiceTest {
 		assertThat(prev.getExtraWorkDefault().getDeclarationDeadline()).isNotEqualTo(date);
 		assertThat(prev.getCoordinatorContractName()).isNotEqualTo("patched coordinator name");
 		assertThat(prev.getCoordinatorContractEmail()).isNotEqualTo("patched coordinator email");
+		assertThat(prev.getCoordinatorNotificationEmail())
+				.isNotEqualTo("patched coordinator notification email");
 
 		service.patchCoordinatorDefault(CSE_DEFAULT_ID, patchDto);
 
@@ -168,6 +172,8 @@ public class CoordinatorDefaultServiceTest {
 		assertThat(post.getExtraWorkDefault().getDeclarationDeadline()).isEqualTo(date);
 		assertThat(post.getCoordinatorContractName()).isEqualTo("patched coordinator name");
 		assertThat(post.getCoordinatorContractEmail()).isEqualTo("patched coordinator email");
+		assertThat(post.getCoordinatorNotificationEmail())
+				.isEqualTo("patched coordinator notification email");
 	}
 
 }
-- 
GitLab