diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapper.java index 39fb748d2e..adde41418b 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapper.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapper.java @@ -1,26 +1,16 @@ package uk.nhs.adaptors.gp2gp.ehr.mapper; +import static org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceClinicalStatus; import static uk.nhs.adaptors.gp2gp.ehr.mapper.AllergyStructureExtractor.extractOnsetDate; -import static uk.nhs.adaptors.gp2gp.ehr.mapper.AllergyStructureExtractor.extractReaction; import static uk.nhs.adaptors.gp2gp.ehr.mapper.AllergyStructureExtractor.extractAssertedDate; -import static uk.nhs.adaptors.gp2gp.ehr.utils.DateFormatUtil.toTextFormat; -import static uk.nhs.adaptors.gp2gp.ehr.utils.ExtensionMappingUtils.filterExtensionByUrl; -import java.util.List; import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.dstu3.model.AllergyIntolerance; -import org.hl7.fhir.dstu3.model.Annotation; -import org.hl7.fhir.dstu3.model.Condition; -import org.hl7.fhir.dstu3.model.PrimitiveType; +import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceCategory; +import org.hl7.fhir.dstu3.model.Enumeration; import org.hl7.fhir.dstu3.model.Reference; -import org.hl7.fhir.dstu3.model.RelatedPerson; import org.hl7.fhir.dstu3.model.ResourceType; -import org.hl7.fhir.instance.model.api.IIdType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -30,167 +20,127 @@ import uk.nhs.adaptors.gp2gp.common.service.ConfidentialityService; import uk.nhs.adaptors.gp2gp.ehr.exception.EhrMapperException; import uk.nhs.adaptors.gp2gp.ehr.mapper.parameters.AllergyStructureTemplateParameters; -import uk.nhs.adaptors.gp2gp.ehr.mapper.parameters.AllergyStructureTemplateParameters.AllergyStructureTemplateParametersBuilder; -import uk.nhs.adaptors.gp2gp.ehr.utils.DateFormatUtil; import uk.nhs.adaptors.gp2gp.ehr.utils.StatementTimeMappingUtils; import uk.nhs.adaptors.gp2gp.ehr.utils.TemplateUtils; @RequiredArgsConstructor(onConstructor = @__(@Autowired)) @Component public class AllergyStructureMapper { - private static final Mustache ALLERGY_STRUCTURE_TEMPLATE = TemplateUtils.loadTemplate("ehr_allergy_structure_template.mustache"); - - private static final String ALLERGY_INTOLERANCE_END_URL = - "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-AllergyIntoleranceEnd-1"; - private static final String END_DATE = "End Date: "; - private static final String STATUS = "Status: "; - private static final String TYPE = "Type: "; - private static final String CRITICALITY = "Criticality: "; - private static final String PATIENT_ASSERTER = "Asserted By Patient"; - private static final String RELATED_PERSON_ASSERTER = "Asserted By: Related Person"; - private static final String LAST_OCCURRENCE = "Last Occurred: "; - private static final String PATIENT_RECORDER = "Recorded By Patient"; - private static final String ENVIRONMENT_CATEGORY = "environment"; - private static final String MEDICATION_CATEGORY = "medication"; - private static final String RESOLVED_CLINICAL_STATUS = "resolved"; - private static final String UNSPECIFIED_ALLERGY_CODE = ""; - private static final String DRUG_ALLERGY_CODE = ""; - private static final String COMMA = ", "; + private static final Mustache ALLERGY_STRUCTURE_TEMPLATE = + TemplateUtils.loadTemplate("ehr_allergy_structure_template.mustache"); + private static final String UNSPECIFIED_ALLERGY_CODE = + ""; + private static final String DRUG_ALLERGY_CODE = + ""; private final MessageContext messageContext; private final CodeableConceptCdMapper codeableConceptCdMapper; private final ParticipantMapper participantMapper; private final ConfidentialityService confidentialityService; + private final PertinentInformationAllergyMapper pertinentInformationAllergyMapper; public String mapAllergyIntoleranceToAllergyStructure(AllergyIntolerance allergyIntolerance) { - final IdMapper idMapper = messageContext.getIdMapper(); - - var confidentialityCode = confidentialityService.generateConfidentialityCode(allergyIntolerance); + final var idMapper = messageContext.getIdMapper(); + final var allergyStructureId = idMapper.getOrNew(ResourceType.AllergyIntolerance, allergyIntolerance.getIdElement()); + final var categoryCode = buildCategoryCode(allergyIntolerance); + final var effectiveTime = buildEffectiveTime(allergyIntolerance); + final var availabilityTime = buildAvailabilityTime(allergyIntolerance); + final var confidentialityCode = confidentialityService.generateConfidentialityCode(allergyIntolerance).orElse(null); + final var observationId = idMapper.getOrNew(ResourceType.Observation, allergyIntolerance.getIdElement()); + final var code = buildCode(allergyIntolerance); + final var pertinentInformation = pertinentInformationAllergyMapper.buildPertinentInformation(allergyIntolerance); + final var author = buildAuthor(allergyIntolerance).orElse(null); + final var performer = buildPerformer(allergyIntolerance).orElse(null); var allergyStructureTemplateParameters = AllergyStructureTemplateParameters.builder() - .allergyStructureId(idMapper.getOrNew(ResourceType.AllergyIntolerance, allergyIntolerance.getIdElement())) - .observationId(idMapper.getOrNew(ResourceType.Observation, allergyIntolerance.getIdElement())) - .pertinentInformation(buildPertinentInformation(allergyIntolerance)) - .code(buildCode(allergyIntolerance)) - .effectiveTime(buildEffectiveTime(allergyIntolerance)) - .availabilityTime(buildAvailabilityTime(allergyIntolerance)) - .confidentialityCode(confidentialityCode.orElse(null)); - - buildCategory(allergyIntolerance, allergyStructureTemplateParameters); - - if (allergyIntolerance.hasRecorder()) { - buildParticipant(allergyIntolerance.getRecorder(), ParticipantType.AUTHOR) - .ifPresent(allergyStructureTemplateParameters::author); - } - - buildAuthor(allergyIntolerance, allergyStructureTemplateParameters); + .allergyStructureId(allergyStructureId) + .categoryCode(categoryCode) + .effectiveTime(effectiveTime) + .availabilityTime(availabilityTime) + .confidentialityCode(confidentialityCode) + .observationId(observationId) + .code(code) + .pertinentInformation(pertinentInformation) + .author(author) + .performer(performer); return TemplateUtils.fillTemplate(ALLERGY_STRUCTURE_TEMPLATE, allergyStructureTemplateParameters.build()); } - private String buildPertinentInformation(AllergyIntolerance allergyIntolerance) { - List descriptionList = retrievePertinentInformation(allergyIntolerance); - - return descriptionList - .stream() - .filter(StringUtils::isNotEmpty) - .collect(Collectors.joining(StringUtils.SPACE)); - } - private String buildCode(AllergyIntolerance allergyIntolerance) { - if (allergyIntolerance.hasClinicalStatus()) { - if (RESOLVED_CLINICAL_STATUS.equals(allergyIntolerance.getClinicalStatus().toCode()) - && allergyIntolerance.hasCode()) { + if (!allergyIntolerance.hasClinicalStatus() || !allergyIntolerance.hasCode()) { + throw new EhrMapperException("Allergy code not present"); + } + final var clinicalStatus = allergyIntolerance.getClinicalStatus(); + final var allergyCode = allergyIntolerance.getCode(); - var category = allergyIntolerance.getCategory() - .stream() - .map(PrimitiveType::getValueAsString) - .filter(value -> value.equals(ENVIRONMENT_CATEGORY) || value.equals(MEDICATION_CATEGORY)) - .findFirst() - .orElse(StringUtils.EMPTY); + if (AllergyIntoleranceClinicalStatus.RESOLVED.equals(clinicalStatus)) { + var category = getAllergyCategory(allergyIntolerance); - if (category.equals(ENVIRONMENT_CATEGORY)) { - return codeableConceptCdMapper.mapCodeableConceptToCdForAllergy(allergyIntolerance.getCode(), - allergyIntolerance.getClinicalStatus()); - } else if (category.equals(MEDICATION_CATEGORY)) { - return codeableConceptCdMapper.mapToNullFlavorCodeableConceptForAllergy(allergyIntolerance.getCode(), - allergyIntolerance.getClinicalStatus()); - } else { - throw new EhrMapperException("Category could not be mapped"); - } + if (category.equals(AllergyIntoleranceCategory.ENVIRONMENT)) { + return codeableConceptCdMapper.mapCodeableConceptToCdForAllergy(allergyCode, clinicalStatus); } - if (allergyIntolerance.hasCode()) { - return codeableConceptCdMapper.mapCodeableConceptToCdForAllergy(allergyIntolerance.getCode(), - allergyIntolerance.getClinicalStatus()); + if (category.equals(AllergyIntoleranceCategory.MEDICATION)) { + return codeableConceptCdMapper.mapToNullFlavorCodeableConceptForAllergy(allergyCode, clinicalStatus); } + throw new EhrMapperException("Category could not be mapped"); } - throw new EhrMapperException("Allergy code not present"); + return codeableConceptCdMapper.mapCodeableConceptToCdForAllergy(allergyCode, clinicalStatus); } private String buildAvailabilityTime(AllergyIntolerance allergyIntolerance) { - var availabilityTime = extractAssertedDate(allergyIntolerance); - return StatementTimeMappingUtils.prepareAvailabilityTimeForAllergyIntolerance(availabilityTime); } private String buildEffectiveTime(AllergyIntolerance allergyIntolerance) { var onsetDate = extractOnsetDate(allergyIntolerance); - return StatementTimeMappingUtils.prepareEffectiveTimeForAllergyIntolerance(onsetDate); } - private void buildCategory(AllergyIntolerance allergyIntolerance, AllergyStructureTemplateParametersBuilder templateParameters) { - var category = allergyIntolerance.getCategory() - .stream() - .map(PrimitiveType::getValueAsString) - .filter(value -> value.equals(ENVIRONMENT_CATEGORY) || value.equals(MEDICATION_CATEGORY)) - .findFirst() - .orElse(StringUtils.EMPTY); + private String buildCategoryCode(AllergyIntolerance allergyIntolerance) { + var category = getAllergyCategory(allergyIntolerance); - if (category.equals(ENVIRONMENT_CATEGORY)) { - templateParameters.categoryCode(UNSPECIFIED_ALLERGY_CODE); - } else if (category.equals(MEDICATION_CATEGORY)) { - templateParameters.categoryCode(DRUG_ALLERGY_CODE); - } else { - throw new EhrMapperException("Category could not be mapped"); + if (category.equals(AllergyIntoleranceCategory.ENVIRONMENT)) { + return UNSPECIFIED_ALLERGY_CODE; } + if (category.equals(AllergyIntoleranceCategory.MEDICATION)) { + return DRUG_ALLERGY_CODE; + } + throw new EhrMapperException("Category could not be mapped"); } + private Optional buildAuthor(AllergyIntolerance allergyIntolerance) { + return allergyIntolerance.hasRecorder() + ? buildParticipant(allergyIntolerance.getRecorder(), ParticipantType.AUTHOR) + : Optional.empty(); + } private Optional buildParticipant(Reference reference, ParticipantType participantType) { - if (reference.getReferenceElement().getResourceType().startsWith(ResourceType.Practitioner.name())) { - var authorReferenceId = messageContext.getAgentDirectory().getAgentId(reference); - return Optional.of(participantMapper.mapToParticipant(authorReferenceId, participantType)); + var resourceType = reference.getReferenceElement().getResourceType(); + if (!resourceType.startsWith(ResourceType.Practitioner.name())) { + return Optional.empty(); } - - return Optional.empty(); + var authorReferenceId = messageContext.getAgentDirectory().getAgentId(reference); + return Optional.of(participantMapper.mapToParticipant(authorReferenceId, participantType)); } - private void buildAuthor(AllergyIntolerance allergyIntolerance, AllergyStructureTemplateParametersBuilder templateParameter) { + private Optional buildPerformer(AllergyIntolerance allergyIntolerance) { if (isValidAsserter(allergyIntolerance)) { - buildParticipant(allergyIntolerance.getAsserter(), ParticipantType.PERFORMER) - .ifPresent(templateParameter::performer); - } else if (allergyIntolerance.hasRecorder()) { - buildParticipant(allergyIntolerance.getRecorder(), ParticipantType.PERFORMER) - .ifPresent(templateParameter::performer); + return buildParticipant(allergyIntolerance.getAsserter(), ParticipantType.PERFORMER); + } + if (allergyIntolerance.hasRecorder()) { + return buildParticipant(allergyIntolerance.getRecorder(), ParticipantType.PERFORMER); } + return Optional.empty(); } - private List retrievePertinentInformation(AllergyIntolerance allergyIntolerance) { - return List.of( - buildExtensionReasonEndPertinentInformation(allergyIntolerance), - buildClinicalStatusPertinentInformation(allergyIntolerance), - buildTypePertinentInformation(allergyIntolerance), - buildCriticalityPertinentInformation(allergyIntolerance), - buildAsserterPertinentInformation(allergyIntolerance), - buildLastOccurrencePertinentInformation(allergyIntolerance), - buildRecorderPertinentInformation(allergyIntolerance), - buildReactionPertinentInformation(allergyIntolerance), - buildNotePertinentInformation(allergyIntolerance), - buildEndDatePertinentInformation(allergyIntolerance) - ); + private AllergyIntoleranceCategory getAllergyCategory(AllergyIntolerance allergyIntolerance) { + return allergyIntolerance.getCategory() + .stream() + .map(Enumeration::getValue) + .filter(this::isMedicationOrEnvironmentCategory) + .findFirst() + .orElse(AllergyIntoleranceCategory.NULL); } private boolean isValidAsserter(AllergyIntolerance allergyIntolerance) { @@ -198,106 +148,8 @@ private boolean isValidAsserter(AllergyIntolerance allergyIntolerance) { && allergyIntolerance.getAsserter().getReferenceElement().getResourceType().startsWith(ResourceType.Practitioner.name()); } - private String buildExtensionReasonEndPertinentInformation(AllergyIntolerance allergyIntolerance) { - return filterExtensionByUrl(allergyIntolerance, ALLERGY_INTOLERANCE_END_URL) - .map(AllergyStructureExtractor::extractReasonEnd) - .orElse(StringUtils.EMPTY); - } - - private String buildClinicalStatusPertinentInformation(AllergyIntolerance allergyIntolerance) { - if (allergyIntolerance.hasClinicalStatus()) { - if (allergyIntolerance.hasNote()) { - return STATUS + StringUtils.capitalize(allergyIntolerance.getClinicalStatus().toCode()); - } - return STATUS + allergyIntolerance.getClinicalStatus().getDisplay(); - } - return StringUtils.EMPTY; - } - - private String buildTypePertinentInformation(AllergyIntolerance allergyIntolerance) { - if (allergyIntolerance.hasType()) { - return TYPE + allergyIntolerance.getType().getDisplay(); - } - return StringUtils.EMPTY; - } - - private String buildCriticalityPertinentInformation(AllergyIntolerance allergyIntolerance) { - if (allergyIntolerance.hasCriticality()) { - return CRITICALITY + allergyIntolerance.getCriticality().getDisplay(); - } - return StringUtils.EMPTY; - } - - private String buildAsserterPertinentInformation(AllergyIntolerance allergyIntolerance) { - if (allergyIntolerance.hasAsserter()) { - IIdType reference = allergyIntolerance.getAsserter().getReferenceElement(); - if (reference.getResourceType().equals(ResourceType.Patient.name())) { - return PATIENT_ASSERTER; - } else if (reference.getResourceType().equals(ResourceType.RelatedPerson.name())) { - return messageContext - .getInputBundleHolder() - .getResource(reference) - .map(RelatedPerson.class::cast) - .filter(RelatedPerson::hasName) - .map(RelatedPerson::getName) - .filter(names -> !names.isEmpty()) - .map(List::getFirst) - .map(name -> Optional.ofNullable(name.getText()) - .filter(StringUtils::isNotBlank) - .orElseGet(name::getNameAsSingleString)) - .filter(StringUtils::isNotBlank) - .map(name -> RELATED_PERSON_ASSERTER + StringUtils.SPACE + name) - .orElse(RELATED_PERSON_ASSERTER); - } - } - return StringUtils.EMPTY; - } - - private String buildLastOccurrencePertinentInformation(AllergyIntolerance allergyIntolerance) { - if (allergyIntolerance.hasLastOccurrence()) { - return LAST_OCCURRENCE + toTextFormat(allergyIntolerance.getLastOccurrenceElement()); - } - return StringUtils.EMPTY; - } - - private String buildRecorderPertinentInformation(AllergyIntolerance allergyIntolerance) { - if (allergyIntolerance.hasRecorder()) { - IIdType reference = allergyIntolerance.getRecorder().getReferenceElement(); - if (reference.getResourceType().equals(ResourceType.Patient.name())) { - return PATIENT_RECORDER; - } - } - return StringUtils.EMPTY; - } - - private String buildReactionPertinentInformation(AllergyIntolerance allergyIntolerance) { - AtomicInteger reactionCount = new AtomicInteger(1); - if (allergyIntolerance.hasReaction()) { - return allergyIntolerance.getReaction() - .stream() - .map(reaction -> extractReaction(reaction, reactionCount)) - .collect(Collectors.joining(COMMA)); - } - return StringUtils.EMPTY; - } - - private String buildNotePertinentInformation(AllergyIntolerance allergyIntolerance) { - return Stream.concat( - messageContext.getInputBundleHolder().getRelatedConditions(allergyIntolerance.getId()) - .stream() - .map(Condition::getNote) - .flatMap(List::stream), - allergyIntolerance.hasNote() ? allergyIntolerance.getNote().stream() : Stream.empty() - ) - .map(Annotation::getText) - .collect(Collectors.joining(StringUtils.SPACE)); - } - - private String buildEndDatePertinentInformation(AllergyIntolerance allergyIntolerance) { - return filterExtensionByUrl(allergyIntolerance, ALLERGY_INTOLERANCE_END_URL) - .map(extension -> AllergyStructureExtractor.extractEndDate(extension, DateFormatUtil::toTextFormat)) - .filter(StringUtils::isNotBlank) - .map(endDate -> END_DATE + endDate) - .orElse(StringUtils.EMPTY); + private boolean isMedicationOrEnvironmentCategory(AllergyIntoleranceCategory category) { + return category.equals(AllergyIntoleranceCategory.ENVIRONMENT) + || category.equals(AllergyIntoleranceCategory.MEDICATION); } } diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/PertinentInformationAllergyMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/PertinentInformationAllergyMapper.java new file mode 100644 index 0000000000..0a47fc0f32 --- /dev/null +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/PertinentInformationAllergyMapper.java @@ -0,0 +1,167 @@ +package uk.nhs.adaptors.gp2gp.ehr.mapper; + +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.dstu3.model.AllergyIntolerance; +import org.hl7.fhir.dstu3.model.Annotation; +import org.hl7.fhir.dstu3.model.Condition; +import org.hl7.fhir.dstu3.model.RelatedPerson; +import org.hl7.fhir.dstu3.model.ResourceType; +import org.hl7.fhir.instance.model.api.IIdType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import uk.nhs.adaptors.gp2gp.ehr.utils.DateFormatUtil; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static uk.nhs.adaptors.gp2gp.ehr.mapper.AllergyStructureExtractor.extractReaction; +import static uk.nhs.adaptors.gp2gp.ehr.utils.DateFormatUtil.toTextFormat; +import static uk.nhs.adaptors.gp2gp.ehr.utils.ExtensionMappingUtils.filterExtensionByUrl; + +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +@Component +public class PertinentInformationAllergyMapper { + private static final String ALLERGY_INTOLERANCE_END_URL = + "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-CareConnect-GPC-AllergyIntoleranceEnd-1"; + private static final String END_DATE = "End Date: "; + private static final String STATUS = "Status: "; + private static final String TYPE = "Type: "; + private static final String CRITICALITY = "Criticality: "; + private static final String PATIENT_ASSERTER = "Asserted By Patient"; + private static final String RELATED_PERSON_ASSERTER = "Asserted By: Related Person"; + private static final String LAST_OCCURRENCE = "Last Occurred: "; + private static final String PATIENT_RECORDER = "Recorded By Patient"; + private static final String COMMA = ", "; + + + private final MessageContext messageContext; + + public String buildPertinentInformation(AllergyIntolerance allergyIntolerance) { + return retrievePertinentInformation(allergyIntolerance) + .stream() + .filter(StringUtils::isNotEmpty) + .collect(Collectors.joining(StringUtils.SPACE)); + } + + private List retrievePertinentInformation(AllergyIntolerance allergyIntolerance) { + return List.of( + buildExtensionReasonEndPertinentInformation(allergyIntolerance), + buildClinicalStatusPertinentInformation(allergyIntolerance), + buildTypePertinentInformation(allergyIntolerance), + buildCriticalityPertinentInformation(allergyIntolerance), + buildAsserterPertinentInformation(allergyIntolerance), + buildLastOccurrencePertinentInformation(allergyIntolerance), + buildRecorderPertinentInformation(allergyIntolerance), + buildReactionPertinentInformation(allergyIntolerance), + buildNotePertinentInformation(allergyIntolerance), + buildEndDatePertinentInformation(allergyIntolerance) + ); + } + + private String buildExtensionReasonEndPertinentInformation(AllergyIntolerance allergyIntolerance) { + return filterExtensionByUrl(allergyIntolerance, ALLERGY_INTOLERANCE_END_URL) + .map(AllergyStructureExtractor::extractReasonEnd) + .orElse(StringUtils.EMPTY); + } + + private String buildClinicalStatusPertinentInformation(AllergyIntolerance allergyIntolerance) { + return allergyIntolerance.hasClinicalStatus() + ? buildClinicalStatusNotePertinentInformation(allergyIntolerance) + : StringUtils.EMPTY; + } + + private String buildClinicalStatusNotePertinentInformation(AllergyIntolerance allergyIntolerance) { + return allergyIntolerance.hasNote() + ? STATUS + StringUtils.capitalize(allergyIntolerance.getClinicalStatus().toCode()) + : STATUS + allergyIntolerance.getClinicalStatus().getDisplay(); + } + + private String buildTypePertinentInformation(AllergyIntolerance allergyIntolerance) { + return allergyIntolerance.hasType() + ? TYPE + allergyIntolerance.getType().getDisplay() + : StringUtils.EMPTY; + } + + private String buildCriticalityPertinentInformation(AllergyIntolerance allergyIntolerance) { + return allergyIntolerance.hasCriticality() + ? CRITICALITY + allergyIntolerance.getCriticality().getDisplay() + : StringUtils.EMPTY; + } + + private String buildAsserterPertinentInformation(AllergyIntolerance allergyIntolerance) { + if (allergyIntolerance.hasAsserter()) { + IIdType reference = allergyIntolerance.getAsserter().getReferenceElement(); + if (reference.getResourceType().equals(ResourceType.Patient.name())) { + return PATIENT_ASSERTER; + } else if (reference.getResourceType().equals(ResourceType.RelatedPerson.name())) { + return messageContext + .getInputBundleHolder() + .getResource(reference) + .map(RelatedPerson.class::cast) + .filter(RelatedPerson::hasName) + .map(RelatedPerson::getName) + .filter(names -> !names.isEmpty()) + .map(List::getFirst) + .map(name -> Optional.ofNullable(name.getText()) + .filter(StringUtils::isNotBlank) + .orElseGet(name::getNameAsSingleString)) + .filter(StringUtils::isNotBlank) + .map(name -> RELATED_PERSON_ASSERTER + StringUtils.SPACE + name) + .orElse(RELATED_PERSON_ASSERTER); + } + } + return StringUtils.EMPTY; + } + + private String buildLastOccurrencePertinentInformation(AllergyIntolerance allergyIntolerance) { + if (allergyIntolerance.hasLastOccurrence()) { + return LAST_OCCURRENCE + toTextFormat(allergyIntolerance.getLastOccurrenceElement()); + } + return StringUtils.EMPTY; + } + + private String buildRecorderPertinentInformation(AllergyIntolerance allergyIntolerance) { + if (allergyIntolerance.hasRecorder()) { + IIdType reference = allergyIntolerance.getRecorder().getReferenceElement(); + if (reference.getResourceType().equals(ResourceType.Patient.name())) { + return PATIENT_RECORDER; + } + } + return StringUtils.EMPTY; + } + + private String buildReactionPertinentInformation(AllergyIntolerance allergyIntolerance) { + AtomicInteger reactionCount = new AtomicInteger(1); + if (allergyIntolerance.hasReaction()) { + return allergyIntolerance.getReaction() + .stream() + .map(reaction -> extractReaction(reaction, reactionCount)) + .collect(Collectors.joining(COMMA)); + } + return StringUtils.EMPTY; + } + + private String buildNotePertinentInformation(AllergyIntolerance allergyIntolerance) { + return Stream.concat( + messageContext.getInputBundleHolder().getRelatedConditions(allergyIntolerance.getId()) + .stream() + .map(Condition::getNote) + .flatMap(List::stream), + allergyIntolerance.hasNote() ? allergyIntolerance.getNote().stream() : Stream.empty() + ) + .map(Annotation::getText) + .collect(Collectors.joining(StringUtils.SPACE)); + } + + private String buildEndDatePertinentInformation(AllergyIntolerance allergyIntolerance) { + return filterExtensionByUrl(allergyIntolerance, ALLERGY_INTOLERANCE_END_URL) + .map(extension -> AllergyStructureExtractor.extractEndDate(extension, DateFormatUtil::toTextFormat)) + .filter(StringUtils::isNotBlank) + .map(endDate -> END_DATE + endDate) + .orElse(StringUtils.EMPTY); + } +} diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapperTest.java index b08b9c0b9c..891fa7c1f0 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/AllergyStructureMapperTest.java @@ -113,8 +113,6 @@ private static Stream resourceFileParamsWithEnvironmentCategoryAndCon void setUp() { when(randomIdGeneratorService.createNewId()).thenReturn(TEST_ID); when(randomIdGeneratorService.createNewOrUseExistingUUID(anyString())).thenReturn(TEST_ID); - when(confidentialityService.generateConfidentialityCode(any())) - .thenReturn(Optional.empty()); var bundleInput = ResourceTestFileUtils.getFileContent(INPUT_JSON_BUNDLE); Bundle bundle = new FhirParseService().parseResource(bundleInput, Bundle.class); @@ -128,7 +126,8 @@ void setUp() { messageContext, codeableConceptCdMapper, new ParticipantMapper(), - confidentialityService); + confidentialityService, + new PertinentInformationAllergyMapper(messageContext)); } @AfterEach diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EhrExtractMapperComponentTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EhrExtractMapperComponentTest.java index 0ed2877b96..7c22f6ff50 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EhrExtractMapperComponentTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EhrExtractMapperComponentTest.java @@ -145,7 +145,9 @@ public void setUp() { EncounterComponentsMapper encounterComponentsMapper = new EncounterComponentsMapper( messageContext, - new AllergyStructureMapper(messageContext, codeableConceptCdMapper, participantMapper, confidentialityService), + new AllergyStructureMapper(messageContext, codeableConceptCdMapper, participantMapper, + confidentialityService, + new PertinentInformationAllergyMapper(messageContext)), new BloodPressureMapper(messageContext, randomIdGeneratorService, new StructuredObservationValueMapper(), codeableConceptCdMapper, new ParticipantMapper(), confidentialityService), diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EncounterComponentsMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EncounterComponentsMapperTest.java index 883e70d614..1be0ddea39 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EncounterComponentsMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EncounterComponentsMapperTest.java @@ -147,7 +147,8 @@ public void setUp() { messageContext, codeableConceptCdMapper, participantMapper, - confidentialityService + confidentialityService, + new PertinentInformationAllergyMapper(messageContext) ); BloodPressureMapper bloodPressureMapper = new BloodPressureMapper( messageContext, diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/uat/EhrExtractUATTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/uat/EhrExtractUATTest.java index 8355fcac34..19b3354209 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/uat/EhrExtractUATTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/uat/EhrExtractUATTest.java @@ -40,6 +40,7 @@ import uk.nhs.adaptors.gp2gp.ehr.mapper.ObservationToNarrativeStatementMapper; import uk.nhs.adaptors.gp2gp.ehr.mapper.OutputMessageWrapperMapper; import uk.nhs.adaptors.gp2gp.ehr.mapper.ParticipantMapper; +import uk.nhs.adaptors.gp2gp.ehr.mapper.PertinentInformationAllergyMapper; import uk.nhs.adaptors.gp2gp.ehr.mapper.PertinentInformationObservationValueMapper; import uk.nhs.adaptors.gp2gp.ehr.mapper.RequestStatementMapper; import uk.nhs.adaptors.gp2gp.ehr.mapper.StructuredObservationValueMapper; @@ -177,7 +178,8 @@ public void setUp() { return new EncounterComponentsMapper( messageContext, - new AllergyStructureMapper(messageContext, codeableConceptCdMapper, participantMapper, confidentialityService), + new AllergyStructureMapper(messageContext, codeableConceptCdMapper, participantMapper, confidentialityService, + new PertinentInformationAllergyMapper(messageContext)), new BloodPressureMapper( messageContext, randomIdGeneratorService, new StructuredObservationValueMapper(), codeableConceptCdMapper, new ParticipantMapper(), confidentialityService),