Skip to content

Commit

Permalink
NIAD-3220: Add Resource filter to identify ReferralRequest to externa…
Browse files Browse the repository at this point in the history
…l document LinkSets (#936)

* Add Test to check verify that the provided `LinkSet` is a "Referral Request to External Document LinkSet."
* Add test XML file containing a "Referral Request to External Document LinkSet."
* Add method `isReferralRequestToExternalDocumentLinkSet` to `ResourceFilterUtil` with parameters for the `ehrExtract` and te `LinkSet` itself to identify `LinkSets` matching the criteria for a "Referral Request to External Document LinkSet."
  • Loading branch information
MartinWheelerMT authored Nov 21, 2024
1 parent 92dae56 commit ea4b0e4
Show file tree
Hide file tree
Showing 3 changed files with 316 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.hl7.v3.RCMRMT030101UKComponent;
import org.hl7.v3.RCMRMT030101UKComponent3;
import org.hl7.v3.RCMRMT030101UKComponent4;
import org.hl7.v3.RCMRMT030101UKCompoundStatement;
import org.hl7.v3.RCMRMT030101UKEhrExtract;
import org.hl7.v3.RCMRMT030101UKLinkSet;
import org.hl7.v3.RCMRMT030101UKNarrativeStatement;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ResourceFilterUtil {

private static final List<String> ALLERGY_CODES = List.of("SN53.00", "14L..00");
private static final String CODE_SYSTEM_READ_CODE_V2 = "2.16.840.1.113883.2.1.6.2";
private static final String SNOMED_CODE_SYSTEM = "2.16.840.1.113883.2.1.3.2.4.15";
private static final String UNSPECIFIED_PROBLEM_CODE = "394776006";
private static final String PATHOLOGY_CODE = "16488004";
private static final String SPECIMEN_CODE = "123038009";
private static final String BATTERY_VALUE = "BATTERY";
Expand Down Expand Up @@ -82,6 +90,63 @@ public static boolean isTemplate(RCMRMT030101UKCompoundStatement compoundStateme
&& List.of(BATTERY_VALUE, CLUSTER_VALUE).contains(compoundStatement.getClassCode().getFirst());
}

public static boolean isReferralRequestToExternalDocumentLinkSet(RCMRMT030101UKEhrExtract ehrExtract, RCMRMT030101UKLinkSet linkSet) {
return hasUnspecifiedProblemCodeWithoutQualifierOrOriginalText(linkSet)
&& !linkSet.getComponent().isEmpty()
&& hasNamedStatementRefReferencingARequestStatement(ehrExtract, linkSet)
&& containsOnlyComponentsWithStatementRefReferencingADocument(ehrExtract, linkSet);
}

private static boolean hasUnspecifiedProblemCodeWithoutQualifierOrOriginalText(RCMRMT030101UKLinkSet linkSet) {
return linkSet.hasCode()
&& SNOMED_CODE_SYSTEM.equals(linkSet.getCode().getCodeSystem())
&& UNSPECIFIED_PROBLEM_CODE.equals(linkSet.getCode().getCode())
&& linkSet.getCode().getQualifier().isEmpty()
&& !linkSet.getCode().hasOriginalText();
}

private static boolean containsOnlyComponentsWithStatementRefReferencingADocument(
RCMRMT030101UKEhrExtract ehrExtract,
RCMRMT030101UKLinkSet linkSet
) {
var statementRefIds = linkSet.getComponent()
.stream()
.map(component -> component.getStatementRef().getId().getRoot())
.collect(Collectors.toSet());

return extractAllEhrCompositionComponentsAsStream(ehrExtract)
.flatMap(CompoundStatementResourceExtractors::extractAllNonBloodPressureNarrativeStatements)
.filter(Objects::nonNull)
.filter(ResourceFilterUtil::isDocumentReference)
.map(narrativeStatement -> narrativeStatement.getId().getRoot())
.collect(Collectors.toSet())
.containsAll(statementRefIds);
}

private static boolean hasNamedStatementRefReferencingARequestStatement(
RCMRMT030101UKEhrExtract ehrExtract,
RCMRMT030101UKLinkSet linkSet
) {
if (linkSet.getConditionNamed() == null) {
return false;
}
var namedStatementRefId = linkSet.getConditionNamed().getNamedStatementRef().getId().getRoot();

return extractAllEhrCompositionComponentsAsStream(ehrExtract)
.flatMap(CompoundStatementResourceExtractors::extractAllRequestStatements)
.filter(Objects::nonNull)
.anyMatch(requestStatement -> namedStatementRefId.equals(requestStatement.getId().getFirst().getRoot()));
}

private static Stream<RCMRMT030101UKComponent4> extractAllEhrCompositionComponentsAsStream(RCMRMT030101UKEhrExtract ehrExtract) {
return ehrExtract.getComponent()
.stream()
.map(RCMRMT030101UKComponent::getEhrFolder)
.flatMap(ehrFolder -> ehrFolder.getComponent().stream())
.map(RCMRMT030101UKComponent3::getEhrComposition)
.flatMap(ehrComposition -> ehrComposition.getComponent().stream());
}

private static boolean hasCode(RCMRMT030101UKCompoundStatement compoundStatement) {
return compoundStatement.hasCode() && compoundStatement.getCode().hasCode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@

import static uk.nhs.adaptors.pss.translator.util.XmlUnmarshallUtil.unmarshallFile;

import java.util.Objects;
import java.util.stream.Stream;

import org.hl7.v3.CR;
import org.hl7.v3.RCMRMT030101UKComponent;
import org.hl7.v3.RCMRMT030101UKComponent4;
import org.hl7.v3.RCMRMT030101UKCompoundStatement;
import org.hl7.v3.RCMRMT030101UKEhrExtract;
import org.hl7.v3.RCMRMT030101UKLinkSet;
import org.hl7.v3.RCMRMT030101UKNarrativeStatement;
import org.hl7.v3.RCMRMT030101UKObservationStatement;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -157,6 +163,96 @@ private static Stream<Arguments> nonSpecimenTestFiles() {
);
}

@Test
public void testIsReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isTrue();
}

@Test
public void When_ActiveProblem_Expect_IsNotReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);
linkSet.getCode().setCode("394774009");

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isFalse();
}

