Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Niad-3114: Populate the "no disclosure to patient" label for Laboratory related resources #751

Merged
merged 17 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ corresponding FHIR resource will now be [appropriately populated][nopat-docs].
corresponding FHIR resource will now be [appropriately populated][nopat-docs].
* If a `bloodPressure` record includes a `confidentialityCode`, the `meta.security` field of the
corresponding FHIR resource will now be [appropriately populated][nopat-docs].
* If a `Observation`, `Specimen`, `DiagnosticReport` record includes a `confidentialityCode`, the `meta.security` field of the
corresponding FHIR resource will now be [appropriately populated][nopat-docs].
* Addressed a bug in the PS adaptor where immunizations were incorrectly mapped to observations.
The adaptor now verifies the Snomed CT ID against both the Concept ID and the Description ID, ensuring
that immunizations are correctly identified when a match is found.


### Fixed
* Resolved issue where the SNOMED import script would reject a password containing a '%' character.
* Fixed some Test Results being given a duplicated `Observation.category` entries for `Laboratory`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public static Stream<Arguments> ehrExtractsWithAllergyIntoleranceActualProblemCo
Arguments.of("linkset-problem-allergy-in-category.xml"),
Arguments.of("linkset-problem-allergy-flat.xml"),
Arguments.of("linkset-problem-allergy-in-topic.xml")

);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.Encounter;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.Period;
Expand All @@ -18,14 +19,18 @@
import org.hl7.v3.CR;
import org.hl7.v3.CV;
import org.hl7.v3.RCMRMT030101UKAnnotation;
import org.hl7.v3.RCMRMT030101UKCompoundStatement;
import org.hl7.v3.RCMRMT030101UKEhrComposition;
import org.hl7.v3.RCMRMT030101UKEhrExtract;
import org.hl7.v3.RCMRMT030101UKObservationStatement;
import org.hl7.v3.RCMRMT030101UKPertinentInformation02;
import org.hl7.v3.RCMRMT030101UKRequestStatement;
import org.hl7.v3.RCMRMT030101UKSubject;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import uk.nhs.adaptors.pss.translator.service.ConfidentialityService;
import uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors;
import uk.nhs.adaptors.pss.translator.util.DatabaseImmunizationChecker;
import uk.nhs.adaptors.pss.translator.util.DegradedCodeableConcepts;

Expand All @@ -40,7 +45,6 @@
import java.util.stream.Stream;

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

import static uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors.extractAllObservationStatementsWithoutAllergiesAndBloodPressures;
import static uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors.extractAllRequestStatements;
import static uk.nhs.adaptors.pss.translator.util.ObservationUtil.getEffective;
Expand All @@ -50,7 +54,6 @@
import static uk.nhs.adaptors.pss.translator.util.ObservationUtil.getValueQuantity;
import static uk.nhs.adaptors.pss.translator.util.ParticipantReferenceUtil.getParticipantReference;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.buildIdentifier;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.generateMeta;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.addContextToObservation;

