diff --git a/README.md b/README.md index a587efb..57699d9 100644 --- a/README.md +++ b/README.md @@ -36,25 +36,30 @@ var jsonResult = Converter.toJsonString( ## Status -| DNPM-Datenmodell 2.1 - Bereich | Status | Anmerkung | -|----------------------------------|--------|----------------------------------------------------------------------------| -| Patient | ✅ | Verwendet Datenbank-ID, keine managing Site | -| Episoden | ✅ | | -| Diagnosen | ✅ | Entsprechend Formularaufbau nur Diagnose der aktuellen Episode | -| Verwandten-Diagnosen | ✅ | | -| Systemische Leitlinien-Therapien | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 | -| Leitlinien-Prozeduren | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 | -| ECOG-Verlauf | ✅ | | -| Tumor-Proben | ⛅ | Best effort: Formular OS.Molekulargenetik erfüllt nicht alle Anforderungen | -| vorherige Molekular-Diagnostik | ⌛ | Aktuell in Arbeit | -| Histologie-Berichte | ⌛ | Aktuell in Arbeit | -| IHC-Berichte | | | -| MSI-Befunde | | | -| NGS-Berichte | ⌛ | Aktuell in Arbeit | -| MTB-Beschlüsse | ⌛ | Aktuell in Arbeit | -| Follow-Up Verlauf | | | -| Antrag Kostenübernahme | | | -| Antwort Kostenübernahme | | | -| Therapien | | | -| Response Befunde | | | +| DNPM-Datenmodell 2.1 - Bereich | Status | Anmerkung | +|----------------------------------|--------|--------------------------------------------------------------------------------| +| Patient | ✅ | Verwendet Datenbank-ID, keine managing Site | +| Episoden | ✅ | | +| Diagnosen | ✅ | Entsprechend Formularaufbau nur Diagnose der aktuellen Episode | +| Verwandten-Diagnosen | ✅ | | +| Systemische Leitlinien-Therapien | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 | +| Leitlinien-Prozeduren | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 | +| ECOG-Verlauf | ✅ | | +| Tumor-Proben | ⛅ | Best effort: Formular OS.Molekulargenetik erfüllt nicht alle Anforderungen (1) | +| vorherige Molekular-Diagnostik | ⌛ | Aktuell in Arbeit | +| Histologie-Berichte | ⌛ | Aktuell in Arbeit | +| IHC-Berichte | | | +| MSI-Befunde | | | +| NGS-Berichte | ⌛ | Aktuell in Arbeit | +| MTB-Beschlüsse | ⛅ | Best effort: Stützende molekulare Alteration(en) aktuell nicht möglich (2) | +| Follow-Up Verlauf | | | +| Antrag Kostenübernahme | | | +| Antwort Kostenübernahme | | | +| Therapien | | | +| Response Befunde | | | +### Hinweise + +1. Nicht alle möglichen Ausprägungen in `OS.Molekulargenetik` vorhanden. +2. Nach Implementierung Mapping von HGNC-Symbol (Gen-Name) zu HGNC-ID ist die Angabe der optionalen stützenden + molekularen Alteration(en) möglich. diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungWirkstoffDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungWirkstoffDataMapper.java index c159b15..b18e1e4 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungWirkstoffDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungWirkstoffDataMapper.java @@ -1,10 +1,12 @@ package dev.pcvolkmer.onco.datamapper.mapper; -import dev.pcvolkmer.mv64e.mtb.MtbMedicationRecommendation; -import dev.pcvolkmer.mv64e.mtb.Reference; +import dev.pcvolkmer.mv64e.mtb.*; +import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; +import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -18,13 +20,19 @@ import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReferen */ public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlungDataMapper { - public EinzelempfehlungWirkstoffDataMapper(EinzelempfehlungCatalogue einzelempfehlungCatalogue) { + private final PropertyCatalogue propertyCatalogue; + + public EinzelempfehlungWirkstoffDataMapper( + EinzelempfehlungCatalogue einzelempfehlungCatalogue, + PropertyCatalogue propertyCatalogue + ) { super(einzelempfehlungCatalogue); + this.propertyCatalogue = propertyCatalogue; } @Override protected MtbMedicationRecommendation map(ResultSet resultSet) { - return MtbMedicationRecommendation.builder() + var resultBuilder = MtbMedicationRecommendation.builder() .id(resultSet.getString("id")) .patient(getPatientReference(resultSet.getString("patient_id"))) // TODO Fix id? @@ -37,8 +45,31 @@ public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlun ) ) .medication(JsonToMedicationMapper.map(resultSet.getString("wirkstoffe_json"))) - .levelOfEvidence(getLevelOfEvidence(resultSet)) - .build(); + .levelOfEvidence(getLevelOfEvidence(resultSet)); + + if (null != resultSet.getString("art_der_therapie")) { + resultBuilder.category( + getMtbMedicationRecommendationCategoryCoding( + resultSet.getString("art_der_therapie"), + resultSet.getInteger("art_der_therapie_propcat_version") + ) + ); + } + + if (null != resultSet.getString("empfehlungsart")) { + resultBuilder.useType( + getMtbMedicationRecommendationUseTypeCoding( + resultSet.getString("empfehlungsart"), + resultSet.getInteger("empfehlungsart_propcat_version") + ) + ); + } + + if (null != resultSet.getString("st_mol_alt_variante")) { + // Empty for now + } + + return resultBuilder.build(); } @Override @@ -51,13 +82,47 @@ public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlun return catalogue.getAllByParentId(parentId) .stream() // Filter Wirkstoffempfehlung (Systemische Therapie) - .filter(it -> it.getString("art_der_therapie") == null - || it.getString("art_der_therapie").isBlank()) - .filter(it -> it.getString("empfehlungskategorie") == null - || it.getString("empfehlungskategorie").isBlank() - || "systemisch".equals(it.getString("empfehlungskategorie"))) + .filter(it -> "systemisch".equals(it.getString("empfehlungskategorie"))) .map(this::map) .collect(Collectors.toList()); } + private MtbMedicationRecommendationCategoryCoding getMtbMedicationRecommendationCategoryCoding(String code, int version) { + if (code == null || !Arrays.stream(MtbMedicationRecommendationCategoryCodingCode.values()).map(MtbMedicationRecommendationCategoryCodingCode::toValue).collect(Collectors.toSet()).contains(code)) { + return null; + } + + var resultBuilder = MtbMedicationRecommendationCategoryCoding.builder() + .system("dnpm-dip/mtb/recommendation/systemic-therapy/category"); + + try { + resultBuilder + .code(MtbMedicationRecommendationCategoryCodingCode.forValue(code)) + .display(propertyCatalogue.getByCodeAndVersion(code, version).getShortdesc()); + } catch (IOException e) { + return null; + } + + return resultBuilder.build(); + } + + private MtbMedicationRecommendationUseTypeCoding getMtbMedicationRecommendationUseTypeCoding(String code, int version) { + if (code == null || !Arrays.stream(MtbMedicationRecommendationUseTypeCodingCode.values()).map(MtbMedicationRecommendationUseTypeCodingCode::toValue).collect(Collectors.toSet()).contains(code)) { + return null; + } + + var resultBuilder = MtbMedicationRecommendationUseTypeCoding.builder() + .system("dnpm-dip/mtb/recommendation/systemic-therapy/use-type"); + + try { + resultBuilder + .code(MtbMedicationRecommendationUseTypeCodingCode.forValue(code)) + .display(propertyCatalogue.getByCodeAndVersion(code, version).getShortdesc()); + } catch (IOException e) { + return null; + } + + return resultBuilder.build(); + } + } diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java index 588493d..048a654 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java @@ -86,6 +86,8 @@ public class MtbDataMapper implements DataMapper { var therapieplanCatalogue = catalogueFactory.catalogue(TherapieplanCatalogue.class); var therapieplanDataMapper = new TherapieplanDataMapper( therapieplanCatalogue, + catalogueFactory.catalogue(RebiopsieCatalogue.class), + catalogueFactory.catalogue(ReevaluationCatalogue.class), einzelempfehlungCatalogue, propertyCatalogue ); diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapper.java index ea06257..485cd49 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapper.java @@ -2,8 +2,7 @@ package dev.pcvolkmer.onco.datamapper.mapper; import dev.pcvolkmer.mv64e.mtb.*; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; -import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; -import dev.pcvolkmer.onco.datamapper.datacatalogues.TherapieplanCatalogue; +import dev.pcvolkmer.onco.datamapper.datacatalogues.*; import java.io.IOException; import java.util.Arrays; @@ -21,6 +20,8 @@ import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReferen public class TherapieplanDataMapper implements DataMapper { private final TherapieplanCatalogue therapieplanCatalogue; + private final RebiopsieCatalogue rebiopsieCatalogue; + private final ReevaluationCatalogue reevaluationCatalogue; private final PropertyCatalogue propertyCatalogue; private final EinzelempfehlungProzedurDataMapper einzelempfehlungProzedurDataMapper; @@ -29,14 +30,18 @@ public class TherapieplanDataMapper implements DataMapper { public TherapieplanDataMapper( final TherapieplanCatalogue therapieplanCatalogue, + final RebiopsieCatalogue rebiopsieCatalogue, + final ReevaluationCatalogue reevaluationCatalogue, final EinzelempfehlungCatalogue einzelempfehlungCatalogue, final PropertyCatalogue propertyCatalogue ) { this.therapieplanCatalogue = therapieplanCatalogue; + this.rebiopsieCatalogue = rebiopsieCatalogue; + this.reevaluationCatalogue = reevaluationCatalogue; this.propertyCatalogue = propertyCatalogue; this.einzelempfehlungProzedurDataMapper = new EinzelempfehlungProzedurDataMapper(einzelempfehlungCatalogue); - this.einzelempfehlungWirkstoffDataMapper = new EinzelempfehlungWirkstoffDataMapper(einzelempfehlungCatalogue); + this.einzelempfehlungWirkstoffDataMapper = new EinzelempfehlungWirkstoffDataMapper(einzelempfehlungCatalogue, propertyCatalogue); this.einzelempfehlungStudieDataMapper = new EinzelempfehlungStudieDataMapper(einzelempfehlungCatalogue); } @@ -55,6 +60,16 @@ public class TherapieplanDataMapper implements DataMapper { .id(therapieplanData.getString("id")) .patient(getPatientReference(therapieplanData.getString("patient_id"))) .issuedOn(therapieplanData.getDate("datum")) + .histologyReevaluationRequests(getHistologyReevaluationRequests(id)) + .rebiopsyRequests( + getRebiopsyRequest( + id, + Reference.builder() + .id(therapieplanData.getString("ref_dnpm_klinikanamnese")) + .type("MTBDiagnosis") + .build() + ) + ) ; if (therapieplanData.isTrue("mit_einzelempfehlung")) { @@ -137,4 +152,30 @@ public class TherapieplanDataMapper implements DataMapper { return resultBuilder.build(); } + private List getRebiopsyRequest(int parentId, Reference diagnosisReference) { + return this.rebiopsieCatalogue.getAllByParentId(parentId).stream() + .map(resultSet -> + RebiopsyRequest.builder() + .id(resultSet.getString("id")) + .patient(getPatientReference(resultSet.getString("patient_id"))) + .issuedOn(resultSet.getDate("datum")) + .tumorEntity(diagnosisReference) + .build() + ) + .collect(Collectors.toList()); + } + + private List getHistologyReevaluationRequests(int parentId) { + return this.reevaluationCatalogue.getAllByParentId(parentId).stream() + .map(resultSet -> + HistologyReevaluationRequest.builder() + .id(resultSet.getString("id")) + .patient(getPatientReference(resultSet.getString("patient_id"))) + .issuedOn(resultSet.getDate("datum")) + .specimen(Reference.builder().id(resultSet.getString("ref_molekulargenetik")).build()) + .build() + ) + .collect(Collectors.toList()); + } + } diff --git a/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapperTest.java b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapperTest.java index 3c18c2d..e097fe7 100644 --- a/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapperTest.java +++ b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapperTest.java @@ -4,6 +4,8 @@ import dev.pcvolkmer.mv64e.mtb.*; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; +import dev.pcvolkmer.onco.datamapper.datacatalogues.RebiopsieCatalogue; +import dev.pcvolkmer.onco.datamapper.datacatalogues.ReevaluationCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.TherapieplanCatalogue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -24,6 +26,8 @@ class TherapieplanDataMapperTest { TherapieplanCatalogue therapieplanCatalogue; EinzelempfehlungCatalogue einzelempfehlungCatalogue; + RebiopsieCatalogue rebiopsieCatalogue; + ReevaluationCatalogue reevaluationCatalogue; PropertyCatalogue propertyCatalogue; TherapieplanDataMapper dataMapper; @@ -31,13 +35,23 @@ class TherapieplanDataMapperTest { @BeforeEach void setUp( @Mock TherapieplanCatalogue therapieplanCatalogue, + @Mock RebiopsieCatalogue rebiopsieCatalogue, + @Mock ReevaluationCatalogue reevaluationCatalogue, @Mock EinzelempfehlungCatalogue einzelempfehlungCatalogue, @Mock PropertyCatalogue propertyCatalogue ) { this.therapieplanCatalogue = therapieplanCatalogue; + this.rebiopsieCatalogue = rebiopsieCatalogue; + this.reevaluationCatalogue = reevaluationCatalogue; this.einzelempfehlungCatalogue = einzelempfehlungCatalogue; this.propertyCatalogue = propertyCatalogue; - this.dataMapper = new TherapieplanDataMapper(therapieplanCatalogue, einzelempfehlungCatalogue, propertyCatalogue); + this.dataMapper = new TherapieplanDataMapper( + therapieplanCatalogue, + rebiopsieCatalogue, + reevaluationCatalogue, + einzelempfehlungCatalogue, + propertyCatalogue + ); } @Test @@ -47,7 +61,8 @@ class TherapieplanDataMapperTest { "patient_id", "42", "wirkstoffe_json", "[{\"code\":\"\",\"name\":\"PARP-Inhibierung\",\"system\":\"UNREGISTERED\"}]", "protokollauszug", "Das ist ein Protokollauszug", - "mit_einzelempfehlung", true + "mit_einzelempfehlung", true, + "empfehlungskategorie", "systemisch" ); doAnswer(invocationOnMock -> {