UpcomingBirthdayEmailHandler.java
package uk.gov.dhsc.htbhf.claimant.communications;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import uk.gov.dhsc.htbhf.claimant.entitlement.PaymentCycleEntitlementCalculator;
import uk.gov.dhsc.htbhf.claimant.entitlement.PaymentCycleVoucherEntitlement;
import uk.gov.dhsc.htbhf.claimant.entity.Claim;
import uk.gov.dhsc.htbhf.claimant.entity.PaymentCycle;
import uk.gov.dhsc.htbhf.claimant.message.MessageQueueClient;
import uk.gov.dhsc.htbhf.claimant.message.MessageType;
import uk.gov.dhsc.htbhf.claimant.message.payload.EmailMessagePayload;
import uk.gov.dhsc.htbhf.claimant.message.payload.EmailType;
import uk.gov.dhsc.htbhf.claimant.message.processor.NextPaymentCycleSummary;
import java.time.Duration;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static uk.gov.dhsc.htbhf.claimant.communications.MessagePayloadUtils.formatPaymentAmountSummary;
import static uk.gov.dhsc.htbhf.claimant.message.EmailTemplateKey.CHILDREN_UNDER_1_PAYMENT;
import static uk.gov.dhsc.htbhf.claimant.message.EmailTemplateKey.CHILDREN_UNDER_4_PAYMENT;
import static uk.gov.dhsc.htbhf.claimant.message.EmailTemplateKey.MULTIPLE_CHILDREN;
import static uk.gov.dhsc.htbhf.claimant.message.EmailTemplateKey.PAYMENT_AMOUNT;
import static uk.gov.dhsc.htbhf.claimant.message.MoneyUtils.convertPenceToPounds;
/**
* Component responsible for determining if any additional emails need to be sent out in addition to
* the normal Payment email for a given PaymentCycle.
*/
@Component
@Slf4j
public class UpcomingBirthdayEmailHandler {
private final Integer numberOfCalculationPeriods;
private final Duration changeInPaymentEmailDelay;
private final MessageQueueClient messageQueueClient;
private final PaymentCycleEntitlementCalculator paymentCycleEntitlementCalculator;
private final EmailMessagePayloadFactory emailMessagePayloadFactory;
public UpcomingBirthdayEmailHandler(@Value("${payment-cycle.number-of-calculation-periods}") Integer numberOfCalculationPeriods,
@Value("${payment-cycle.change-in-payment-email-delay}") Duration changeInPaymentEmailDelay,
MessageQueueClient messageQueueClient,
PaymentCycleEntitlementCalculator paymentCycleEntitlementCalculator,
EmailMessagePayloadFactory emailMessagePayloadFactory) {
this.numberOfCalculationPeriods = numberOfCalculationPeriods;
this.changeInPaymentEmailDelay = changeInPaymentEmailDelay;
this.messageQueueClient = messageQueueClient;
this.paymentCycleEntitlementCalculator = paymentCycleEntitlementCalculator;
this.emailMessagePayloadFactory = emailMessagePayloadFactory;
}
public void sendChildTurnsFourEmail(PaymentCycle paymentCycle, NextPaymentCycleSummary dateOfBirthSummaryAffectingNextPayment) {
PaymentCycleVoucherEntitlement entitlement = determineEntitlementForNextCycle(paymentCycle);
boolean multipleChildrenTurningFourInNextMonth = dateOfBirthSummaryAffectingNextPayment.hasMultipleChildrenTurningFour();
EmailMessagePayload messagePayload = buildChildTurnsAgeNotificationEmailPayload(paymentCycle,
entitlement, multipleChildrenTurningFourInNextMonth, EmailType.CHILD_TURNS_FOUR);
log.debug("Sending email for child turns 4 for Payment Cycle after cycle with id: [{}], with a delay of {}",
paymentCycle.getId(), changeInPaymentEmailDelay);
messageQueueClient.sendMessageWithDelay(messagePayload, MessageType.SEND_EMAIL, changeInPaymentEmailDelay);
}
public void sendChildTurnsOneEmail(PaymentCycle paymentCycle, NextPaymentCycleSummary dateOfBirthSummaryAffectingNextPayment) {
PaymentCycleVoucherEntitlement entitlement = determineEntitlementForNextCycle(paymentCycle);
boolean multipleChildrenTurningOneInNextMonth = dateOfBirthSummaryAffectingNextPayment.hasMultipleChildrenTurningOne();
EmailMessagePayload messagePayload = buildChildTurnsAgeNotificationEmailPayload(paymentCycle,
entitlement, multipleChildrenTurningOneInNextMonth, EmailType.CHILD_TURNS_ONE);
log.debug("Sending email for child turns 1 for Payment Cycle after cycle with id: [{}], with a delay of {}",
paymentCycle.getId(), changeInPaymentEmailDelay);
messageQueueClient.sendMessageWithDelay(messagePayload, MessageType.SEND_EMAIL, changeInPaymentEmailDelay);
}
public void sendPaymentStoppingYoungestChildTurnsFourEmail(PaymentCycle paymentCycle, NextPaymentCycleSummary dateOfBirthSummaryAffectingNextPayment) {
boolean multipleChildrenTurningFourInNextMonth = dateOfBirthSummaryAffectingNextPayment.hasMultipleChildrenTurningFour();
EmailMessagePayload messagePayload = buildPaymentStoppingNotificationEmailPayload(paymentCycle,
multipleChildrenTurningFourInNextMonth);
log.debug("Sending email for payment stopping when youngest child turns 4 for Payment Cycle after cycle with id: [{}], with a delay of {}",
paymentCycle.getId(), changeInPaymentEmailDelay);
messageQueueClient.sendMessageWithDelay(messagePayload, MessageType.SEND_EMAIL, changeInPaymentEmailDelay);
}
private EmailMessagePayload buildChildTurnsAgeNotificationEmailPayload(PaymentCycle paymentCycle,
PaymentCycleVoucherEntitlement entitlementNextMonth,
boolean multipleChildrenTurningAgeInMonth,
EmailType emailType) {
Map<String, Object> emailPersonalisation = createEmailPersonalisationMapForNextCycle(paymentCycle, entitlementNextMonth);
emailPersonalisation.put(MULTIPLE_CHILDREN.getTemplateKeyName(), multipleChildrenTurningAgeInMonth);
return buildEmailMessagePayload(paymentCycle, emailType, emailPersonalisation);
}
private EmailMessagePayload buildPaymentStoppingNotificationEmailPayload(PaymentCycle paymentCycle,
boolean multipleChildrenTurningAgeInMonth) {
Map<String, Object> emailPersonalisation = new HashMap<>();
String paymentAmount = convertPenceToPounds(paymentCycle.getVoucherEntitlement().getTotalVoucherValueInPence());
emailPersonalisation.put(PAYMENT_AMOUNT.getTemplateKeyName(), paymentAmount);
emailPersonalisation.put(MULTIPLE_CHILDREN.getTemplateKeyName(), multipleChildrenTurningAgeInMonth);
return buildEmailMessagePayload(paymentCycle, EmailType.PAYMENT_STOPPING, emailPersonalisation);
}
private EmailMessagePayload buildEmailMessagePayload(PaymentCycle paymentCycle, EmailType emailType, Map<String, Object> emailPersonalisation) {
return EmailMessagePayload.builder()
.claimId(paymentCycle.getClaim().getId())
.emailType(emailType)
.emailPersonalisation(emailPersonalisation)
.build();
}
private Map<String, Object> createEmailPersonalisationMapForNextCycle(PaymentCycle paymentCycle, PaymentCycleVoucherEntitlement voucherEntitlement) {
Map<String, Object> emailPersonalisation = emailMessagePayloadFactory.createCommonEmailPersonalisationMap(paymentCycle, voucherEntitlement);
emailPersonalisation.put(CHILDREN_UNDER_1_PAYMENT.getTemplateKeyName(), buildUnder1PaymentSummaryForNextCycle(voucherEntitlement));
emailPersonalisation.put(CHILDREN_UNDER_4_PAYMENT.getTemplateKeyName(), buildUnder4PaymentSummaryForNextCycle(voucherEntitlement));
return emailPersonalisation;
}
private String buildUnder4PaymentSummaryForNextCycle(PaymentCycleVoucherEntitlement voucherEntitlement) {
int vouchersForBetweenOneAndFourForFinalWeek = voucherEntitlement.getLastVoucherEntitlementForCycle().getVouchersForChildrenBetweenOneAndFour();
int totalVouchersForChildrenUnderOne = vouchersForBetweenOneAndFourForFinalWeek * numberOfCalculationPeriods;
return formatPaymentAmountSummary(
"\n* %s for children between 1 and 4",
totalVouchersForChildrenUnderOne,
voucherEntitlement.getSingleVoucherValueInPence());
}
private String buildUnder1PaymentSummaryForNextCycle(PaymentCycleVoucherEntitlement voucherEntitlement) {
int vouchersForUnderOneForFinalWeek = voucherEntitlement.getLastVoucherEntitlementForCycle().getVouchersForChildrenUnderOne();
int totalVouchersForChildrenUnderOne = vouchersForUnderOneForFinalWeek * numberOfCalculationPeriods;
return formatPaymentAmountSummary(
"\n* %s for children under 1",
totalVouchersForChildrenUnderOne,
voucherEntitlement.getSingleVoucherValueInPence());
}
private PaymentCycleVoucherEntitlement determineEntitlementForNextCycle(PaymentCycle currentPaymentCycle) {
LocalDate nextCycleStartDate = currentPaymentCycle.getCycleEndDate().plusDays(1);
Claim claim = currentPaymentCycle.getClaim();
return paymentCycleEntitlementCalculator.calculateEntitlement(
Optional.ofNullable(claim.getClaimant().getExpectedDeliveryDate()),
currentPaymentCycle.getChildrenDob(),
nextCycleStartDate,
currentPaymentCycle.getVoucherEntitlement(),
claim.getCurrentIdentityAndEligibilityResponse().getQualifyingReason());
}
}