PregnancyEntitlementCalculator.java
package uk.gov.dhsc.htbhf.claimant.entitlement;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import uk.gov.dhsc.htbhf.claimant.entity.PaymentCycle;
import uk.gov.dhsc.htbhf.dwp.model.QualifyingReason;
import java.time.LocalDate;
import static uk.gov.dhsc.htbhf.dwp.model.QualifyingReason.UNDER_18;
/**
* Responsible for deciding whether a claimant is entitled to a voucher for pregnancy,
* by comparing the due date to a given entitlement date.
* There is a grace period after the due date before the claimant stops being eligible for a voucher.
*/
@Component
public class PregnancyEntitlementCalculator {
private final int pregnancyGracePeriodInWeeks;
private final int paymentCycleDurationInDays;
private final int under18PregnancyGracePeriodInWeeks;
public PregnancyEntitlementCalculator(@Value("${entitlement.pregnancy-grace-period-in-weeks}") int pregnancyGracePeriodInWeeks,
@Value("${payment-cycle.cycle-duration-in-days}") int paymentCycleDurationInDays,
@Value("${entitlement.under-eighteen-pregnancy-grace-period-in-weeks}") int under18PregnancyGracePeriodInWeeks) {
this.pregnancyGracePeriodInWeeks = pregnancyGracePeriodInWeeks;
this.paymentCycleDurationInDays = paymentCycleDurationInDays;
this.under18PregnancyGracePeriodInWeeks = under18PregnancyGracePeriodInWeeks;
}
public boolean isEntitledToVoucher(LocalDate dueDate, LocalDate entitlementDate, QualifyingReason qualifyingReason) {
if (entitlementDate == null) {
throw new IllegalArgumentException("entitlementDate must not be null");
}
if (dueDate == null) {
return false;
}
LocalDate endOfGracePeriod;
if (qualifyingReason == UNDER_18) {
endOfGracePeriod = dueDate.plusWeeks(under18PregnancyGracePeriodInWeeks);
} else {
endOfGracePeriod = dueDate.plusWeeks(pregnancyGracePeriodInWeeks);
}
return !endOfGracePeriod.isBefore(entitlementDate);
}
/**
* Determines if the current cycle is the claimant's second to last cycle with pregnancy vouchers. i.e if the current and next payment cycle are
* entitled to pregnancy vouchers, and the one after that is not entitled to vouchers.
* <p>
* Example illustrated below:
* |...|...|...|...| four payment cycles (16 weeks)
* ^ due date
* |...| second to last cycle with pregnancy vouchers
* ^ end of grace period for pregnancy vouchers
* |...| last cycle with pregnancy vouchers
* </p>
* @param currentPaymentCycle the current payment cycle
* @return true if the current and next payment cycle are entitled to pregnancy vouchers, and the one after that is not entitled to vouchers.
*/
public boolean currentCycleIsSecondToLastCycleWithPregnancyVouchers(PaymentCycle currentPaymentCycle) {
LocalDate expectedDeliveryDate = currentPaymentCycle.getExpectedDeliveryDate();
LocalDate cycleStartDate = currentPaymentCycle.getCycleStartDate();
QualifyingReason qualifyingReason = getQualifyingReasonFromCombinedIdentityAndEligibilityResponse(currentPaymentCycle);
boolean entitledToVouchersInCurrentCycle = isEntitledToVoucher(expectedDeliveryDate, cycleStartDate, qualifyingReason);
LocalDate nextCycleStartDate = cycleStartDate.plusDays(paymentCycleDurationInDays);
boolean entitledToVouchersInNextCycle = isEntitledToVoucher(expectedDeliveryDate, nextCycleStartDate, qualifyingReason);
LocalDate cycleAfterNextStartDate = nextCycleStartDate.plusDays(paymentCycleDurationInDays);
boolean entitledToVouchersInCycleAfterNext = isEntitledToVoucher(expectedDeliveryDate, cycleAfterNextStartDate, qualifyingReason);
return entitledToVouchersInCurrentCycle && entitledToVouchersInNextCycle && !entitledToVouchersInCycleAfterNext;
}
private QualifyingReason getQualifyingReasonFromCombinedIdentityAndEligibilityResponse(PaymentCycle paymentCycle) {
return paymentCycle.getClaim().getCurrentIdentityAndEligibilityResponse().getQualifyingReason();
}
/**
* Determines if a claimant is pregnant in the payment cycle based on their due date and the pregnancy grace period.
* Returns true if the claimant's due date is before or equal to the payment cycle start date plus the grace period duration.
* @param paymentCycle the payment cycle to check when the claimant is pregnant
*
* @return true if the claimant's due date is before or equal to the payment cycle start date plus the grace period duration.
*/
public boolean claimantIsPregnantInCycle(PaymentCycle paymentCycle) {
QualifyingReason qualifyingReason = getQualifyingReasonFromCombinedIdentityAndEligibilityResponse(paymentCycle);
return isEntitledToVoucher(paymentCycle.getExpectedDeliveryDate(), paymentCycle.getCycleStartDate(), qualifyingReason);
}
/**
* Determines if a claimant is still pregnant on the day after the payment cycle ends, based on their due date and the pregnancy grace period.
* Returns true if the claimant's due date is before or equal to the day after payment cycle end date plus the grace period duration.
* @param paymentCycle the payment cycle to check when the claimant is pregnant
*
* @return true if the claimant is entitled to a voucher on the day after the given cycle ends.
*/
public boolean claimantIsPregnantAfterCycle(PaymentCycle paymentCycle) {
LocalDate expectedDeliveryDate = paymentCycle.getExpectedDeliveryDate();
LocalDate nextCycleStartDate = paymentCycle.getCycleEndDate().plusDays(1);
QualifyingReason qualifyingReason = getQualifyingReasonFromCombinedIdentityAndEligibilityResponse(paymentCycle);
return isEntitledToVoucher(expectedDeliveryDate, nextCycleStartDate, qualifyingReason);
}
}