Skip to content

Commit

Permalink
NIAD-2843: Blood pressure NarrativeStatements are also mapped as Obse…
Browse files Browse the repository at this point in the history
…rvation comments, leading to duplication (#367)

* Add test for changes to ensure blood pressure NarrativeStatements are not being mapped by the ObservationCommentMapper.
Add new functionality to CompoundStatementResourceExtractors to  exclude blood pressures when NarrativeStatements are being extracted

* Add test for changes to ensure blood pressure NarrativeStatements are not being mapped by the ObservationCommentMapper.
Add source file for new test.
Add new functionality to CompoundStatementResourceExtractors to  exclude blood pressures when NarrativeStatements are being extracted.

* fix checkstyle test naming issue

* Update expectedBundle to remove duplicate entries

* Update method name for clarity
Refactor method in DocumentReferenceMapper to remove warning
Add CHANGELOG.md

---------

Co-authored-by: hospel <[email protected]>
  • Loading branch information
MartinWheelerMT and hospel authored Nov 14, 2023
1 parent cbb330c commit dbfcda2
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 99 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Updated

* Updated the way Observation comments are mapped so that blood pressure NarrativeStatements are not duplicated into
in a separate observation.

### Changed

* Changed `ReferralRequest` mapping to use `ASAP` instead of the `Stat` value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31674,44 +31674,6 @@
"comment": "Comments - Aaaargh"
}
},
{
"resource": {
"resourceType": "Observation",
"id": "EC913E83-7610-4FBD-9A60-1769D42E9DEB",
"meta": {
"profile": [
"https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-Observation-1"
]
},
"identifier": [
{
"system": "https://PSSAdaptor/D5445",
"value": "EC913E83-7610-4FBD-9A60-1769D42E9DEB"
}
],
"status": "final",
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "37331000000100",
"display": "Comment note"
}
]
},
"subject": {
"reference": "Patient/e2cf4cc1-08da-4971-845f-35b8447cabdd"
},
"effectiveDateTime": "2006-04-25T15:30:00+00:00",
"issued": "2020-01-01T01:01:01.000+00:00",
"performer": [
{
"reference": "Practitioner/2D70F602-6BB1-47E0-B2EC-39912A59787D"
}
],
"comment": "Systolic Measurement Absent: Unknown"
}
},
{
"resource": {
"resourceType": "Observation",
Expand Down Expand Up @@ -31847,47 +31809,6 @@
]
}
},
{
"resource": {
"resourceType": "Observation",
"id": "B27EB734-741C-4152-9E41-7BAB5EF9DD5E",
"meta": {
"profile": [
"https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-Observation-1"
]
},
"identifier": [
{
"system": "https://PSSAdaptor/D5445",
"value": "B27EB734-741C-4152-9E41-7BAB5EF9DD5E"
}
],
"status": "final",
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "37331000000100",
"display": "Comment note"
}
]
},
"subject": {
"reference": "Patient/e2cf4cc1-08da-4971-845f-35b8447cabdd"
},
"context": {
"reference": "Encounter/9FB8560B-A7FF-4F04-9E0B-CFBB4D0AF4E9"
},
"effectiveDateTime": "2006-04-25T15:30:00+00:00",
"issued": "2010-01-13T15:13:32.000+00:00",
"performer": [
{
"reference": "Practitioner/70555A33-0550-405D-BB67-E9805440B38C"
}
],
"comment": "Systolic Measurement Absent: Unknown"
}
},
{
"resource": {
"resourceType": "Observation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import static org.hl7.fhir.dstu3.model.Enumerations.DocumentReferenceStatus;

import static uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors.extractAllNarrativeStatements;
import static uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors.extractAllNonBloodPressureNarrativeStatements;
import static uk.nhs.adaptors.pss.translator.util.ParticipantReferenceUtil.getParticipantReference;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.buildIdentifier;

Expand Down Expand Up @@ -38,7 +38,7 @@
@AllArgsConstructor
public class DocumentReferenceMapper extends AbstractMapper<DocumentReference> {

// TODO: Add file Size using the uncompressed/unencoded size of the document (NIAD-2030)
// TODO: Add file Size using the uncompressed/un-encoded size of the document (NIAD-2030)

private static final String META_PROFILE = "https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-DocumentReference-1";
private static final String ABSENT_ATTACHMENT = "AbsentAttachment";
Expand All @@ -51,7 +51,7 @@ public List<DocumentReference> mapResources(RCMRMT030101UK04EhrExtract ehrExtrac
List<Encounter> encounterList, Organization organization, List<PatientAttachmentLog> attachments) {

return mapEhrExtractToFhirResource(ehrExtract, (extract, composition, component) ->
extractAllNarrativeStatements(component)
extractAllNonBloodPressureNarrativeStatements(component)
.filter(Objects::nonNull)
.filter(ResourceFilterUtil::isDocumentReference)
.map(narrativeStatement -> mapDocumentReference(narrativeStatement, composition, patient, encounterList,
Expand All @@ -60,12 +60,12 @@ public List<DocumentReference> mapResources(RCMRMT030101UK04EhrExtract ehrExtrac
}

public boolean hasDocumentReferences(RCMRMT030101UK04EhrExtract ehrExtract) {
return mapEhrExtractToFhirResource(ehrExtract, (extract, composition, component) ->
extractAllNarrativeStatements(component)
.filter(Objects::nonNull)
.filter(ResourceFilterUtil::isDocumentReference)
.map(narrativeStatement -> new DocumentReference())
).toList().size() > 0;
return !mapEhrExtractToFhirResource(ehrExtract, (extract, composition, component) ->
extractAllNonBloodPressureNarrativeStatements(component)
.filter(Objects::nonNull)
.filter(ResourceFilterUtil::isDocumentReference)
.map(narrativeStatement -> new DocumentReference())
).toList().isEmpty();
}

private DocumentReference mapDocumentReference(RCMRMT030101UK04NarrativeStatement narrativeStatement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import static org.hl7.fhir.dstu3.model.Observation.ObservationStatus.FINAL;

import static uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors.extractAllNarrativeStatements;
import static uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors.extractAllNonBloodPressureNarrativeStatements;
import static uk.nhs.adaptors.pss.translator.util.ResourceFilterUtil.isDocumentReference;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.addContextToObservation;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.buildIdentifier;
Expand Down Expand Up @@ -43,7 +43,7 @@ public List<Observation> mapResources(RCMRMT030101UK04EhrExtract ehrExtract, Pat
String practiseCode) {

return mapEhrExtractToFhirResource(ehrExtract, (extract, composition, component) ->
extractAllNarrativeStatements(component)
extractAllNonBloodPressureNarrativeStatements(component)
.filter(Objects::nonNull)
.filter(narrativeStatement -> !isDocumentReference(narrativeStatement))
.map(narrativeStatement -> mapObservation(ehrExtract, composition, narrativeStatement, patient, encounters, practiseCode)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,25 @@ public static Stream<RCMRMT030101UK04RequestStatement> extractAllRequestStatemen
);
}

public static Stream<RCMRMT030101UK04NarrativeStatement> extractAllNarrativeStatements(RCMRMT030101UK04Component4 component4) {
return Stream.concat(
Stream.of(component4.getNarrativeStatement()),
component4.hasCompoundStatement() ? CompoundStatementUtil.extractResourcesFromCompound(component4.getCompoundStatement(),
RCMRMT030101UK04Component02::hasNarrativeStatement, RCMRMT030101UK04Component02::getNarrativeStatement)
.stream()
.map(RCMRMT030101UK04NarrativeStatement.class::cast)
: Stream.empty()
);
public static Stream<RCMRMT030101UK04NarrativeStatement> extractAllNonBloodPressureNarrativeStatements(
RCMRMT030101UK04Component4 component4) {

/*
As blood pressures already map their own NarrativeStatements, we do not want to map these again if the
provided component contains a blood pressure triple.
See PR #367 AKA NIAD-2843 for details.
*/
Stream<RCMRMT030101UK04NarrativeStatement> childNarrativeStatements =
hasCompoundStatementAndIsNotBloodPressure(component4)
? CompoundStatementUtil.extractResourcesFromCompound(
component4.getCompoundStatement(),
RCMRMT030101UK04Component02::hasNarrativeStatement,
RCMRMT030101UK04Component02::getNarrativeStatement)
.stream()
.map(RCMRMT030101UK04NarrativeStatement.class::cast)
: Stream.empty();

return Stream.concat(Stream.of(component4.getNarrativeStatement()), childNarrativeStatements);
}

public static Stream<RCMRMT030101UK04MedicationStatement> extractAllMedications(RCMRMT030101UK04Component4 component4) {
Expand All @@ -149,4 +159,9 @@ private static boolean isNotAllergy(RCMRMT030101UK04CompoundStatement compoundSt
}
return true;
}

private static boolean hasCompoundStatementAndIsNotBloodPressure(RCMRMT030101UK04Component4 component4) {
return component4.hasCompoundStatement()
&& !isBloodPressureWithBatteryAndBloodPressureTriple(component4.getCompoundStatement());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ public void mapObservationsWithFullDataSingleObservation() {
assertThat(observation.getContext().getResource()).isEqualTo(encounter);
}

@Test
public void When_MappingObservationsWithBloodPressureTriple_Expect_ObservationCommentNotToBeCreated() {
var ehrExtract = unmarshallEhrExtract("narrative_statement_in_blood_pressure.xml");

var encounter = new Encounter();
encounter.setId(ENCOUNTER_ID);

List<Observation> observations = observationCommentMapper.mapResources(
ehrExtract,
patient,
Collections.singletonList(encounter),
PRACTISE_CODE);

assertThat(observations)
.hasSize(0);
}

@Test
public void mapObservationsWithFullDataMultipleObservations() {
var ehrExtract = unmarshallEhrExtract("multiple_narrative_statements.xml");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<EhrExtract xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" classCode="EXTRACT" moodCode="EVN">
<component typeCode="COMP">
<ehrFolder classCode="FOLDER" moodCode="EVN">
<component typeCode="COMP">
<ehrComposition classCode="COMPOSITION" moodCode="EVN">
<id root="58EC471C-8438-4D55-A132-BB1400FFB195"/>
<code code="196401000000100" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Non-consultation data">
<originalText>Summary Event Entry</originalText>
</code>
<statusCode code="COMPLETE"/>
<effectiveTime>
<center nullFlavor="NI"/>
</effectiveTime>
<availabilityTime value="20230912"/>
<author contextControlCode="OP" typeCode="AUT">
<time value="20230912165630"/>
<agentRef classCode="AGNT">
<id root="FD5FD24C-D657-1C3B-2F42-8334EC23A810"/>
</agentRef>
</author>
<Participant2 contextControlCode="OP" typeCode="RESP">
<agentRef classCode="AGNT">
<id root="FD5FD24C-D657-1C3B-2F42-8334EC23A810"/>
</agentRef>
</Participant2>
<component typeCode="COMP">
<CompoundStatement classCode="BATTERY" moodCode="EVN">
<id root="B7170865-DAFF-43F4-BE52-BB0979E745EB"/>
<code code="254063019" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="O/E - blood pressure reading">
<translation code="246..00" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="O/E - blood pressure reading"/>
</code>
<statusCode code="COMPLETE"/>
<effectiveTime>
<center nullFlavor="NI"/>
</effectiveTime>
<availabilityTime value="20230912"/>
<component contextConductionInd="true" typeCode="COMP">
<ObservationStatement classCode="OBS" moodCode="EVN">
<id root="E1EE7567-D740-4DCF-A676-CDB52B65E2EB"/>
<code code="120159016" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Systolic arterial pressure">
<translation code="2469.00" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="O/E - Systolic BP reading"/>
</code>
<statusCode code="COMPLETE"/>
<effectiveTime>
<center nullFlavor="NI"/>
</effectiveTime>
<availabilityTime value="20230912"/>
<value unit="1" value="120" xsi:type="PQ">
<translation value="120">
<originalText>mmHg</originalText>
</translation>
</value>
</ObservationStatement>
</component>
<component contextConductionInd="true" typeCode="COMP">
<ObservationStatement classCode="OBS" moodCode="EVN">
<id root="7E50A4D4-745A-4E5B-BFA6-39228D1D9F68"/>
<code code="2734671000000117" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Diastolic arterial pressure">
<translation code="246A.00" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="O/E - Diastolic BP reading"/>
</code>
<statusCode code="COMPLETE"/>
<effectiveTime>
<center nullFlavor="NI"/>
</effectiveTime>
<availabilityTime value="20230912"/>
<value unit="1" value="80" xsi:type="PQ">
<translation value="80">
<originalText>mmHg</originalText>
</translation>
</value>
</ObservationStatement>
</component>
<component contextConductionInd="true" typeCode="COMP">
<NarrativeStatement classCode="OBS" moodCode="EVN">
<id root="6D9AF82E-E989-49E9-B9DB-D8AF6AB4ED23"/>
<text>test uncat data</text>
<statusCode code="COMPLETE"/>
<availabilityTime value="20230912"/>
</NarrativeStatement>
</component>
</CompoundStatement>
</component>
</ehrComposition>
</component>
</ehrFolder>
</component>
</EhrExtract>

0 comments on commit dbfcda2

Please sign in to comment.