ReportPropertiesFactory.java
package uk.gov.dhsc.htbhf.claimant.reporting.payload;
import uk.gov.dhsc.htbhf.claimant.entity.Claim;
import uk.gov.dhsc.htbhf.claimant.entity.Claimant;
import uk.gov.dhsc.htbhf.claimant.message.context.ReportEventMessageContext;
import uk.gov.dhsc.htbhf.claimant.model.PostcodeData;
import uk.gov.dhsc.htbhf.claimant.reporting.ClaimantCategoryCalculator;
import uk.gov.dhsc.htbhf.dwp.model.QualifyingReason;
import uk.gov.dhsc.htbhf.eligibility.model.CombinedIdentityAndEligibilityResponse;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static uk.gov.dhsc.htbhf.claimant.message.processor.ChildDateOfBirthCalculator.getNumberOfChildrenUnderFour;
import static uk.gov.dhsc.htbhf.claimant.message.processor.ChildDateOfBirthCalculator.getNumberOfChildrenUnderOne;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.CustomDimension.*;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.CustomMetric.CHILDREN_BETWEEN_ONE_AND_FOUR;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.CustomMetric.CHILDREN_UNDER_ONE;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.CustomMetric.CLAIMANT_AGE;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.CustomMetric.PREGNANCIES;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.EventProperties.*;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.MandatoryProperties.HIT_TYPE_KEY;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.MandatoryProperties.PROTOCOL_VERSION_KEY;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.MandatoryProperties.TRACKING_ID_KEY;
import static uk.gov.dhsc.htbhf.claimant.reporting.payload.UserType.ONLINE;
/**
* Factory class for creating a map of parameters reported to google analytics measurement protocol.
*/
public abstract class ReportPropertiesFactory {
private static final String HIT_TYPE_VALUE = "event";
private static final String PROTOCOL_VERSION_VALUE = "1";
// queue times longer than 4 hours may cause the event to not be registered:
// https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#qt
private static final Long MAX_QUEUE_TIME = 1000L * 60 * 60 * 4;
public static final int PREGNANCY_DURATION_IN_WEEKS = 40;
private final ClaimantCategoryCalculator claimantCategoryCalculator;
private final String trackingId;
public ReportPropertiesFactory(String trackingId,
ClaimantCategoryCalculator claimantCategoryCalculator) {
this.trackingId = trackingId;
this.claimantCategoryCalculator = claimantCategoryCalculator;
}
protected Long calculateQueueTime(LocalDateTime timestamp) {
long queueTime = Duration.between(timestamp, LocalDateTime.now()).toMillis();
return Math.min(queueTime, MAX_QUEUE_TIME);
}
protected Map<String, String> mapValuesToString(Map<String, Object> original) {
Map<String, String> reportProperties = new LinkedHashMap<>();
original.forEach((key, value) -> reportProperties.put(key, String.valueOf(value)));
return reportProperties;
}
protected Map<String, Object> createMandatoryPropertiesMap() {
Map<String, Object> mandatoryProperties = new LinkedHashMap<>();
mandatoryProperties.put(HIT_TYPE_KEY.getFieldName(), HIT_TYPE_VALUE);
mandatoryProperties.put(PROTOCOL_VERSION_KEY.getFieldName(), PROTOCOL_VERSION_VALUE);
mandatoryProperties.put(TRACKING_ID_KEY.getFieldName(), trackingId);
return mandatoryProperties;
}
protected Map<String, Object> createEventPropertiesMap(ReportEventMessageContext context, EventCategory eventCategory, int eventValue) {
Map<String, Object> eventPropertiesMap = new LinkedHashMap<>();
eventPropertiesMap.put(EVENT_CATEGORY.getFieldName(), eventCategory.name());
eventPropertiesMap.put(EVENT_ACTION.getFieldName(), context.getEventAction());
eventPropertiesMap.put(EVENT_VALUE.getFieldName(), eventValue);
eventPropertiesMap.put(QUEUE_TIME.getFieldName(), calculateQueueTime(context.getTimestamp()));
eventPropertiesMap.put(CUSTOMER_ID.getFieldName(), context.getClaim().getId());
return eventPropertiesMap;
}
protected Map<String, Object> createCommonCustomDimensions(ReportEventMessageContext context) {
Map<String, Object> customDimensions = new TreeMap<>();
customDimensions.put(USER_TYPE.getFieldName(), ONLINE.name());
Claim claim = context.getClaim();
CombinedIdentityAndEligibilityResponse identityAndEligibilityResponse = context.getIdentityAndEligibilityResponse();
List<LocalDate> dobOfChildrenUnder4 = getDobOfChildrenUnder4(claim, identityAndEligibilityResponse);
//current identity and eligibility response will be null in case of duplicate rejected claims
QualifyingReason qualifyingReason = claim.getCurrentIdentityAndEligibilityResponse() == null
? QualifyingReason.NOT_SET : claim.getCurrentIdentityAndEligibilityResponse().getQualifyingReason();
ClaimantCategory claimantCategory = claimantCategoryCalculator.determineClaimantCategory(
claim.getClaimant(),
dobOfChildrenUnder4,
context.getTimestamp().toLocalDate(),
qualifyingReason);
customDimensions.put(CLAIMANT_CATEGORY.getFieldName(), claimantCategory.getDescription());
PostcodeData postcodeData = claim.getPostcodeData();
customDimensions.put(LOCAL_AUTHORITY.getFieldName(), postcodeData.getAdminDistrict());
customDimensions.put(LOCAL_AUTHORITY_CODE.getFieldName(), postcodeData.getCodes().getAdminDistrict());
customDimensions.put(COUNTRY.getFieldName(), postcodeData.getCountry());
customDimensions.put(POSTCODE_OUTCODE.getFieldName(), postcodeData.getOutcode());
customDimensions.put(WESTMINSTER_PARLIAMENTARY_CONSTITUENCY.getFieldName(), postcodeData.getParliamentaryConstituency());
customDimensions.put(CLINICAL_COMMISSIONING_GROUP.getFieldName(), postcodeData.getCcg());
customDimensions.put(CLINICAL_COMMISSIONING_GROUP_CODE.getFieldName(), postcodeData.getCodes().getCcg());
customDimensions.put(QUALIFYING_REASON.getFieldName(), getQualifyingReason(identityAndEligibilityResponse));
return customDimensions;
}
private List<LocalDate> getDobOfChildrenUnder4(Claim claim, CombinedIdentityAndEligibilityResponse identityAndEligibilityResponse) {
return identityAndEligibilityResponse == null
? claim.getClaimant().getInitiallyDeclaredChildrenDob()
: identityAndEligibilityResponse.getDobOfChildrenUnder4();
}
private QualifyingReason getQualifyingReason(CombinedIdentityAndEligibilityResponse identityAndEligibilityResponse) {
return identityAndEligibilityResponse == null
? QualifyingReason.NOT_SET
: identityAndEligibilityResponse.getQualifyingReason();
}
protected Map<String, Object> createCommonCustomMetrics(ReportEventMessageContext context) {
Map<String, Object> customMetrics = new TreeMap<>();
Claim claim = context.getClaim();
Claimant claimant = claim.getClaimant();
LocalDate atDate = context.getTimestamp().toLocalDate();
customMetrics.put(CLAIMANT_AGE.getFieldName(), Period.between(claimant.getDateOfBirth(), atDate).getYears());
List<LocalDate> dobOfChildrenUnder4 = getDobOfChildrenUnder4(claim, context.getIdentityAndEligibilityResponse());
long childrenUnder4 = getNumberOfChildrenUnderFour(dobOfChildrenUnder4, atDate);
long childrenUnder1 = getNumberOfChildrenUnderOne(dobOfChildrenUnder4, atDate);
customMetrics.put(CHILDREN_UNDER_ONE.getFieldName(), childrenUnder1);
customMetrics.put(CHILDREN_BETWEEN_ONE_AND_FOUR.getFieldName(), childrenUnder4 - childrenUnder1);
LocalDate expectedDeliveryDate = claimant.getExpectedDeliveryDate();
int pregnanciesValue = isClaimantPregnant(expectedDeliveryDate, atDate) ? 1 : 0;
customMetrics.put(PREGNANCIES.getFieldName(), pregnanciesValue);
return customMetrics;
}
protected boolean isClaimantPregnant(LocalDate expectedDeliveryDate, LocalDate atDate) {
return expectedDeliveryDate != null && !expectedDeliveryDate.isBefore(atDate);
}
}