Skip to content

Commit 291027d

Browse files
committed
Send self-review emails at launch, 3 days to close, and 1 day to close.
1 parent 5fcb464 commit 291027d

File tree

5 files changed

+160
-2
lines changed

5 files changed

+160
-2
lines changed

server/src/main/java/com/objectcomputing/checkins/services/request_notifications/CheckServicesImpl.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequest;
44
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequestRepository;
55
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequestServicesImpl;
6+
import com.objectcomputing.checkins.services.reviews.ReviewPeriodServices;
67
import com.objectcomputing.checkins.services.pulse.PulseServices;
78
import jakarta.inject.Singleton;
89
import org.slf4j.Logger;
@@ -18,13 +19,16 @@ public class CheckServicesImpl implements CheckServices {
1819
private final FeedbackRequestServicesImpl feedbackRequestServices;
1920
private final FeedbackRequestRepository feedbackRequestRepository;
2021
private final PulseServices pulseServices;
22+
private final ReviewPeriodServices reviewPeriodServices;
2123

2224
public CheckServicesImpl(FeedbackRequestServicesImpl feedbackRequestServices,
2325
FeedbackRequestRepository feedbackRequestRepository,
24-
PulseServices pulseServices) {
26+
PulseServices pulseServices,
27+
ReviewPeriodServices reviewPeriodServices) {
2528
this.feedbackRequestServices = feedbackRequestServices;
2629
this.feedbackRequestRepository = feedbackRequestRepository;
2730
this.pulseServices = pulseServices;
31+
this.reviewPeriodServices = reviewPeriodServices;
2832
}
2933

3034
@Override
@@ -38,6 +42,7 @@ public boolean sendScheduledEmails() {
3842
feedbackRequestRepository.update(req);
3943
}
4044
pulseServices.sendPendingEmail(today);
45+
reviewPeriodServices.sendNotifications(today);
4146
return true;
4247
}
4348

server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodServices.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.objectcomputing.checkins.services.reviews;
22

3+
import java.time.LocalDate;
34
import java.util.Set;
45
import java.util.UUID;
56

@@ -14,4 +15,6 @@ public interface ReviewPeriodServices {
1415
Set<ReviewPeriod> findByValue(String name, ReviewStatus reviewStatus);
1516

1617
void delete(UUID id);
18+
19+
void sendNotifications(LocalDate today);
1720
}

server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodServicesImpl.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
import java.util.Set;
2929
import java.util.UUID;
3030
import java.util.stream.Collectors;
31+
import java.util.Map;
32+
import java.util.HashMap;
3133
import java.io.BufferedReader;
34+
import java.time.temporal.ChronoUnit;
3235

