Skip to content

Commit

Permalink
[CCAP-642] - Sends confirmation email when provider agrees to care (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
analoo authored Feb 20, 2025
1 parent 6f4306e commit c836223
Show file tree
Hide file tree
Showing 13 changed files with 435 additions and 43 deletions.
25 changes: 0 additions & 25 deletions src/main/java/org/ilgcc/app/email/EmailConstants.java

This file was deleted.

54 changes: 54 additions & 0 deletions src/main/java/org/ilgcc/app/email/ILGCCEmail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.ilgcc.app.email;

import lombok.Getter;
import com.sendgrid.helpers.mail.objects.Content;
import com.sendgrid.helpers.mail.objects.Email;
import java.util.UUID;

@Getter
public class ILGCCEmail {

public static final String FROM_ADDRESS = "[email protected]";
public static final String EMAIL_SENDER_KEY = "email.general.sender-name";

private Email senderEmail;
private String subject;
private Content body;
private EmailType emailType;
private UUID submissionId;
private Email recipientEmail;

public ILGCCEmail(String senderName, String recipientAddress, String subject, Content body, EmailType emailType,
UUID submissionId) {
this.senderEmail = new Email(FROM_ADDRESS, senderName);
this.recipientEmail = new Email(recipientAddress);
this.subject = subject;
this.body = body;
this.emailType = emailType;
this.submissionId = submissionId;
}


public static ILGCCEmail createProviderConfirmationEmail(String senderName, String recipientAddress, String subject,
Content body, UUID submissionId) {
return new ILGCCEmail(senderName, recipientAddress, subject, body, EmailType.PROVIDER_CONFIRMATION_EMAIL, submissionId);
}

@Getter
public enum EmailType {
FAMILY_CONFIRMATION_EMAIL("Family Confirmation Email"), FAMILY_CONFIRMATION_EMAIL_NO_PROVIDER(
"No Provider Family Confirmation Email"), PROVIDER_AGREES_TO_CARE_FAMILY_EMAIL(
"Provider Agrees to Care Family Email"), PROVIDER_CONFIRMATION_EMAIL("Provider confirmation email");

private final String description;

EmailType(String description) {
this.description = description;
}

public String getDescription() {
return description;
}
}

}
13 changes: 12 additions & 1 deletion src/main/java/org/ilgcc/app/email/SendGridEmailService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class SendGridEmailService {
private final SendGrid sendGrid = new SendGrid(System.getenv("SENDGRID_API_KEY"));

public Response sendEmail(String recipientAddress, String senderName, String subject, Content content) throws IOException {
Email senderEmail = new Email(EmailConstants.FROM_ADDRESS, senderName);
Email senderEmail = new Email(ILGCCEmail.FROM_ADDRESS, senderName);
Email recipientEmail = new Email(recipientAddress);
Mail mail = new Mail(senderEmail, subject, recipientEmail, content);
Request request = new Request();
Expand All @@ -31,4 +31,15 @@ public Response sendEmail(String recipientAddress, String senderName, String sub

return sendGrid.api(request);
}

public Response sendEmail(ILGCCEmail ilgccEmail) throws IOException {
Mail mail = new Mail(ilgccEmail.getSenderEmail(), ilgccEmail.getSubject(), ilgccEmail.getRecipientEmail(),
ilgccEmail.getBody());
Request request = new Request();
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());

return sendGrid.api(request);
}
}
2 changes: 2 additions & 0 deletions src/main/java/org/ilgcc/app/inputs/Providerresponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,6 @@ public class Providerresponse extends FlowInputs {
// registration-signature
@NotBlank(message = "{errors.validate.provider-signed-name}")
private String providerSignedName;

private String providerConfirmationEmailSent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import formflow.library.data.SubmissionRepositoryService;
import java.util.Locale;
import lombok.extern.slf4j.Slf4j;
import org.ilgcc.app.email.EmailConstants;
import org.ilgcc.app.email.ILGCCEmail;
import org.ilgcc.app.utils.SubmissionUtilities;
import org.ilgcc.jobs.SendEmailJob;
import org.springframework.context.MessageSource;
Expand Down Expand Up @@ -52,7 +52,7 @@ public void run(Submission familySubmission) {
String senderName = messageSource.getMessage("email.general.sender-name", null, locale);

sendEmailJob.enqueueSendEmailJob(familyEmail, senderName, subject,
EmailConstants.EmailType.FAMILY_CONFIRMATION_EMAIL.getDescription(),
ILGCCEmail.EmailType.FAMILY_CONFIRMATION_EMAIL.getDescription(),
createFamilyConfirmationEmailBody(familySubmission, familySubmissionShortCode, locale), familySubmission);
familySubmission.getInputData().put("familyConfirmationEmailSent", "true");
submissionRepositoryService.save(familySubmission);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.ilgcc.app.submission.actions;

import static org.ilgcc.app.utils.ProviderSubmissionUtilities.formatListIntoReadableString;
import static org.ilgcc.app.utils.ProviderSubmissionUtilities.getChildrenInitialsListFromApplication;

import com.sendgrid.helpers.mail.objects.Content;
import formflow.library.config.submission.Action;
import formflow.library.data.FormSubmission;
Expand All @@ -9,7 +12,7 @@
import java.util.Optional;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.ilgcc.app.email.EmailConstants;
import org.ilgcc.app.email.ILGCCEmail;
import org.ilgcc.app.utils.ProviderSubmissionUtilities;
import org.ilgcc.jobs.SendEmailJob;
import org.springframework.context.MessageSource;
Expand Down Expand Up @@ -74,7 +77,7 @@ public void run(FormSubmission formSubmission, Submission providerSubmission) {
Content body = createProviderResponseConfirmationEmailBody(providerSubmission, familySubmission, familySubmissionConfirmationId, locale);

sendEmailJob.enqueueSendEmailJob(familyEmailAddress, senderName, subject,
EmailConstants.EmailType.PROVIDER_AGREES_TO_CARE_FAMILY_EMAIL.getDescription(),
ILGCCEmail.EmailType.PROVIDER_AGREES_TO_CARE_FAMILY_EMAIL.getDescription(),
body, providerSubmission);
providerSubmission.getInputData().put("providerResponseFamilyConfirmationEmailSent", "true");
submissionRepositoryService.save(providerSubmission);
Expand All @@ -88,8 +91,7 @@ private Content createProviderResponseConfirmationEmailBody(Submission providerS
String p1 = messageSource.getMessage("email.response-email-for-family.provider-agrees.p1", null, locale);
String p2 = providerName.isBlank() ? messageSource.getMessage("email.response-email-for-family.provider-agrees.p2-no-provider-name", new Object[]{ccrrName}, locale) : messageSource.getMessage("email.response-email-for-family.provider-agrees.p2-has-provider-name", new Object[]{providerName, ccrrName}, locale);
String p3 = messageSource.getMessage("email.response-email-for-family.provider-agrees.p3",
new Object[]{
ProviderSubmissionUtilities.getChildrenInitialsFromApplication(familySubmission),
new Object[]{formatListIntoReadableString(getChildrenInitialsListFromApplication(familySubmission), messageSource.getMessage("general.and", null, locale)),
ProviderSubmissionUtilities.getCCAPStartDateFromProviderOrFamilyChildcareStartDate(familySubmission, providerSubmission)
}, locale);
String p4 = messageSource.getMessage("email.response-email-for-family.provider-agrees.p4", new Object[]{confirmationCode}, locale);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package org.ilgcc.app.submission.actions;

import static org.ilgcc.app.utils.ProviderSubmissionUtilities.formatListIntoReadableString;
import static org.ilgcc.app.utils.ProviderSubmissionUtilities.getCombinedDataForEmails;

import com.sendgrid.helpers.mail.objects.Content;
import formflow.library.config.submission.Action;
import formflow.library.data.Submission;
import formflow.library.data.SubmissionRepositoryService;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.ilgcc.app.email.ILGCCEmail;
import org.ilgcc.app.utils.ProviderSubmissionUtilities;
import org.ilgcc.jobs.SendEmailJob;
import org.springframework.context.MessageSource;

@Slf4j
public class SendProviderConfirmationEmail implements Action {

protected static String EMAIL_SENT_STATUS_INPUT_NAME = "providerConfirmationEmailSent";
protected static String RECIPIENT_EMAIL_INPUT_NAME = "providerResponseContactEmail";

protected static MessageSource messageSource;

protected final SubmissionRepositoryService submissionRepositoryService;

protected final SendEmailJob sendEmailJob;

public SendProviderConfirmationEmail(SendEmailJob sendEmailJob, MessageSource messageSource, SubmissionRepositoryService submissionRepositoryService) {
this.sendEmailJob = sendEmailJob;
this.messageSource = messageSource;
this.submissionRepositoryService = submissionRepositoryService;
}

@Override
public void run(Submission submission) {
if (!skipEmailSend(submission)) {
Locale locale =
submission.getInputData().getOrDefault("languageRead", "English").equals("Spanish") ? Locale.forLanguageTag(
"es") : Locale.ENGLISH;
Optional<Map<String, Object>> emailData = getEmailData(submission);

if (emailData.isEmpty()) {
return;
}

ILGCCEmail email = ILGCCEmail.createProviderConfirmationEmail(getSenderName(locale), getRecipientEmail(submission),
setSubject(emailData.get(), locale), new Content("text/html", setBodyCopy(emailData.get(), locale)),
submission.getId());
sendEmail(email, submission);
}
}

protected Boolean skipEmailSend(Submission submission) {
boolean emailSent = submission.getInputData().getOrDefault(EMAIL_SENT_STATUS_INPUT_NAME, "false").equals("true");
boolean providerAgreedToCare = submission.getInputData().getOrDefault("providerResponseAgreeToCare", "false")
.equals("true");

return emailSent || !providerAgreedToCare;
}

protected Optional<Map<String, Object>> getEmailData(Submission providerSubmission) {
Optional<Submission> familySubmission = getFamilyApplication(providerSubmission);
if (familySubmission.isPresent()) {
return Optional.of(getCombinedDataForEmails(providerSubmission, familySubmission.get()));
} else {
log.warn("Could not send Email. No family submission is associated with the providerSubmissionId: {}",
providerSubmission.getId());
return Optional.empty();
}
}

protected static String getSenderName(Locale locale) {
return messageSource.getMessage(ILGCCEmail.EMAIL_SENDER_KEY, null, locale);
}

protected static String getRecipientEmail(Submission submission) {
return submission.getInputData().getOrDefault(RECIPIENT_EMAIL_INPUT_NAME, "").toString();
}

protected String setSubject(Map<String, Object> emailData, Locale locale) {
return messageSource.getMessage("email.family-confirmation.subject", new Object[]{emailData.get("confirmationCode")},
locale);
}

protected String setBodyCopy(Map<String, Object> emailData, Locale locale) {
String p1 = messageSource.getMessage("email.provider-confirmation.p1", null, locale);
String p2 = messageSource.getMessage("email.provider-confirmation.p2", new Object[]{emailData.get("ccrrName")},
locale);
String p3 = messageSource.getMessage("email.provider-confirmation.p3",
new Object[]{formatListIntoReadableString((List<String>) emailData.get("childrenInitialsList"), messageSource.getMessage("general.and", null, locale)), emailData.get("ccapStartDate")}, locale);
String p4 = messageSource.getMessage("email.provider-confirmation.p4",
new Object[]{emailData.get("confirmationCode")}, locale);
String p5 = messageSource.getMessage("email.provider-confirmation.p5",
new Object[]{emailData.get("ccrrName"), emailData.get("ccrrPhoneNumber")},
locale);
String p6 = messageSource.getMessage("email.general.footer.automated-response", null, locale);
String p7 = messageSource.getMessage("email.general.footer.cfa", null, locale);
return p1 + p2 + p3 + p4 + p5 + p6 + p7;
}

protected void sendEmail(ILGCCEmail email, Submission submission) {
sendEmailJob.enqueueSendEmailJob(email);
updateEmailStatus(submission);
}

private void updateEmailStatus(Submission submission) {
submission.getInputData().putIfAbsent(EMAIL_SENT_STATUS_INPUT_NAME, "true");
submissionRepositoryService.save(submission);
}

private Optional<Submission> getFamilyApplication(Submission providerSubmission) {
Optional<UUID> familySubmissionId = ProviderSubmissionUtilities.getClientId(providerSubmission);
if (familySubmissionId.isEmpty()) {
log.warn("No family submission is associated with the provider submission with ID: {}",
providerSubmission.getId());
return Optional.empty();
}

return submissionRepositoryService.findById(familySubmissionId.get());
}
}


55 changes: 44 additions & 11 deletions src/main/java/org/ilgcc/app/utils/ProviderSubmissionUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
@Component
@Slf4j
public class ProviderSubmissionUtilities {

private final static Map<String, Integer> DAY_OF_WEEK_WITH_BUSINESS_DAYS_OFFSET = Map.of(
"MONDAY", 3, "TUESDAY", 3, "WEDNESDAY", 5, "THURSDAY", 5, "FRIDAY", 5, "SATURDAY", 4, "SUNDAY", 3);

Expand Down Expand Up @@ -86,6 +87,22 @@ private static String getApplicantName(Map<String, Object> applicantInputData) {
return String.format("%s %s", firstName, lastName);
}

public static Map<String, Object> getCombinedDataForEmails(Submission providerSubmission, Submission familySubmission) {
Map<String, Object> applicationData = new HashMap<>();

applicationData.put("providerName", getProviderResponseName(providerSubmission));
applicationData.put("ccrrName", (String) familySubmission.getInputData().getOrDefault("ccrrName", ""));
applicationData.put("ccrrPhoneNumber", (String) familySubmission.getInputData().getOrDefault("ccrrPhoneNumber", ""));
applicationData.put("childrenInitialsList",
ProviderSubmissionUtilities.getChildrenInitialsListFromApplication(familySubmission));
applicationData.put("ccapStartDate",
ProviderSubmissionUtilities.getCCAPStartDateFromProviderOrFamilyChildcareStartDate(familySubmission,
providerSubmission));
applicationData.put("confirmationCode", familySubmission.getShortCode());

return applicationData;
}

public static List<Map<String, String>> getChildrenDataForProviderResponse(Submission applicantSubmission) {
List<Map<String, String>> children = new ArrayList<>();

Expand All @@ -104,7 +121,7 @@ public static List<Map<String, String>> getChildrenDataForProviderResponse(Submi
}
return children;
}

public static String formatChildNamesAsCommaSeperatedList(Submission applicantSubmission) {
List<Map<String, Object>> children = SubmissionUtilities.getChildrenNeedingAssistance(applicantSubmission);
List<String> childNames = new ArrayList<>();
Expand Down Expand Up @@ -196,31 +213,47 @@ public static boolean providerApplicationHasExpired(Submission submission, Zoned
todaysDate) > 0;
}

public static String getCCAPStartDateFromProviderOrFamilyChildcareStartDate(Submission familySubmission, Submission providerSubmission) {
public static String getCCAPStartDateFromProviderOrFamilyChildcareStartDate(Submission familySubmission,
Submission providerSubmission) {
String providerCareStartDate = (String) providerSubmission.getInputData().getOrDefault("providerCareStartDate", "");

if (!providerCareStartDate.isBlank()) {
return DateUtilities.convertDateToFullWordMonthPattern(providerCareStartDate);
}else {
String familyEarliestChildcareStartDate = (String) familySubmission.getInputData().getOrDefault("earliestChildcareStartDate", "");
} else {
String familyEarliestChildcareStartDate = (String) familySubmission.getInputData()
.getOrDefault("earliestChildcareStartDate", "");
return DateUtilities.convertDateToFullWordMonthPattern(familyEarliestChildcareStartDate);
}
}
public static String getChildrenInitialsFromApplication(Submission familySubmission) {

public static List<String> getChildrenInitialsListFromApplication(Submission familySubmission) {
List<Map<String, Object>> children = SubmissionUtilities.getChildrenNeedingAssistance(familySubmission);
var childrenInitials = new ArrayList<String>();
if (children.isEmpty()) {
return "";
}
List<String> childrenInitials = new ArrayList<String>();
for (var child : children) {
String firstName = (String) child.get("childFirstName");
String lastName = (String) child.get("childLastName");
childrenInitials.add(String.format("%s.%s.", firstName.toUpperCase().charAt(0), lastName.toUpperCase().charAt(0)));
}
return String.join(", ", childrenInitials);
return childrenInitials;
}

public static String formatListIntoReadableString(List<String> dataList, String joiner) {
if (dataList.isEmpty()) {
return "";
} else if (dataList.size() == 1) {
return dataList.get(0); // Single name, no 'and'
} else if (dataList.size() == 2) {
return String.join(" " + joiner + " ", dataList); // if only 2 elements join with 'and'
} else {
// More than 2 elements in list, use comma for all but the last one
String last = dataList.remove(dataList.size() - 1);
return String.join(", ", dataList) + " " + joiner + " " + last; // Join remaining with commas, append 'and last'
}
}

public static String getProviderResponseName(Submission providerSubmission) {
String providerResponseBusinessName = (String) providerSubmission.getInputData().getOrDefault("providerResponseBusinessName", "");
String providerResponseBusinessName = (String) providerSubmission.getInputData()
.getOrDefault("providerResponseBusinessName", "");
if (!providerResponseBusinessName.isEmpty()) {
return providerResponseBusinessName;
}
Expand Down
Loading

0 comments on commit c836223

Please sign in to comment.