DetermineEntitlementMessageProcessor.java
package uk.gov.dhsc.htbhf.claimant.message.processor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import uk.gov.dhsc.htbhf.claimant.eligibility.EligibilityDecisionHandler;
import uk.gov.dhsc.htbhf.claimant.entity.Claim;
import uk.gov.dhsc.htbhf.claimant.entity.Message;
import uk.gov.dhsc.htbhf.claimant.entity.PaymentCycle;
import uk.gov.dhsc.htbhf.claimant.message.MessageStatus;
import uk.gov.dhsc.htbhf.claimant.message.MessageType;
import uk.gov.dhsc.htbhf.claimant.message.MessageTypeProcessor;
import uk.gov.dhsc.htbhf.claimant.message.context.DetermineEntitlementMessageContext;
import uk.gov.dhsc.htbhf.claimant.message.context.MessageContextLoader;
import uk.gov.dhsc.htbhf.claimant.model.eligibility.EligibilityAndEntitlementDecision;
import uk.gov.dhsc.htbhf.claimant.service.EligibilityAndEntitlementService;
import uk.gov.dhsc.htbhf.claimant.service.claim.ClaimService;
import uk.gov.dhsc.htbhf.claimant.service.payments.PaymentCycleService;
import java.time.LocalDateTime;
import java.time.Period;
import javax.transaction.Transactional;
import static uk.gov.dhsc.htbhf.claimant.message.MessageStatus.COMPLETED;
import static uk.gov.dhsc.htbhf.claimant.message.MessageType.DETERMINE_ENTITLEMENT;
import static uk.gov.dhsc.htbhf.claimant.model.ClaimStatus.ACTIVE;
import static uk.gov.dhsc.htbhf.claimant.model.ClaimStatus.PENDING_EXPIRY;
import static uk.gov.dhsc.htbhf.eligibility.model.EligibilityStatus.ELIGIBLE;
@Slf4j
@Component
public class DetermineEntitlementMessageProcessor implements MessageTypeProcessor {
private final Period maximumPendingExpiryDuration;
private final EligibilityAndEntitlementService eligibilityAndEntitlementService;
private final MessageContextLoader messageContextLoader;
private final PaymentCycleService paymentCycleService;
private final EligibilityDecisionHandler eligibilityDecisionHandler;
private final ClaimService claimService;
public DetermineEntitlementMessageProcessor(
@Value("${payment-cycle.maximum-pending-expiry-duration}") Period maximumPendingExpiryDuration,
EligibilityAndEntitlementService eligibilityAndEntitlementService,
MessageContextLoader messageContextLoader,
PaymentCycleService paymentCycleService,
EligibilityDecisionHandler eligibilityDecisionHandler,
ClaimService claimService) {
this.maximumPendingExpiryDuration = maximumPendingExpiryDuration;
this.eligibilityAndEntitlementService = eligibilityAndEntitlementService;
this.messageContextLoader = messageContextLoader;
this.paymentCycleService = paymentCycleService;
this.eligibilityDecisionHandler = eligibilityDecisionHandler;
this.claimService = claimService;
}
@Override
public MessageType supportsMessageType() {
return DETERMINE_ENTITLEMENT;
}
/**
* Processes DETERMINE_ENTITLEMENT messages from the message queue by determining the eligibility and entitlement of the
* claimant for the current Payment Cycle. The entitlement and eligibility are then persisted to the current Payment Cycle.
*
* @param message The message to process.
* @return The message status on completion
*/
@Override
@Transactional(Transactional.TxType.REQUIRES_NEW)
public MessageStatus processMessage(Message message) {
DetermineEntitlementMessageContext messageContext = messageContextLoader.loadDetermineEntitlementContext(message);
Claim claim = messageContext.getClaim();
PaymentCycle currentPaymentCycle = messageContext.getCurrentPaymentCycle();
PaymentCycle previousPaymentCycle = messageContext.getPreviousPaymentCycle();
EligibilityAndEntitlementDecision decision = eligibilityAndEntitlementService.evaluateClaimantForPaymentCycle(
claim,
currentPaymentCycle.getCycleStartDate(),
previousPaymentCycle);
paymentCycleService.updatePaymentCycleFromDecision(currentPaymentCycle, decision);
claimService.updateCurrentIdentityAndEligibilityResponse(claim, decision.getIdentityAndEligibilityResponse());
handleDecision(claim, previousPaymentCycle, currentPaymentCycle, decision, message.getCreatedTimestamp());
if (claim.getClaimStatus() == PENDING_EXPIRY) {
paymentCycleService.updateEndDateForClaimBecomingPendingExpiry(currentPaymentCycle);
}
return COMPLETED;
}
private void handleDecision(Claim claim,
PaymentCycle previousPaymentCycle,
PaymentCycle currentPaymentCycle,
EligibilityAndEntitlementDecision decision,
LocalDateTime messageTimestamp) {
if (decision.getEligibilityStatus() == ELIGIBLE) {
eligibilityDecisionHandler.handleEligibleDecision(claim, currentPaymentCycle);
} else if (claim.getClaimStatus() == ACTIVE) {
eligibilityDecisionHandler.handleIneligibleDecisionForActiveClaim(claim, previousPaymentCycle, currentPaymentCycle, decision);
} else if (claimHasBeenPendingExpiryForLongerThanTheMaximumDuration(claim, messageTimestamp)) {
eligibilityDecisionHandler.expirePendingExpiryClaim(claim, decision.getIdentityAndEligibilityResponse());
}
}
private boolean claimHasBeenPendingExpiryForLongerThanTheMaximumDuration(Claim claim, LocalDateTime messageTimestamp) {
// !isAfter has the same effect as (isBefore || isEqual). Unfortunately isBeforeOrEqual does not exist on LocalDateTime.
return claim.getClaimStatus() == PENDING_EXPIRY
&& !claim.getClaimStatusTimestamp().isAfter(messageTimestamp.minus(maximumPendingExpiryDuration));
}
}