Skip to content

Commit

Permalink
feat: add initial SystemischeTherapieMapper
Browse files Browse the repository at this point in the history
  • Loading branch information
pcvolkmer committed Nov 20, 2024
1 parent 75a545e commit f14d925
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public static class FhirSystems {
private String miiCsOnkoStrahlentherapieStrahlenart;
private String miiCsOnkoStrahlentherapieZielgebiet;
private String strahlentherapieProcedureId;
private String systemischeTherapieProcedureId;
private String miiCsOnkoSeitenlokalisation;
private String conditionVerStatus;
private String icdo3MorphologieOid;
Expand All @@ -95,6 +96,7 @@ public static class FhirProfiles {
private String deathObservation;
private String miiPrOnkoDiagnosePrimaertumor;
private String miiPrOnkoStrahlentherapie;
private String miiPrOnkoSystemischeTherapie;
}

@Data
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.miracum.streams.ume.obdstofhir.mapper.mii;

import de.basisdatensatz.obds.v3.SYSTTyp;
import java.util.Objects;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.DateTimeType;
import org.hl7.fhir.r4.model.Enumerations.ResourceType;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Period;
import org.hl7.fhir.r4.model.Procedure;
import org.hl7.fhir.r4.model.Reference;
import org.miracum.streams.ume.obdstofhir.FhirProperties;
import org.miracum.streams.ume.obdstofhir.mapper.ObdsToFhirMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class SystemischeTherapieMapper extends ObdsToFhirMapper {

private static final Logger LOG = LoggerFactory.getLogger(SystemischeTherapieMapper.class);

public SystemischeTherapieMapper(FhirProperties fhirProperties) {
super(fhirProperties);
}

public Procedure map(SYSTTyp syst, Reference subject) {
Objects.requireNonNull(syst, "Systemtherapie must not be null");
Objects.requireNonNull(subject, "Reference must not be null");

Validate.notBlank(syst.getSYSTID(), "Required SYST_ID is unset");
Validate.isTrue(
Objects.equals(
subject.getReferenceElement().getResourceType(), ResourceType.PATIENT.toCode()),
"The subject reference should point to a Patient resource");

var procedure = new Procedure();
procedure.getMeta().addProfile(fhirProperties.getProfiles().getMiiPrOnkoSystemischeTherapie());

// TODO: can we be sure that this SYST-ID is globally unqiue across all SYSTs? -
// if not we may instead need to construct the ID from the patient-id + others.
var identifier =
new Identifier()
.setSystem(fhirProperties.getSystems().getSystemischeTherapieProcedureId())
.setValue(syst.getSYSTID());
procedure.addIdentifier(identifier);
procedure.setId(computeResourceIdFromIdentifier(identifier));

// Status
if (syst.getMeldeanlass() == SYSTTyp.Meldeanlass.BEHANDLUNGSENDE) {
procedure.setStatus(Procedure.ProcedureStatus.COMPLETED);
} else {
procedure.setStatus(Procedure.ProcedureStatus.INPROGRESS);
}

procedure.setSubject(subject);

var dataAbsentExtension =
new Extension(
fhirProperties.getExtensions().getDataAbsentReason(), new CodeType("unknown"));
var dataAbsentCode = new CodeType();
dataAbsentCode.addExtension(dataAbsentExtension);

if (syst.getBeginn() == null && syst.getEnde() == null) {
var performedStart = new DateTimeType();
performedStart.addExtension(dataAbsentExtension);
var performed = new Period().setStartElement(performedStart);
procedure.setPerformed(performed);
} else {
var performed = new Period();
var performedStart = new DateTimeType();
performedStart.setValue(syst.getBeginn().getValue().toGregorianCalendar().getTime());
performed.setStartElement(performedStart);
if (syst.getEnde() != null) {
var performedEnd = new DateTimeType();
performedEnd.setValue(syst.getEnde().toGregorianCalendar().getTime());
performed.setEndElement(performedEnd);
}
procedure.setPerformed(performed);
}

// TODO: Same as in Strahlentherapie?
var category =
new CodeableConcept(
new Coding(
fhirProperties.getSystems().getSnomed(), "277132007", "Therapeutic procedure"));
procedure.setCategory(category);



return procedure;
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fhir:
gleasonScoreObservationId: "${fhir.default.baseSystemUrl}/obds-to-fhir/identifiers/gleason-score-observation-id"
psaObservationId: "${fhir.default.baseSystemUrl}/obds-to-fhir/identifiers/psa-observation-id"
strahlentherapie-procedure-id: "${fhir.default.baseSystemUrl}/obds-to-fhir/identifiers/strahlentherapie-procedure-id"
systemische-therapie-procedure-id: "${fhir.default.baseSystemUrl}/obds-to-fhir/identifiers/systemische-therapie-procedure-id"
loinc: "http://loinc.org"
icdo3Morphologie: "http://terminology.hl7.org/CodeSystem/icd-o-3"
icdo3MorphologieOid: "urn:oid:2.16.840.1.113883.6.43.1"
Expand Down Expand Up @@ -81,6 +82,7 @@ fhir:
mii-patient-pseudonymisiert: "https://www.medizininformatik-initiative.de/fhir/core/modul-person/StructureDefinition/PatientPseudonymisiert"
mii-pr-onko-diagnose-primaertumor: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-diagnose-primaertumor"
mii-pr-onko-strahlentherapie: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-strahlentherapie"
mii-pr-onko-systemische-therapie: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-systemische-therapie"
display:
histologyLoinc: "Histology and Behavior ICD-O-3 Cancer"
gradingLoinc: "Grade pathology value Cancer"
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/schema/oBDS_v3.0.3.bindings.xjb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
</jaxb:bindings>
<jaxb:bindings node="//xs:complexType[@name='ST_Typ']//xs:element[@name='Meldeanlass']/xs:simpleType">
<jaxb:typesafeEnumClass name="Meldeanlass" />
</jaxb:bindings>
<jaxb:bindings node="//xs:complexType[@name='SYST_Typ']//xs:element[@name='Meldeanlass']/xs:simpleType">
<jaxb:typesafeEnumClass name="Meldeanlass" />
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.miracum.streams.ume.obdstofhir.mapper.mii;

import static org.assertj.core.api.Assertions.assertThat;

import ca.uhn.fhir.context.FhirContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationModule;
import de.basisdatensatz.obds.v3.OBDS;
import java.io.IOException;
import org.approvaltests.Approvals;
import org.hl7.fhir.r4.model.Reference;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.miracum.streams.ume.obdstofhir.FhirProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(classes = {FhirProperties.class})
@EnableConfigurationProperties
class SystemischeTherapieMapperTest {
private static SystemischeTherapieMapper sut;

@BeforeAll
static void beforeEach(@Autowired FhirProperties fhirProps) {
sut = new SystemischeTherapieMapper(fhirProps);
}

@ParameterizedTest
@CsvSource({"Testpatient_1.xml", "Testpatient_2.xml", "Testpatient_3.xml"})
void map_withGivenObds_shouldCreateValidProcedure(String sourceFile) throws IOException {
final var resource = this.getClass().getClassLoader().getResource("obds3/" + sourceFile);
assertThat(resource).isNotNull();

final var xmlMapper =
XmlMapper.builder()
.defaultUseWrapper(false)
.addModule(new JakartaXmlBindAnnotationModule())
.addModule(new Jdk8Module())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.build();

final var obds = xmlMapper.readValue(resource.openStream(), OBDS.class);

var obdsPatient = obds.getMengePatient().getPatient().getFirst();

var subject = new Reference("Patient/any");
var systMeldung =
obdsPatient.getMengeMeldung().getMeldung().stream()
.filter(m -> m.getSYST() != null)
.findFirst()
.get();
var procedure = sut.map(systMeldung.getSYST(), subject);

var fhirParser = FhirContext.forR4().newJsonParser().setPrettyPrint(true);
var fhirJson = fhirParser.encodeResourceToString(procedure);
Approvals.verify(
fhirJson, Approvals.NAMES.withParameters(sourceFile).forFile().withExtension(".fhir.json"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"resourceType": "Procedure",
"id": "8e5a61d808bb30074e894fc702086b24763c410267b91c86f75de0b3b6507ccf",
"meta": {
"profile": [ "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-systemische-therapie" ]
},
"identifier": [ {
"system": "https://bzkf.github.io/obds-to-fhir/identifiers/systemische-therapie-procedure-id",
"value": "101_IN-1"
} ],
"status": "completed",
"category": {
"coding": [ {
"system": "http://snomed.info/sct",
"code": "277132007",
"display": "Therapeutic procedure"
} ]
},
"subject": {
"reference": "Patient/any"
},
"performedPeriod": {
"start": "2020-05-01T02:00:00+02:00",
"end": "2020-10-15T02:00:00+02:00"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"resourceType": "Procedure",
"id": "fbc045f02f136bf06dcbf1c9002d85d86ae87ec317fdb0b10a23a4cc76ba2fc2",
"meta": {
"profile": [ "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-systemische-therapie" ]
},
"identifier": [ {
"system": "https://bzkf.github.io/obds-to-fhir/identifiers/systemische-therapie-procedure-id",
"value": "11_1_Innere.1"
} ],
"status": "in-progress",
"category": {
"coding": [ {
"system": "http://snomed.info/sct",
"code": "277132007",
"display": "Therapeutic procedure"
} ]
},
"subject": {
"reference": "Patient/any"
},
"performedPeriod": {
"start": "2021-11-08T01:00:00+01:00"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"resourceType": "Procedure",
"id": "e722bcc3a86e05e00a0fe5566607b4293be976500750ed2de2f48280b7fba359",
"meta": {
"profile": [ "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-systemische-therapie" ]
},
"identifier": [ {
"system": "https://bzkf.github.io/obds-to-fhir/identifiers/systemische-therapie-procedure-id",
"value": "12_1_Innere.1"
} ],
"status": "in-progress",
"category": {
"coding": [ {
"system": "http://snomed.info/sct",
"code": "277132007",
"display": "Therapeutic procedure"
} ]
},
"subject": {
"reference": "Patient/any"
},
"performedPeriod": {
"start": "2018-03-17T01:00:00+01:00"
}
}

0 comments on commit f14d925

Please sign in to comment.