3336
@Singleton
3437
class ReviewPeriodServicesImpl implements ReviewPeriodServices {
@@ -44,10 +47,15 @@ class ReviewPeriodServicesImpl implements ReviewPeriodServices {
4447
private final Environment environment;
4548
private final String webAddress;
4649

50+
private enum SelfReviewDate { LAUNCH, THREE_DAYS, ONE_DAY }
51+
private final Map<String, Boolean> sent = new HashMap<>();
52+
4753
@Value("classpath:mjml/supervisor_review_assignment.mjml")
4854
private Readable supervisorReviewAssignmentTemplate;
4955
@Value("classpath:mjml/review_period_announcement.mjml")
5056
private Readable reviewPeriodAnnouncementTemplate;
57+
@Value("classpath:mjml/self_review_reminder.mjml")
58+
private Readable selfReviewReminderTemplate;
5159

5260
ReviewPeriodServicesImpl(ReviewPeriodRepository reviewPeriodRepository,
5361
ReviewAssignmentRepository reviewAssignmentRepository,
@@ -346,4 +354,108 @@ private void createReviewRequest(ReviewPeriod period,
346354
LOG.error(ex.toString());
347355
}
348356
}
357+
358+
public void sendNotifications(LocalDate today) {
359+
List<ReviewPeriod> openPeriods =
360+
reviewPeriodRepository.findByReviewStatus(ReviewStatus.OPEN);
361+
for(ReviewPeriod openPeriod : openPeriods) {
362+
for(SelfReviewDate date : SelfReviewDate.values()) {
363+
String key = openPeriod.getId().toString() + date.toString();
364+
if (!sent.containsKey(key)) {
365+
LocalDateTime check;
366+
switch(date) {
367+
case SelfReviewDate.LAUNCH:
368+
check = openPeriod.getLaunchDate();
369+
break;
370+
case SelfReviewDate.THREE_DAYS:
371+
check = openPeriod.getSelfReviewCloseDate();
372+
if (check != null) {
373+
check = check.minus(3, ChronoUnit.DAYS);
374+
}
375+
break;
376+
default:
377+
case SelfReviewDate.ONE_DAY:
378+
check = openPeriod.getSelfReviewCloseDate();
379+
if (check != null) {
380+
check = check.minus(1, ChronoUnit.DAYS);
381+
}
382+
break;
383+
}
384+
385+
if (check != null) {
386+
if (today.isEqual(check.toLocalDate())) {
387+
sendSelfReviewEmail(openPeriod.getId(), date);
388+
sent.put(key, true);
389+
}
390+
}
391+
}
392+
}
393+
}
394+
}
395+
396+
void sendSelfReviewEmail(UUID reviewPeriodId, SelfReviewDate date) {
397+
Optional<ReviewPeriod> reviewPeriod =
398+
reviewPeriodRepository.findById(reviewPeriodId);
399+
if (reviewPeriod.isEmpty()) {
400+
LOG.error("Unable to find review period: " + reviewPeriodId.toString());
401+
return;
402+
}
403+
404+
// Determine which email template and subject we need to use.
405+
String subject = "";
406+
switch(date) {
407+
case SelfReviewDate.LAUNCH:
408+
subject = reviewPeriod.get().getName() + " has launched!";
409+
break;
410+
case SelfReviewDate.THREE_DAYS:
411+
subject = reviewPeriod.get().getName() +
412+
" closes in three days!";
413+
break;
414+
default:
415+
case SelfReviewDate.ONE_DAY:
416+
subject = reviewPeriod.get().getName() + " closes in one day!";
417+
break;
418+
}
419+
420+
try {
421+
// Read in the email template.
422+
String template = IOUtils.readText(
423+
new BufferedReader(
424+
selfReviewReminderTemplate.asReader()));
425+
426+
// Get the set of self-reviewer email addresses.
427+
Set<MemberProfile> recipients = new HashSet<>();
428+
List<FeedbackRequest> requests =
429+
feedbackRequestServices.findByValues(null, null, null, null,
430+
reviewPeriodId,
431+
null, null);
432+
for (FeedbackRequest request : requests) {
433+
if (request.getRecipientId().equals(request.getRequesteeId())) {
434+
Optional<MemberProfile> requesteeProfile =
435+
memberProfileRepository.findById(
436+
request.getRequesteeId());
437+
if (!requesteeProfile.isEmpty()) {
438+
recipients.add(requesteeProfile.get());
439+
}
440+
}
441+
}
442+
443+
for(MemberProfile recipient : recipients) {
444+
// Customize the email content using the template.
445+
String content = String.format(template,
446+
webAddress,
447+
reviewPeriodId.toString(),
448+
recipient.getFirstName(),
449+
dateAsString(reviewPeriod.get()
450+
.getSelfReviewCloseDate()),
451+
webAddress);
452+
453+
// Send out the email to the individual.
454+
emailSender.sendEmail(null, null, subject, content,
455+
recipient.getWorkEmail());
456+
}
457+
} catch(Exception ex) {
458+
LOG.error("Send Self-Review Email: " + ex.toString());
459+
}
460+
}
349461
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<mjml>
2+
<mj-head>
3+
<mj-title>Self-Review Reminder</mj-title>
4+
<mj-preview>Self-Reviews are due soon!</mj-preview>
5+
<mj-attributes>
6+
<mj-class name="preheader" color="#000000" font-size="11px" font-family="Ubuntu, Helvetica, Arial, sans-serif" padding="0px"></mj-class>
7+
</mj-attributes>
8+
</mj-head>
9+
<mj-body background-color="#e0f2ff">
10+
<mj-section background-color="#2559a7">
11+
<mj-column>
12+
<mj-image src="https://objectcomputing.com/files/6416/4277/8012/ObjectComputingLogo_version2_white.png" alt="logo" width="150px"></mj-image>
13+
</mj-column>
14+
</mj-section>
15+
<mj-hero mode="fluid-height" background-url="https://lh3.googleusercontent.com/pw/AL9nZEXvzBSrNroLHtqfW8W5_oM296XY7FPJqz15RNP3RBcf_XEkyZ0gn5JVkDCSTWA-loYTeVL5c-ycoAEOh_3dFBpPju1UmfGt7tLPCMFQdf5IVeHipmhyOV4fZnCWSl0n-b3tsHB4THfub4Mtknvz8R4t=w900-h600-no" background-color="#FFF" padding="100px 0px">
16+
<mj-text padding="20px" font-family="Helvetica" align="center" font-size="45px" line-height="45px" font-weight="900"> If you haven't already... </mj-text>
17+
<mj-button href="%s/feedback/self-reviews?period=%s" align="center"> FILL OUT YOUR<br/>SELF-REVIEW </mj-button>
18+
</mj-hero>
19+
<mj-section background-color="#ffffff">
20+
<mj-column>
21+
<mj-text>
22+
<h2>Self-Review Reminder!</h2>
23+
</mj-text>
24+
<mj-text font-size="16px">Dear %s,</mj-text>
25+
<mj-text font-size="16px">This is a friendly reminder to complete your self-reviews by %s. <strong></strong></mj-text>
26+
<mj-text font-size="16px">To access your self-review click the button above, or visit <a href="%s">Check-Ins</a> and find "Self-Reviews" under the "Feedback" menu.</mj-text>
27+
</mj-column>
28+
</mj-section>
29+
<mj-section background-color="#feb672" padding="10px">
30+
<mj-column vertical-align="top" width="100%%">
31+
<mj-text align="center" color="#FFF" font-size="16px">Thank you for everything you do!</mj-text>
32+
</mj-column>
33+
</mj-section>
34+
</mj-body>
35+
</mjml>

server/src/test/java/com/objectcomputing/checkins/services/request_notifications/CheckServicesImplTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequestRepository;
66
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequestServicesImpl;
77
import com.objectcomputing.checkins.services.pulse.PulseServices;
8+
import com.objectcomputing.checkins.services.reviews.ReviewPeriodServices;
89
import org.junit.jupiter.api.AfterEach;
910
import org.junit.jupiter.api.BeforeEach;
1011
import org.junit.jupiter.api.Test;
@@ -35,6 +36,9 @@ class CheckServicesImplTest extends TestContainersSuite {
3536
@Mock
3637
private PulseServices pulseServices;
3738

39+
@Mock
40+
private ReviewPeriodServices reviewPeriodServices;
41+
3842
@InjectMocks
3943
private CheckServicesImpl checkServices;
4044

@@ -60,6 +64,5 @@ void sendScheduledEmails() {
6064
verify(feedbackRequestServices).sendNewRequestEmail(retrievedRequest);
6165
retrievedRequest.setStatus("sent");
6266
verify(feedbackRequestRepository).update(retrievedRequest);
63-
6467
}
6568
}

0 commit comments

Comments
 (0)