From 87a6b63dc2084e0fa49c989a1bb8fec0acc4050e Mon Sep 17 00:00:00 2001 From: chgl Date: Tue, 7 May 2024 07:58:53 +0200 Subject: [PATCH 1/4] fix: handle Primaertumor_ICD_Version being unset or not matching regex (#39) * fix: handle Primaertumor_ICD_Version being unset or not matching regex * fix: handle Meldung.Diagnose.Primaertumor_* unset and default to TumorZuordnung * fix: use distinct ID when condition is generated from a tumorzuordnung avoids overriding existing resources but may cause duplicate diagnosis being present * test: added snapshot tests for previously failing data --- .../mapper/ObdsConditionMapper.java | 46 +++++--- .../ObdsObservationProcessorTest.java | 33 ++++++ .../processor/ObdsProcessorTest.java | 2 +- ...pshot.diagnosis_set.xml.approved.fhir.json | 39 +++++++ ...hot.diagnosis_unset.xml.approved.fhir.json | 51 ++++++++ src/test/resources/diagnosis_set.xml | 110 ++++++++++++++++++ src/test/resources/diagnosis_unset.xml | 107 +++++++++++++++++ 7 files changed, 374 insertions(+), 14 deletions(-) create mode 100644 src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_set.xml.approved.fhir.json create mode 100644 src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_unset.xml.approved.fhir.json create mode 100644 src/test/resources/diagnosis_set.xml create mode 100644 src/test/resources/diagnosis_unset.xml diff --git a/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsConditionMapper.java b/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsConditionMapper.java index 0106f8c9..c2b01a3c 100644 --- a/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsConditionMapper.java +++ b/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsConditionMapper.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; import org.hl7.fhir.r4.model.*; import org.miracum.streams.ume.obdstofhir.FhirProperties; import org.miracum.streams.ume.obdstofhir.lookup.*; @@ -12,12 +13,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; @Configuration public class ObdsConditionMapper extends ObdsToFhirMapper { private static final Logger LOG = LoggerFactory.getLogger(ObdsConditionMapper.class); + private static final Pattern icdVersionPattern = + Pattern.compile("^(10 (?20\\d{2}) ((GM)|(WHO))|Sonstige)$"); + @Value("${app.version}") private String appVersion; @@ -64,8 +69,12 @@ public Bundle mapOnkoResourcesToCondition( ADT_GEKID.PrimaryConditionAbs primDia = meldung.getDiagnose(); - // diagnose Tag ist only specified in meldeanlass 'diagnose', otherwise use tag 'Tumorzuordung' - if (primDia == null) { + // Diagnose Element is only fully specified in meldeanlass 'diagnose', otherwise use element + // 'Tumorzuordung' + // It's possible that 'Meldung.Diagnose' is set but 'Meldung.Diagnose.Primaertumor_*' is not, + // in that case also use the TumorZuordnung to construct the Condition. + var useTumorZuordnung = primDia == null || primDia.getPrimaertumor_ICD_Code() == null; + if (useTumorZuordnung) { primDia = meldung.getTumorzuordnung(); if (primDia == null) { @@ -80,6 +89,9 @@ public Bundle mapOnkoResourcesToCondition( } var conIdentifier = pid + "condition" + primDia.getTumor_ID(); + if (useTumorZuordnung) { + conIdentifier += "-from-tumorzuordnung"; + } onkoCondition.setId(this.getHash(ResourceType.Condition, conIdentifier)); @@ -94,18 +106,26 @@ public Bundle mapOnkoResourcesToCondition( .getMeta() .setProfile(List.of(new CanonicalType(fhirProperties.getProfiles().getCondition()))); - var coding = new Coding(); - var icd10Version = primDia.getPrimaertumor_ICD_Version(); - // Aufbau: "10 2021 GM" - String[] icdVersionArray = icd10Version.split(" "); - - if (icdVersionArray.length == 3 && icdVersionArray[1].matches("^20\\d{2}$")) { - coding.setVersion(icdVersionArray[1]); - } // FIXME: else throw exception? + var coding = + new Coding() + .setCode(primDia.getPrimaertumor_ICD_Code()) + .setSystem(fhirProperties.getSystems().getIcd10gm()); - coding - .setCode(primDia.getPrimaertumor_ICD_Code()) - .setSystem(fhirProperties.getSystems().getIcd10gm()); + // Aufbau: "10 2021 GM" + var icd10Version = primDia.getPrimaertumor_ICD_Version(); + if (StringUtils.hasLength(icd10Version)) { + var matcher = icdVersionPattern.matcher(icd10Version); + if (matcher.matches()) { + coding.setVersion(matcher.group("versionYear")); + } else { + LOG.warn( + "Primaertumor_ICD_Version doesn't match expected format. Expected: '{}', actual: '{}'", + icdVersionPattern.pattern(), + icd10Version); + } + } else { + LOG.warn("Primaertumor_ICD_Version is unset or contains only whitespaces"); + } var conditionCode = new CodeableConcept().addCoding(coding); onkoCondition.setCode(conditionCode); diff --git a/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.java b/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.java index 8211a138..790392b6 100644 --- a/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.java +++ b/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.java @@ -6,11 +6,13 @@ import java.io.IOException; import java.util.*; import java.util.stream.Stream; +import org.apache.commons.lang3.tuple.Pair; import org.approvaltests.Approvals; import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.Observation; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.MethodSource; import org.miracum.streams.ume.obdstofhir.FhirProperties; import org.miracum.streams.ume.obdstofhir.mapper.*; @@ -194,4 +196,35 @@ void mapObservation_withGivenAdtXml( .withExtension(".fhir.json")); } } + + @ParameterizedTest + @CsvSource({"diagnosis_set.xml", "diagnosis_unset.xml"}) + void mapObservation_withGivenObdsXml_shouldMatchSnapshot(String resourceXmlName) + throws IOException { + + var meldungExportList = + buildMeldungExportList(List.of(new Tupel(resourceXmlName, 1))); + + var onkoProcessor = + new ObdsProcessor( + fhirProps, + onkoMedicationStatementMapper, + onkoObservationMapper, + onkoProcedureMapper, + onkoPatientMapper, + onkoConditionMapper); + + var observResultBundle = + onkoProcessor.getOnkoToObservationBundleMapper().apply(meldungExportList); + + var resultBundle = + onkoProcessor + .getOnkoToConditionBundleMapper() + .apply(Pair.of(meldungExportList, observResultBundle)); + + var fhirJson = fhirParser.encodeResourceToString(resultBundle); + Approvals.verify( + fhirJson, + Approvals.NAMES.withParameters(resourceXmlName).forFile().withExtension(".fhir.json")); + } } diff --git a/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsProcessorTest.java b/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsProcessorTest.java index ab9e4b20..cd94228e 100644 --- a/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsProcessorTest.java +++ b/src/test/java/org/miracum/streams/ume/obdstofhir/processor/ObdsProcessorTest.java @@ -64,7 +64,7 @@ protected MeldungExportList buildMeldungExportList(List> Map payloadOnkoRessource = new HashMap<>(); payloadOnkoRessource.put("ID", payloadId); payloadOnkoRessource.put("REFERENZ_NUMMER", patId); - payloadOnkoRessource.put("LKR_MELDUNG", Integer.parseInt(meldungsId.replace(melderId, ""))); + payloadOnkoRessource.put("LKR_MELDUNG", meldungsId.replace(melderId, "")); payloadOnkoRessource.put("VERSIONSNUMMER", xmlTupel.getSecond()); payloadOnkoRessource.put("XML_DATEN", xmlContent); diff --git a/src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_set.xml.approved.fhir.json b/src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_set.xml.approved.fhir.json new file mode 100644 index 00000000..85fbcd34 --- /dev/null +++ b/src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_set.xml.approved.fhir.json @@ -0,0 +1,39 @@ +{ + "resourceType": "Bundle", + "type": "transaction", + "entry": [ { + "fullUrl": "Condition/04c8f27ca021b8fd87ffd3abbde1f4b907bb3d6921fd61c5d4b9a0a756b8d110", + "resource": { + "resourceType": "Condition", + "id": "04c8f27ca021b8fd87ffd3abbde1f4b907bb3d6921fd61c5d4b9a0a756b8d110", + "meta": { + "source": "KR7X825X.ONKOSTAR:obds-to-fhir:0.0.0-test", + "profile": [ "http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Condition-Primaerdiagnose" ] + }, + "code": { + "coding": [ { + "system": "http://fhir.de/CodeSystem/bfarm/icd-10-gm", + "version": "2010", + "code": "C43.5" + } ] + }, + "subject": { + "reference": "Patient/19cc75fbfb51266ac0149828ae2f8522106e3ba176ceac2b40acb3cb1c9365f9", + "identifier": { + "type": { + "coding": [ { + "system": "http://terminology.hl7.org/CodeSystem/v2-0203", + "code": "MR" + } ] + }, + "system": "https://fhir.diz.uk-erlangen.de/identifiers/patient-id", + "value": "0001234567" + } + } + }, + "request": { + "method": "PUT", + "url": "Condition/04c8f27ca021b8fd87ffd3abbde1f4b907bb3d6921fd61c5d4b9a0a756b8d110" + } + } ] +} \ No newline at end of file diff --git a/src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_unset.xml.approved.fhir.json b/src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_unset.xml.approved.fhir.json new file mode 100644 index 00000000..b27a159f --- /dev/null +++ b/src/test/java/snapshots/org/miracum/streams/ume/obdstofhir/processor/ObdsObservationProcessorTest.mapObservation_withGivenObdsXml_shouldMatchSnapshot.diagnosis_unset.xml.approved.fhir.json @@ -0,0 +1,51 @@ +{ + "resourceType": "Bundle", + "type": "transaction", + "entry": [ { + "fullUrl": "Condition/dd9844e53c6d877fb91a9059f1bc0a433e7e892cd272770caa84aad4e7b7189d", + "resource": { + "resourceType": "Condition", + "id": "dd9844e53c6d877fb91a9059f1bc0a433e7e892cd272770caa84aad4e7b7189d", + "meta": { + "source": "KR7X825X.ONKOSTAR:obds-to-fhir:0.0.0-test", + "profile": [ "http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Condition-Primaerdiagnose" ] + }, + "code": { + "coding": [ { + "system": "http://fhir.de/CodeSystem/bfarm/icd-10-gm", + "version": "2019", + "code": "C43.2" + } ] + }, + "bodySite": [ { + "coding": [ { + "system": "http://dktk.dkfz.de/fhir/onco/core/CodeSystem/SeitenlokalisationCS", + "code": "L", + "display": "links" + }, { + "system": "http://snomed.info/sct", + "code": "7771000", + "display": "Left" + } ] + } ], + "subject": { + "reference": "Patient/19cc75fbfb51266ac0149828ae2f8522106e3ba176ceac2b40acb3cb1c9365f9", + "identifier": { + "type": { + "coding": [ { + "system": "http://terminology.hl7.org/CodeSystem/v2-0203", + "code": "MR" + } ] + }, + "system": "https://fhir.diz.uk-erlangen.de/identifiers/patient-id", + "value": "0001234567" + } + }, + "onsetDateTime": "2019-08-21" + }, + "request": { + "method": "PUT", + "url": "Condition/dd9844e53c6d877fb91a9059f1bc0a433e7e892cd272770caa84aad4e7b7189d" + } + } ] +} \ No newline at end of file diff --git a/src/test/resources/diagnosis_set.xml b/src/test/resources/diagnosis_set.xml new file mode 100644 index 00000000..d342d558 --- /dev/null +++ b/src/test/resources/diagnosis_set.xml @@ -0,0 +1,110 @@ + + + + UKI + Chef + Irgendwo-Straße 1, 12345 Phantasieland + + + + + privatversichert + 1234567890 + TestpatientEnzensperger + + Horst + + M + 01.01.1950 + + + Irgendwo-Straße 2 + 2 + DE + 12345 + Phantasieland + + + + + + 30.01.2024 + D + histologie_zytologie + + C43.2 + 10 2019 GM + 21.08.2019 + L + + + C43.5 + 10 2010 GM + Bösartiges Melanom des Rumpfes + + + 21.08.2019 + p 21557-19 + 8720/3 + 33 + + + + + N + + + *** Pathobericht + + + + Einsender_Vorname + Sepp + + + Einsender_Nachname + Prof. Dr. Doof + + + Einsender_Titel + - + + + Einsender_Strasse + Irgendwo-Straße + + + Einsender_Hausnummer + 1 + + + Einsender_Ort + Phantasieland + + + Einsender_PLZ + 12345 + + + Einsender_Einrichtung + Prof. Dr. Doof, UKI, HG + + + Einsender_BSNR + - + + + Einsender_LANR + - + + + + + + + + + KR7X825X + + + diff --git a/src/test/resources/diagnosis_unset.xml b/src/test/resources/diagnosis_unset.xml new file mode 100644 index 00000000..5bc464a8 --- /dev/null +++ b/src/test/resources/diagnosis_unset.xml @@ -0,0 +1,107 @@ + + + + UKI + Chef + Irgendwo-Straße 1, 12345 Phantasieland + + + + + privatversichert + 1234567890 + TestpatientEnzensperger + + Horst + + M + 01.01.1950 + + + Irgendwo-Straße 2 + 2 + DE + 12345 + Phantasieland + + + + + + 30.01.2024 + D + histologie_zytologie + + C43.2 + 10 2019 GM + 21.08.2019 + L + + + + + 21.08.2019 + p 21557-19 + 8720/3 + 33 + + + + + N + + + *** Pathobericht + + + + Einsender_Vorname + Sepp + + + Einsender_Nachname + Prof. Dr. Doof + + + Einsender_Titel + - + + + Einsender_Strasse + Irgendwo-Straße + + + Einsender_Hausnummer + 1 + + + Einsender_Ort + Phantasieland + + + Einsender_PLZ + 12345 + + + Einsender_Einrichtung + Prof. Dr. Doof, UKI, HG + + + Einsender_BSNR + - + + + Einsender_LANR + - + + + + + + + + + KR7X825X + + + From e053596c32a1eb06b02efc2b90a3425d30327d2d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 7 May 2024 06:03:55 +0000 Subject: [PATCH 2/4] chore(release): 2.0.17 [skip ci] ## [2.0.17](https://github.com/miracum/obds-to-fhir/compare/v2.0.16...v2.0.17) (2024-05-07) ### Bug Fixes * handle Primaertumor_ICD_Version being unset or not matching regex ([#39](https://github.com/miracum/obds-to-fhir/issues/39)) ([87a6b63](https://github.com/miracum/obds-to-fhir/commit/87a6b63dc2084e0fa49c989a1bb8fec0acc4050e)) ### CI/CD * added prerelease config ([#33](https://github.com/miracum/obds-to-fhir/issues/33)) ([7398750](https://github.com/miracum/obds-to-fhir/commit/739875050eaeb956fc6685f412a6a27d6d9f50ce)) ### Miscellaneous Chores * **deps:** update github-actions ([#18](https://github.com/miracum/obds-to-fhir/issues/18)) ([bbaceb5](https://github.com/miracum/obds-to-fhir/commit/bbaceb550c333f7198ba02e9f604d392369fea3a)) --- build.gradle | 2 +- src/main/resources/application.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index fab19187..28daf61b 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { } group = 'org.miracum.streams.ume' -version = '2.0.16' +version = '2.0.17' sourceCompatibility = '17' targetCompatibility = '17' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f00b641c..746de73f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,5 @@ app: - version: 2.0.16 + version: 2.0.17 enableCheckDigitConv: ${CHECK_DIGIT_CONVERSION:false} fhir: From 76331049d2db2b80e0a992009b7ca889b88ca6f9 Mon Sep 17 00:00:00 2001 From: "jasmin.ziegler" Date: Tue, 7 May 2024 15:38:59 +0200 Subject: [PATCH 3/4] fix: NPE if mengeHistologie is unset (#40) --- .../ume/obdstofhir/mapper/ObdsObservationMapper.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsObservationMapper.java b/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsObservationMapper.java index 549846d9..8bbab4ad 100644 --- a/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsObservationMapper.java +++ b/src/main/java/org/miracum/streams/ume/obdstofhir/mapper/ObdsObservationMapper.java @@ -96,8 +96,11 @@ public Bundle mapOnkoResourcesToObservation(List meldungExportLis if (Objects.equals(meldeanlass, fhirProperties.getReportingReason().getDiagnosis())) { // aus Diagnose: histologie, grading, c-tnm und p-tnm histList = new ArrayList<>(); - for (var hist : meldung.getDiagnose().getMenge_Histologie().getHistologie()) { - histList.add(new Tupel<>(hist, meldeanlass)); + var mengeHistologie = meldung.getDiagnose().getMenge_Histologie(); + if (mengeHistologie != null) { + for (var hist : mengeHistologie.getHistologie()) { + histList.add(new Tupel<>(hist, meldeanlass)); + } } cTnm = new Triple<>( From 428cf0d77f36df2ab5765d9c76b12e0069e9687a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 7 May 2024 13:43:33 +0000 Subject: [PATCH 4/4] chore(release): 2.0.18 [skip ci] ## [2.0.18](https://github.com/miracum/obds-to-fhir/compare/v2.0.17...v2.0.18) (2024-05-07) ### Bug Fixes * NPE if mengeHistologie is unset ([#40](https://github.com/miracum/obds-to-fhir/issues/40)) ([7633104](https://github.com/miracum/obds-to-fhir/commit/76331049d2db2b80e0a992009b7ca889b88ca6f9)) --- build.gradle | 2 +- src/main/resources/application.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 28daf61b..f30d0c94 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { } group = 'org.miracum.streams.ume' -version = '2.0.17' +version = '2.0.18' sourceCompatibility = '17' targetCompatibility = '17' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 746de73f..f28be096 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,5 @@ app: - version: 2.0.17 + version: 2.0.18 enableCheckDigitConv: ${CHECK_DIGIT_CONVERSION:false} fhir: