diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/AbstractEinzelempfehlungDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/AbstractEinzelempfehlungDataMapper.java index 430edb2..18fa6a7 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/AbstractEinzelempfehlungDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/AbstractEinzelempfehlungDataMapper.java @@ -4,6 +4,7 @@ import dev.pcvolkmer.mv64e.mtb.*; import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; @@ -18,6 +19,25 @@ public abstract class AbstractEinzelempfehlungDataMapper extends AbstractSubf super(einzelempfehlungCatalogue); } + protected RecommendationPriorityCoding getRecommendationPriorityCoding(String code, int version) { + if (code == null || !Arrays.stream(RecommendationPriorityCodingCode.values()).map(RecommendationPriorityCodingCode::toValue).collect(Collectors.toSet()).contains(code)) { + return null; + } + + var resultBuilder = RecommendationPriorityCoding.builder() + .system("dnpm-dip/recommendation/priority"); + + try { + resultBuilder + .code(RecommendationPriorityCodingCode.forValue(code)) + .display(code); + } catch (IOException e) { + return null; + } + + return resultBuilder.build(); + } + protected LevelOfEvidence getLevelOfEvidence(ResultSet resultSet) { if (resultSet == null) { return null; diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungProzedurDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungProzedurDataMapper.java index de61821..42076bc 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungProzedurDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungProzedurDataMapper.java @@ -1,14 +1,15 @@ package dev.pcvolkmer.onco.datamapper.mapper; -import dev.pcvolkmer.mv64e.mtb.*; +import dev.pcvolkmer.mv64e.mtb.MtbProcedureRecommendationCategoryCoding; +import dev.pcvolkmer.mv64e.mtb.MtbProcedureRecommendationCategoryCodingCode; +import dev.pcvolkmer.mv64e.mtb.ProcedureRecommendation; +import dev.pcvolkmer.mv64e.mtb.Reference; import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReference; @@ -27,26 +28,33 @@ public class EinzelempfehlungProzedurDataMapper extends AbstractEinzelempfehlung @Override protected ProcedureRecommendation map(ResultSet resultSet) { - return ProcedureRecommendation.builder() + var resultBuilder = ProcedureRecommendation.builder() .id(resultSet.getString("id")) .patient(getPatientReference(resultSet.getString("patient_id"))) // TODO Fix id? .reason(Reference.builder().id(resultSet.getString("id")).build()) .issuedOn(resultSet.getDate("datum")) - .priority( - getRecommendationPriorityCoding( - resultSet.getString("evidenzlevel"), - resultSet.getInteger("evidenzlevel_propcat_version") - ) - ) - .code( - getMtbProcedureRecommendationCategoryCoding( - resultSet.getString("art_der_therapie"), - resultSet.getInteger("art_der_therapie_propcat_version") - ) - ) - .levelOfEvidence(getLevelOfEvidence(resultSet)) - .build(); + .levelOfEvidence(getLevelOfEvidence(resultSet)); + + if (null != resultSet.getString("evidenzlevel")) { + resultBuilder.priority( + getRecommendationPriorityCoding( + resultSet.getString("evidenzlevel"), + resultSet.getInteger("evidenzlevel_propcat_version") + ) + ); + } + + if (null != resultSet.getString("art_der_therapie")) { + resultBuilder.code( + getMtbProcedureRecommendationCategoryCoding( + resultSet.getString("art_der_therapie"), + resultSet.getInteger("art_der_therapie_propcat_version") + ) + ); + } + + return resultBuilder.build(); } @Override @@ -60,29 +68,11 @@ public class EinzelempfehlungProzedurDataMapper extends AbstractEinzelempfehlung .stream() // Filter Prozedurempfehlung (Weitere Empfehlungen) .filter(it -> it.getString("art_der_therapie") != null && !it.getString("art_der_therapie").isBlank()) + .filter(it -> "sonstige".equals(it.getString("empfehlungskategorie"))) .map(this::map) .collect(Collectors.toList()); } - private RecommendationPriorityCoding getRecommendationPriorityCoding(String code, int version) { - if (code == null || !Arrays.stream(RecommendationPriorityCodingCode.values()).map(RecommendationPriorityCodingCode::toValue).collect(Collectors.toSet()).contains(code)) { - return null; - } - - var resultBuilder = RecommendationPriorityCoding.builder() - .system("dnpm-dip/recommendation/priority"); - - try { - resultBuilder - .code(RecommendationPriorityCodingCode.forValue(code)) - .display(code); - } catch (IOException e) { - return null; - } - - return resultBuilder.build(); - } - private MtbProcedureRecommendationCategoryCoding getMtbProcedureRecommendationCategoryCoding(String code, int version) { if (code == null || !Arrays.stream(MtbProcedureRecommendationCategoryCodingCode.values()).map(MtbProcedureRecommendationCategoryCodingCode::toValue).collect(Collectors.toSet()).contains(code)) { return null; diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungStudieDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungStudieDataMapper.java new file mode 100644 index 0000000..2d78385 --- /dev/null +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungStudieDataMapper.java @@ -0,0 +1,60 @@ +package dev.pcvolkmer.onco.datamapper.mapper; + +import dev.pcvolkmer.mv64e.mtb.MtbStudyEnrollmentRecommendation; +import dev.pcvolkmer.mv64e.mtb.Reference; +import dev.pcvolkmer.onco.datamapper.ResultSet; +import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; + +import java.util.List; +import java.util.stream.Collectors; + +import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReference; + +/** + * Mapper class to load and map diagnosis data from database table 'dk_dnpm_einzelempfehlung' + * + * @author Paul-Christian Volkmer + * @since 0.1 + */ +public class EinzelempfehlungStudieDataMapper extends AbstractEinzelempfehlungDataMapper { + + public EinzelempfehlungStudieDataMapper(EinzelempfehlungCatalogue einzelempfehlungCatalogue) { + super(einzelempfehlungCatalogue); + } + + @Override + protected MtbStudyEnrollmentRecommendation map(ResultSet resultSet) { + return MtbStudyEnrollmentRecommendation.builder() + .id(resultSet.getString("id")) + .patient(getPatientReference(resultSet.getString("patient_id"))) + // TODO Fix id? + .reason(Reference.builder().id(resultSet.getString("id")).build()) + .issuedOn(resultSet.getDate("datum")) + .priority( + getRecommendationPriorityCoding( + resultSet.getString("evidenzlevel"), + resultSet.getInteger("evidenzlevel_propcat_version") + ) + ) + .medication(JsonToMedicationMapper.map(resultSet.getString("wirkstoffe_json"))) + .levelOfEvidence(getLevelOfEvidence(resultSet)) + .study(JsonToStudyMapper.map(resultSet.getString("studien_alle_json"))) + .build(); + } + + @Override + public MtbStudyEnrollmentRecommendation getById(int id) { + return this.map(this.catalogue.getById(id)); + } + + @Override + public List getByParentId(final int parentId) { + return catalogue.getAllByParentId(parentId) + .stream() + // Filter Wirkstoffempfehlung (Systemische Therapie) + .filter(it -> "studie".equals(it.getString("empfehlungskategorie"))) + .map(this::map) + .collect(Collectors.toList()); + } + +} 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 12cd6b1..c159b15 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungWirkstoffDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/EinzelempfehlungWirkstoffDataMapper.java @@ -1,14 +1,10 @@ package dev.pcvolkmer.onco.datamapper.mapper; import dev.pcvolkmer.mv64e.mtb.MtbMedicationRecommendation; -import dev.pcvolkmer.mv64e.mtb.RecommendationPriorityCoding; -import dev.pcvolkmer.mv64e.mtb.RecommendationPriorityCodingCode; import dev.pcvolkmer.mv64e.mtb.Reference; 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; @@ -55,28 +51,13 @@ 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("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"))) .map(this::map) .collect(Collectors.toList()); } - private RecommendationPriorityCoding getRecommendationPriorityCoding(String code, int version) { - if (code == null || !Arrays.stream(RecommendationPriorityCodingCode.values()).map(RecommendationPriorityCodingCode::toValue).collect(Collectors.toSet()).contains(code)) { - return null; - } - - var resultBuilder = RecommendationPriorityCoding.builder() - .system("dnpm-dip/recommendation/priority"); - - try { - resultBuilder - .code(RecommendationPriorityCodingCode.forValue(code)) - .display(code); - } catch (IOException e) { - return null; - } - - return resultBuilder.build(); - } - } diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToStudyMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToStudyMapper.java new file mode 100644 index 0000000..d090d16 --- /dev/null +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToStudyMapper.java @@ -0,0 +1,81 @@ +package dev.pcvolkmer.onco.datamapper.mapper; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import dev.pcvolkmer.mv64e.mtb.StudyReference; +import dev.pcvolkmer.mv64e.mtb.StudySystem; +import dev.pcvolkmer.onco.datamapper.exceptions.DataAccessException; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Maps JSON strings used in form into DNPM study + * + * @author Paul-Christian Volkmer + * @since 0.1 + */ +public class JsonToStudyMapper { + + private JsonToStudyMapper() { + // intentionally left empty + } + + public static List map(String studyJson) { + if (studyJson == null) { + return List.of(); + } + try { + return new ObjectMapper().readValue(studyJson, new TypeReference>() { + }).stream() + .map(studie -> StudyReference.builder() + .id(studie.id) + .system(getStudySystem(studie.system)) + .type("Study") + .build() + ) + .collect(Collectors.toList()); + } catch (Exception e) { + throw new DataAccessException(String.format("Cannot map medication for %s", studyJson)); + } + } + + private static StudySystem getStudySystem(String code) { + if (code == null || !Arrays.stream(StudySystem.values()).map(StudySystem::toValue).collect(Collectors.toSet()).contains(code)) { + return null; + } + + try { + return StudySystem.valueOf(code); + } catch (IllegalArgumentException e) { + return null; + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + private static class Studie { + @JsonAlias("nct") + private String id; + private String system; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSystem() { + return system; + } + + public void setSystem(String system) { + this.system = system; + } + } + +} diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java index 0dbc0ac..facdb49 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java @@ -6,6 +6,7 @@ import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.datacatalogues.*; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReference; @@ -109,6 +110,7 @@ public class MolekulargenetikToSpecimenDataMapper implements DataMapper it.setDiagnosis(diagnoseReferenz)) .collect(Collectors.toList()); 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 44ff15c..ea06257 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/TherapieplanDataMapper.java @@ -25,6 +25,7 @@ public class TherapieplanDataMapper implements DataMapper { private final EinzelempfehlungProzedurDataMapper einzelempfehlungProzedurDataMapper; private final EinzelempfehlungWirkstoffDataMapper einzelempfehlungWirkstoffDataMapper; + private final EinzelempfehlungStudieDataMapper einzelempfehlungStudieDataMapper; public TherapieplanDataMapper( final TherapieplanCatalogue therapieplanCatalogue, @@ -36,6 +37,7 @@ public class TherapieplanDataMapper implements DataMapper { this.einzelempfehlungProzedurDataMapper = new EinzelempfehlungProzedurDataMapper(einzelempfehlungCatalogue); this.einzelempfehlungWirkstoffDataMapper = new EinzelempfehlungWirkstoffDataMapper(einzelempfehlungCatalogue); + this.einzelempfehlungStudieDataMapper = new EinzelempfehlungStudieDataMapper(einzelempfehlungCatalogue); } /** @@ -53,11 +55,12 @@ public class TherapieplanDataMapper implements DataMapper { .id(therapieplanData.getString("id")) .patient(getPatientReference(therapieplanData.getString("patient_id"))) .issuedOn(therapieplanData.getDate("datum")) - .procedureRecommendations(einzelempfehlungProzedurDataMapper.getByParentId(id)) ; if (therapieplanData.isTrue("mit_einzelempfehlung")) { builder.medicationRecommendations(einzelempfehlungWirkstoffDataMapper.getByParentId(id)); + builder.procedureRecommendations(einzelempfehlungProzedurDataMapper.getByParentId(id)); + builder.studyEnrollmentRecommendations(einzelempfehlungStudieDataMapper.getByParentId(id)); } // Formularfeld "protokollauszug" diff --git a/src/test/java/dev/pcvolkmer/onco/datamapper/datacatalogues/JsonToMedicationMapperTest.java b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToMedicationMapperTest.java similarity index 94% rename from src/test/java/dev/pcvolkmer/onco/datamapper/datacatalogues/JsonToMedicationMapperTest.java rename to src/test/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToMedicationMapperTest.java index 3801438..ec77672 100644 --- a/src/test/java/dev/pcvolkmer/onco/datamapper/datacatalogues/JsonToMedicationMapperTest.java +++ b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToMedicationMapperTest.java @@ -1,7 +1,6 @@ -package dev.pcvolkmer.onco.datamapper.datacatalogues; +package dev.pcvolkmer.onco.datamapper.mapper; import dev.pcvolkmer.mv64e.mtb.RequestedMedicationSystem; -import dev.pcvolkmer.onco.datamapper.mapper.JsonToMedicationMapper; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToStudyMapperTest.java b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToStudyMapperTest.java new file mode 100644 index 0000000..809517e --- /dev/null +++ b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/JsonToStudyMapperTest.java @@ -0,0 +1,28 @@ +package dev.pcvolkmer.onco.datamapper.mapper; + +import dev.pcvolkmer.mv64e.mtb.StudySystem; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class JsonToStudyMapperTest { + + // See example in: https://github.com/pcvolkmer/onkostar-plugin-dnpm/blob/master/sql/sql-queries.md + @Test + void shouldMapEinzelempfehlungJson() { + var json = "[\n" + + " {\"studie\":\"TestInhibitor\",\"system\":\"NCT\",\"id\":\"NCT12345678\",\"nct\":\"NCT12345678\",\"ort\":\"Teststadt\",\"internextern\":\"e\"}\n" + + "]"; + + var actual = JsonToStudyMapper.map(json); + + assertThat(actual).hasSize(1); + + var study = actual.get(0); + assertThat(study.getId()).isEqualTo("NCT12345678"); + assertThat(study.getDisplay()).isNull(); + assertThat(study.getSystem()).isEqualTo(StudySystem.NCT); + assertThat(study.getType()).isEqualTo("Study"); + } + +}