@Test
public void When_LinkSetHasReadV2Code_Expect_IsNotReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);
linkSet.getCode().setCodeSystem("2.16.840.1.113883.2.1.6.2");

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isFalse();
}

@Test
public void When_LinkSetHasCodeWithQualifier_Expect_IsNotReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);
linkSet.getCode().getQualifier().add(new CR());

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isFalse();
}

@Test
public void When_LinkSetHasCodeWithOriginalText_Expect_IsNotReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);
linkSet.getCode().setOriginalText("original-text");

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isFalse();
}

@Test
public void When_LinkSetHasNoComponents_Expect_IsNotReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);
linkSet.getComponent().clear();

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isFalse();
}

@Test
public void When_LinkSetHasNamedStatementRefWhichIsANarrativeStatement_Expect_IsNotReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);
linkSet.getConditionNamed().getNamedStatementRef().getId().setRoot("narrative-statement-1");

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isFalse();
}

@Test
public void When_LinkSetHasComponentWhichReferencesRequestStatement_Expect_IsNotReferralRequestToExternalDocumentLinkSet() {
final var ehrExtract = unmarshallEhrExtractElement("ehr_extract_with_referral_request_to_external_document_linkset.xml");
final var linkSet = extractFirstLinkSetFromEhrExtract(ehrExtract);
linkSet.getComponent().getFirst().getStatementRef().getId().setRoot("request-statement-1");

assertThat(ResourceFilterUtil.isReferralRequestToExternalDocumentLinkSet(ehrExtract, linkSet))
.isFalse();
}

private RCMRMT030101UKLinkSet extractFirstLinkSetFromEhrExtract(RCMRMT030101UKEhrExtract ehrExtract) {
return ehrExtract.getComponent().stream()
.map(RCMRMT030101UKComponent::getEhrFolder)
.flatMap(ehrFolder -> ehrFolder.getComponent().stream())
.flatMap(component -> component.getEhrComposition().getComponent().stream())
.map(RCMRMT030101UKComponent4::getLinkSet)
.filter(Objects::nonNull)
.findFirst()
.orElseThrow();
}

@SneakyThrows
private RCMRMT030101UKCompoundStatement unmarshallCompoundStatementElement(String fileName) {
return unmarshallFile(getFile("classpath:" + XML_RESOURCES + fileName),
Expand All @@ -174,4 +270,10 @@ private RCMRMT030101UKNarrativeStatement unmarshallNarrativeStatementElement(Str
return unmarshallFile(getFile("classpath:" + XML_RESOURCES + fileName),
RCMRMT030101UKNarrativeStatement.class);
}

@SneakyThrows
private RCMRMT030101UKEhrExtract unmarshallEhrExtractElement(String fileName) {
return unmarshallFile(getFile("classpath:" + XML_RESOURCES + fileName),
RCMRMT030101UKEhrExtract.class);
}
}
Loading

0 comments on commit ea4b0e4

Please sign in to comment.