@Service
Expand All @@ -66,6 +69,7 @@ public class ObservationMapper extends AbstractMapper<Observation> {

private final CodeableConceptMapper codeableConceptMapper;
private final DatabaseImmunizationChecker immunizationChecker;
private final ConfidentialityService confidentialityService;

public List<Observation> mapResources(RCMRMT030101UKEhrExtract ehrExtract, Patient patient, List<Encounter> encounters,
String practiseCode) {
Expand Down Expand Up @@ -93,45 +97,75 @@ public List<Observation> mapResources(RCMRMT030101UKEhrExtract ehrExtract, Patie
}

private Observation mapObservation(RCMRMT030101UKEhrComposition ehrComposition,
RCMRMT030101UKObservationStatement observationStatement, Patient patient, List<Encounter> encounters,
RCMRMT030101UKObservationStatement observationStatement,
Patient patient,
List<Encounter> encounters,
String practiseCode) {

var compoundStatement = ehrComposition
.getComponent()
.stream()
.flatMap(CompoundStatementResourceExtractors::extractAllCompoundStatements)
.filter(Objects::nonNull)
.findFirst().orElseGet(RCMRMT030101UKCompoundStatement::new);
ole4ryb marked this conversation as resolved.
Show resolved Hide resolved

var id = observationStatement.getId().getRoot();
var meta = confidentialityService.createMetaAndAddSecurityIfConfidentialityCodesPresent(
META_PROFILE,
ehrComposition.getConfidentialityCode(),
observationStatement.getConfidentialityCode(),
compoundStatement.getConfidentialityCode());

Observation observation = new Observation()
var observation = buildBaseObservation(ehrComposition, observationStatement, patient, practiseCode, id, meta);

addContextToObservation(observation, encounters, ehrComposition);
addValue(observation, getValueQuantity(observationStatement.getValue(), observationStatement.getUncertaintyCode()),
getValueString(observationStatement.getValue()));
addEffective(observation,
getEffective(observationStatement.getEffectiveTime(), observationStatement.getAvailabilityTime()));

return observation;
}

private @NotNull Observation buildBaseObservation(RCMRMT030101UKEhrComposition ehrComposition,
RCMRMT030101UKObservationStatement observationStatement,
Patient patient,
String practiseCode,
String id,
Meta meta) {
var observation = new Observation()
.setStatus(FINAL)
.addIdentifier(buildIdentifier(id, practiseCode))
.setCode(getCode(observationStatement.getCode()))
.setIssuedElement(getIssued(ehrComposition))
.addPerformer(getParticipantReference(observationStatement.getParticipant(), ehrComposition))
.setInterpretation(getInterpretation(observationStatement.getInterpretationCode()))
.setComment(getComment(
observationStatement.getPertinentInformation(),
observationStatement.getSubject(),
observationStatement.getCode(),
Optional.of(Optional.ofNullable(observationStatement.getCode())
observationStatement.getPertinentInformation(),
observationStatement.getSubject(),
observationStatement.getCode(),
Optional.of(Optional.ofNullable(observationStatement.getCode())
martin-nhs marked this conversation as resolved.
Show resolved Hide resolved
.map(CD::getQualifier)
.orElse(Collections.emptyList()))
))
.setReferenceRange(getReferenceRange(observationStatement.getReferenceRange()))
.setSubject(new Reference(patient));
observation.setId(id);
observation.setMeta(generateMeta(META_PROFILE));
.setSubject(new Reference(patient))
.setMeta(meta)
.setId(id);

addContextToObservation(observation, encounters, ehrComposition);
addValue(observation, getValueQuantity(observationStatement.getValue(), observationStatement.getUncertaintyCode()),
getValueString(observationStatement.getValue()));
addEffective(observation,
getEffective(observationStatement.getEffectiveTime(), observationStatement.getAvailabilityTime()));

return observation;
return (Observation) observation;
ole4ryb marked this conversation as resolved.
Show resolved Hide resolved
}

private Observation mapObservationFromRequestStatement(RCMRMT030101UKEhrComposition ehrComposition,
RCMRMT030101UKRequestStatement requestStatement, Patient patient,
List<Encounter> encounters, String practiseCode) {

var id = requestStatement.getId().get(0).getRoot();
var meta = confidentialityService.createMetaAndAddSecurityIfConfidentialityCodesPresent(
META_PROFILE,
ehrComposition.getConfidentialityCode(),
requestStatement.getConfidentialityCode());


Observation observation = new Observation()
.setStatus(FINAL)
Expand All @@ -144,7 +178,7 @@ private Observation mapObservationFromRequestStatement(RCMRMT030101UKEhrComposit
.setComponent(createComponentList(requestStatement));

observation.setId(id);
observation.setMeta(generateMeta(META_PROFILE));
observation.setMeta(meta);

addContextToObservation(observation, encounters, ehrComposition);
addEffective(observation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import static uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors.extractAllCompoundStatements;
import static uk.nhs.adaptors.pss.translator.util.DateFormatUtil.parseToInstantType;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.buildIdentifier;
import static uk.nhs.adaptors.pss.translator.util.ResourceUtil.generateMeta;
import static uk.nhs.adaptors.pss.translator.util.TextUtil.extractPmipComment;

import java.util.ArrayList;
Expand Down Expand Up @@ -41,6 +40,7 @@
import org.springframework.stereotype.Service;

import uk.nhs.adaptors.pss.translator.mapper.AbstractMapper;
import uk.nhs.adaptors.pss.translator.service.ConfidentialityService;
import uk.nhs.adaptors.pss.translator.service.IdGeneratorService;
import uk.nhs.adaptors.pss.translator.util.CompoundStatementResourceExtractors;
import uk.nhs.adaptors.pss.translator.util.ResourceFilterUtil;
Expand All @@ -61,6 +61,7 @@ public class DiagnosticReportMapper extends AbstractMapper<DiagnosticReport> {
public static final String USER_COMMENT_COMMENT_TYPE = "CommentType:USER COMMENT";

private final IdGeneratorService idGeneratorService;
private final ConfidentialityService confidentialityService;

public static void addResultToDiagnosticReport(Observation observation, DiagnosticReport diagnosticReport) {
if (!containsReference(diagnosticReport.getResult(), observation.getId())) {
Expand Down Expand Up @@ -126,7 +127,12 @@ private DiagnosticReport createDiagnosticReport(RCMRMT030101UKCompoundStatement
final DiagnosticReport diagnosticReport = new DiagnosticReport();
final String id = compoundStatement.getId().get(0).getRoot();

diagnosticReport.setMeta(generateMeta(META_PROFILE_URL_SUFFIX));
var meta = confidentialityService.createMetaAndAddSecurityIfConfidentialityCodesPresent(
META_PROFILE_URL_SUFFIX,
ole4ryb marked this conversation as resolved.
Show resolved Hide resolved
composition.getConfidentialityCode(),
compoundStatement.getConfidentialityCode());

diagnosticReport.setMeta(meta);
diagnosticReport.setId(id);
diagnosticReport.addIdentifier(buildIdentifier(id, practiceCode));
diagnosticReport.setCode(createCode());
Expand Down
Loading