diff --git a/CHANGELOG.md b/CHANGELOG.md index 78cbf4696..72e9ba013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * The GP2GP Adaptor now throws an exception when the Access Structure Record is empty, thereby rejecting the transfer ### Fixed -* When DiagnosticReport doesn't contain a Specimen reference, instead of "DUMMY" "NOT-PRESENT" value is used +* When DiagnosticReport doesn't contain a Specimen or Observation reference, instead of "DUMMY" "NOT-PRESENT" value is used ### Update diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapper.java index 8cee1400c..e34c99435 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapper.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapper.java @@ -53,7 +53,7 @@ public class DiagnosticReportMapper { public static final String NOT_PRESENT_SPECIMEN_ID_PREFIX = "NOT-PRESENT-SPECIMEN-"; - public static final String DUMMY_OBSERVATION_ID_PREFIX = "DUMMY-OBSERVATION-"; + public static final String NOT_PRESENT_OBSERVATION_ID_PREFIX = "NOT-PRESENT-OBSERVATION-"; private static final Mustache DIAGNOSTIC_REPORT_COMPOUND_STATEMENT_TEMPLATE = TemplateUtils.loadTemplate("diagnostic_report_compound_statement_template.mustache"); @@ -80,25 +80,25 @@ public String mapDiagnosticReportToCompoundStatement(DiagnosticReport diagnostic final IdMapper idMapper = messageContext.getIdMapper(); markObservationsAsProcessed(idMapper, observations); - List observationsWithAttachedDummySpecimens = - new ArrayList<>(assignDummySpecimensToObservationsWithNoSpecimen(observations, specimens)); + List observationsWithAttachedNotPresentSpecimens = + new ArrayList<>(assignNotPresentSpecimensToObservationsWithNoSpecimen(observations, specimens)); - observations = addDummyObservationsToObservationList( - observationsWithAttachedDummySpecimens, + observations = addNotPresentObservationsToObservationList( + observationsWithAttachedNotPresentSpecimens, specimens, diagnosticReport); - List observationsWithDummySpecimensAndDummyObservations = observations; + List observationsWithNotPresentSpecimensAndNotPresentObservations = observations; String mappedSpecimens = specimens.stream() .map(specimen -> specimenMapper.mapSpecimenToCompoundStatement(specimen, - observationsForSpecimen(specimen, observationsWithDummySpecimensAndDummyObservations), + observationsForSpecimen(specimen, observationsWithNotPresentSpecimensAndNotPresentObservations), diagnosticReport)) .collect(Collectors.joining()); String reportLevelNarrativeStatements = prepareReportLevelNarrativeStatements( diagnosticReport, - observationsWithDummySpecimensAndDummyObservations); + observationsWithNotPresentSpecimensAndNotPresentObservations); var diagnosticReportCompoundStatementTemplateParameters = DiagnosticReportCompoundStatementTemplateParameters.builder() .compoundStatementId(idMapper.getOrNew(ResourceType.DiagnosticReport, diagnosticReport.getIdElement())) @@ -146,14 +146,14 @@ private List fetchSpecimens(DiagnosticReport diagnosticReport, List nonDummySpecimens = diagnosticReport.getSpecimen() + List nonNotPresentSpecimens = diagnosticReport.getSpecimen() .stream() .map(specimenReference -> inputBundleHolder.getResource(specimenReference.getReferenceElement())) .flatMap(Optional::stream) .map(Specimen.class::cast) .toList(); - specimens.addAll(nonDummySpecimens); + specimens.addAll(nonNotPresentSpecimens); return specimens; } @@ -166,9 +166,9 @@ private boolean hasObservationsWithoutSpecimen(List observations) { } /** - * For correct display in EMIS, any observation without a specimen must be assigned a dummy specimen. + * For correct display in EMIS, any observation without a specimen must be assigned a not present specimen. */ - List assignDummySpecimensToObservationsWithNoSpecimen(List observations, List specimens) { + List assignNotPresentSpecimensToObservationsWithNoSpecimen(List observations, List specimens) { List filingComments = getFilingComments(observations); List nonFilingObservations = new ArrayList<>(stripFilingComments(observations)); @@ -178,7 +178,7 @@ List assignDummySpecimensToObservationsWithNoSpecimen(List specimen.getId().contains(NOT_PRESENT_SPECIMEN_ID_PREFIX)) .toList().getFirst(); @@ -219,21 +219,21 @@ private List fetchObservations(DiagnosticReport diagnosticReport) { } /** - * For correct display in EMIS, any specimen without an observation must be assigned a dummy observation. + * For correct display in EMIS, any specimen without an observation must be assigned a not present observation. */ - private List addDummyObservationsToObservationList( + private List addNotPresentObservationsToObservationList( List observations, List specimens, DiagnosticReport diagnosticReport) { List completeObservations = new ArrayList<>(); completeObservations.addAll(observations); - // Generate a dummy Observation for each Specimen without an Observation + // Generate a not present Observation for each Specimen without an Observation for (String specimenWithoutObservations : getSpecimenIdsWithoutObservation(specimens, observations)) { - Observation dummyObservation = generateDummyObservation(diagnosticReport); + Observation notPresentObservation = generateNotPresentObservation(diagnosticReport); Reference specimenReference = new Reference(specimenWithoutObservations); - dummyObservation.setSpecimen(specimenReference); - completeObservations.add(dummyObservation); + notPresentObservation.setSpecimen(specimenReference); + completeObservations.add(notPresentObservation); } return completeObservations; @@ -243,7 +243,7 @@ private List getSpecimenIdsWithoutObservation(List specimens, List specimenIDList = new ArrayList<>(); List nonOrphanSpecimenIDList = new ArrayList<>(); for (Specimen specimen : specimens) { - // Dummy Specimens should not have a dummy observation attached. + // Not present Specimens should not have a not present observation attached. if (!specimen.getId().contains(NOT_PRESENT_SPECIMEN_ID_PREFIX)) { specimenIDList.add(specimen.getId()); } @@ -264,10 +264,10 @@ private List getSpecimenIdsWithoutObservation(List specimens, return specimensWithoutObservations; } - private Observation generateDummyObservation(DiagnosticReport diagnosticReport) { + private Observation generateNotPresentObservation(DiagnosticReport diagnosticReport) { Observation observation = new Observation(); - observation.setId(DUMMY_OBSERVATION_ID_PREFIX + randomIdGeneratorService.createNewId()); + observation.setId(NOT_PRESENT_OBSERVATION_ID_PREFIX + randomIdGeneratorService.createNewId()); return observation .setIssuedElement(diagnosticReport.getIssuedElement()) diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapper.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapper.java index 54c20c8bf..1e27a27b6 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapper.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapper.java @@ -1,6 +1,5 @@ package uk.nhs.adaptors.gp2gp.ehr.mapper.diagnosticreport; -import static uk.nhs.adaptors.gp2gp.ehr.mapper.diagnosticreport.DiagnosticReportMapper.DUMMY_OBSERVATION_ID_PREFIX; import java.util.List; import java.util.Objects; @@ -46,6 +45,8 @@ import uk.nhs.adaptors.gp2gp.ehr.utils.StatementTimeMappingUtils; import uk.nhs.adaptors.gp2gp.ehr.utils.TemplateUtils; +import static uk.nhs.adaptors.gp2gp.ehr.mapper.diagnosticreport.DiagnosticReportMapper.NOT_PRESENT_OBSERVATION_ID_PREFIX; + @Component @RequiredArgsConstructor(onConstructor = @__(@Autowired)) @Slf4j @@ -240,7 +241,7 @@ private String mapObservationToObservationStatement(MultiStatementObservationHol private Optional prepareNarrativeStatements(MultiStatementObservationHolder holder, boolean interpretationCodeMapped) { Observation observation = holder.getObservation(); - if (observation.getIdElement().getIdPart().contains(DUMMY_OBSERVATION_ID_PREFIX)) { + if (observation.getIdElement().getIdPart().contains(NOT_PRESENT_OBSERVATION_ID_PREFIX)) { return Optional.of( mapObservationToNarrativeStatement(holder, observation.getComment(), CommentType.AGGREGATE_COMMENT_SET.getCode()) ); diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapperTest.java index 7d491c5b9..805ca40ba 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/DiagnosticReportMapperTest.java @@ -155,7 +155,7 @@ void shouldAssignDummySpecimenOnlyToNonFilingObservationsWithoutSpecimen() { dummySpecimen.setId(NOT_PRESENT_SPECIMEN_ID_PREFIX + "123"); List specimens = List.of(dummySpecimen); - List result = mapper.assignDummySpecimensToObservationsWithNoSpecimen(observations, specimens); + List result = mapper.assignNotPresentSpecimensToObservationsWithNoSpecimen(observations, specimens); assertThat(obsWithoutSpecimen.getSpecimen()) .isNotNull() @@ -178,7 +178,7 @@ void shouldThrowIfNoDummySpecimenFound() { List specimens = List.of(); - assertThatThrownBy(() -> mapper.assignDummySpecimensToObservationsWithNoSpecimen(observations, specimens)) + assertThatThrownBy(() -> mapper.assignNotPresentSpecimensToObservationsWithNoSpecimen(observations, specimens)) .isInstanceOf(NoSuchElementException.class); } @@ -197,7 +197,7 @@ void shouldAssignDummySpecimenToObservationsWithoutSpecimen() { realSpecimen.setId("real-specimen"); List specimens = List.of(realSpecimen, dummySpecimen); - List result = mapper.assignDummySpecimensToObservationsWithNoSpecimen(observations, specimens); + List result = mapper.assignNotPresentSpecimensToObservationsWithNoSpecimen(observations, specimens); assertThat(result).hasSize(2); assertThat(result.get(0).getSpecimen().getReference()).contains(dummySpecimen.getId()); @@ -412,7 +412,7 @@ void When_DiagnosticReport_Has_MultipleSpecimensAndOneObservation_Expect_ADummyO assertThat(actualXml).containsIgnoringWhitespaces( ""); + + "with linked Observations: NOT-PRESENT-OBSERVATION-5E496953-065B-41F2-9577-BE8F2FBD0757-->"); } @@ -438,11 +438,11 @@ void When_DiagnosticReport_Has_ThreeSpecimensAndOneObservation_Expect_DummyObser assertThat(actualXml).containsIgnoringWhitespaces( ""); + + "with linked Observations: NOT-PRESENT-OBSERVATION-5E496953-065B-41F2-9577-BE8F2FBD0757-->"); assertThat(actualXml).containsIgnoringWhitespaces( ""); + + "with linked Observations: NOT-PRESENT-OBSERVATION-5E496953-065B-41F2-9577-BE8F2FBD0757-->"); } /** @@ -472,7 +472,7 @@ void When_DiagnosticReport_Has_TwoLinkedSpecimensOneUnlinkedSpecimenAndOneObserv assertThat(actualXml).containsIgnoringWhitespaces( ""); + + "with linked Observations: NOT-PRESENT-OBSERVATION-5E496953-065B-41F2-9577-BE8F2FBD0757-->"); } @Test diff --git a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapperTest.java b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapperTest.java index 9dd07046e..7f185feca 100644 --- a/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapperTest.java +++ b/service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/diagnosticreport/ObservationMapperTest.java @@ -90,6 +90,8 @@ class ObservationMapperTest { "observation_test_group_header.json"; private static final String OBSERVATION_TEST_RESULT_JSON = "observation_test_result.json"; + private static final String NOT_PRESENT_OBSERVATION_RESULT_JSON = + "not_present_observation.json"; private static final String OBSERVATION_FILING_COMMENT_JSON = "observation_filing_comment.json"; private static final String OBSERVATION_ASSOCIATED_WITH_IGNORED_MEMBER_JSON = @@ -273,6 +275,21 @@ void When_MappingTestResult_With_NopatMetaSecurity_Expect_ConfidentialityCodeWit assertThatXml(actualXml).containsXPath(OBSERVATION_STATEMENT_CONFIDENTIALITY_CODE_XPATH); } + @Test + void When_ObservationDoesNotContainNotPresentElements_Expect_MappedObservetionNotContainAggregateComments() { + final Observation not_present_observation = getObservationResourceFromJson(NOT_PRESENT_OBSERVATION_RESULT_JSON); + String expression = "//component/NarrativeStatement/text[contains(normalize-space(.), 'AGGREGATE COMMENT SET')]"; + + ConfidentialityCodeUtility.appendNopatSecurityToMetaForResource(not_present_observation); + when(confidentialityService.generateConfidentialityCode(not_present_observation)) + .thenReturn(Optional.of(NOPAT_HL7_CONFIDENTIALITY_CODE)); + + final String actualXml = observationMapper.mapObservationToCompoundStatement(not_present_observation); + String wrappedXml = "" + actualXml + ""; + + assertThatXml(wrappedXml).containsXPath(expression); + } + @Test void When_MappingTestResult_With_NoscrubMetaSecurity_Expect_ConfidentialityCodeNotPresent() { final Observation observation = getObservationResourceFromJson(OBSERVATION_TEST_RESULT_JSON); diff --git a/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-multi-specimens.xml b/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-multi-specimens.xml index 905d6f05f..adc598396 100644 --- a/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-multi-specimens.xml +++ b/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-multi-specimens.xml @@ -20,8 +20,8 @@ Status: unknown - - - + + + \ No newline at end of file diff --git a/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-one-specimen.xml b/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-one-specimen.xml index 837442480..fc9187488 100644 --- a/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-one-specimen.xml +++ b/service/src/test/resources/ehr/mapper/diagnosticreport/diagnostic-report-with-one-specimen.xml @@ -20,6 +20,6 @@ Status: unknown - + \ No newline at end of file diff --git a/service/src/test/resources/ehr/mapper/diagnosticreport/observation/not_present_observation.json b/service/src/test/resources/ehr/mapper/diagnosticreport/observation/not_present_observation.json new file mode 100644 index 000000000..79e1125bc --- /dev/null +++ b/service/src/test/resources/ehr/mapper/diagnosticreport/observation/not_present_observation.json @@ -0,0 +1,55 @@ +{ + "resourceType": "Observation", + "id": "NOT-PRESENT-OBSERVATION-32685afe-1d46-4d98-8279-39b9e96ee914", + "meta": + { + "profile": [ + "https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-Observation-1" + ] + }, + "identifier": [ + { + "system": "https://tools.ietf.org/html/rfc4122", + "value": "2af46949-4938-4c57-bad4-c4363e1965d7" + } + ], + "status": "final", + "category": [ + { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "394595002", + "display": "Pathology" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "1022451000000103", + "display": "Red blood cell count" + } + ] + }, + "subject": { + "reference": "Patient/11", + "display": "SKELLY, Horace" + }, + "issued": "2019-04-06T12:00:00+00:00", + "performer": [ + { + "reference": "Organization/7", + "display": "COXWOLD Surgery" + } + ], + "valueQuantity": { + "value": 4.5700000000000003, + "unit": "10*12/L" + }, + "specimen": { + "reference": "Specimen/756a8361-79ce-4561-afcb-a91fe19df123" + } +} \ No newline at end of file