1
0
mirror of https://github.com/pcvolkmer/mv64e-onkostar-data.git synced 2025-09-13 16:02:52 +00:00

feat: add specimens related to Vorbefunde

This also uses DB id as specimen id.
This commit is contained in:
2025-07-06 16:51:45 +02:00
parent 21ce6f3185
commit 37c553a34e
6 changed files with 113 additions and 33 deletions

View File

@@ -21,6 +21,7 @@
package dev.pcvolkmer.onco.datamapper.datacatalogues; package dev.pcvolkmer.onco.datamapper.datacatalogues;
import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.ResultSet;
import dev.pcvolkmer.onco.datamapper.exceptions.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List; import java.util.List;
@@ -98,4 +99,42 @@ public class MolekulargenetikCatalogue extends AbstractDataCatalogue {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/**
* Get procedure result set by einsendenummer
*
* @param einsendenummer The case id related to this procedure
* @return The procedure id
*/
public ResultSet getByEinsendenummer(String einsendenummer) {
var result = this.jdbcTemplate.queryForList(
String.format(
"SELECT patient.patienten_id, %s.*, prozedur.* FROM %s JOIN prozedur ON (prozedur.id = %s.id) JOIN patient ON (patient.id = prozedur.patient_id) WHERE geloescht = 0 AND %s.einsendenummer = ?",
getTableName(),
getTableName(),
getTableName(),
getTableName()
),
einsendenummer);
if (result.isEmpty()) {
throw new DataAccessException("No record found for einsendenummer: " + einsendenummer);
} else if (result.size() > 1) {
throw new DataAccessException("Multiple records found for einsendenummer: " + einsendenummer);
}
var resultSet = ResultSet.from(result.get(0));
if (resultSet.getRawData().containsKey("id")) {
var merkmale = getMerkmaleById(resultSet.getId());
if (merkmale.isEmpty()) {
return resultSet;
}
merkmale.forEach((key, value) ->
resultSet.getRawData().put(key, value)
);
}
return resultSet;
}
} }

View File

@@ -20,15 +20,19 @@
package dev.pcvolkmer.onco.datamapper.mapper; package dev.pcvolkmer.onco.datamapper.mapper;
import dev.pcvolkmer.mv64e.mtb.*; import dev.pcvolkmer.mv64e.mtb.MolecularDiagnosticReportCoding;
import dev.pcvolkmer.mv64e.mtb.MolecularDiagnosticReportCodingCode;
import dev.pcvolkmer.mv64e.mtb.PriorDiagnosticReport;
import dev.pcvolkmer.mv64e.mtb.Reference;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.ResultSet;
import dev.pcvolkmer.onco.datamapper.datacatalogues.EcogCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.MolekulargenetikCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.VorbefundeCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.VorbefundeCatalogue;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -39,10 +43,16 @@ import java.util.stream.Collectors;
*/ */
public class KpaVorbefundeDataMapper extends AbstractSubformDataMapper<PriorDiagnosticReport> { public class KpaVorbefundeDataMapper extends AbstractSubformDataMapper<PriorDiagnosticReport> {
private final MolekulargenetikCatalogue molekulargenetikCatalogue;
private final PropertyCatalogue propertyCatalogue; private final PropertyCatalogue propertyCatalogue;
public KpaVorbefundeDataMapper(final VorbefundeCatalogue catalogue, PropertyCatalogue propertyCatalogue) { public KpaVorbefundeDataMapper(
final VorbefundeCatalogue catalogue,
final MolekulargenetikCatalogue molekulargenetikCatalogue,
final PropertyCatalogue propertyCatalogue
) {
super(catalogue); super(catalogue);
this.molekulargenetikCatalogue = molekulargenetikCatalogue;
this.propertyCatalogue = propertyCatalogue; this.propertyCatalogue = propertyCatalogue;
} }
@@ -63,17 +73,24 @@ public class KpaVorbefundeDataMapper extends AbstractSubformDataMapper<PriorDiag
return catalogue.getAllByParentId(parentId) return catalogue.getAllByParentId(parentId)
.stream() .stream()
.map(this::map) .map(this::map)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override @Override
protected PriorDiagnosticReport map(final ResultSet resultSet) { protected PriorDiagnosticReport map(final ResultSet resultSet) {
var builder = PriorDiagnosticReport.builder(); var builder = PriorDiagnosticReport.builder();
var einsendenummer = resultSet.getString("befundnummer");
var osMolGen = molekulargenetikCatalogue.getByEinsendenummer(einsendenummer);
if (null != osMolGen) {
builder builder
.id(resultSet.getId().toString()) .id(resultSet.getId().toString())
.patient(resultSet.getPatientReference()) .patient(resultSet.getPatientReference())
.issuedOn(resultSet.getDate("erstellungsdatum")) .issuedOn(resultSet.getDate("erstellungsdatum"))
.specimen(Reference.builder().id(resultSet.getString("befundnummer")).type("Specimen").build()) .specimen(Reference.builder().id(osMolGen.getId().toString()).type("Specimen").build())
.type( .type(
getMolecularDiagnosticReportCoding( getMolecularDiagnosticReportCoding(
resultSet.getString("artderdiagnostik"), resultSet.getString("artderdiagnostik"),
@@ -88,6 +105,9 @@ public class KpaVorbefundeDataMapper extends AbstractSubformDataMapper<PriorDiag
return builder.build(); return builder.build();
} }
return null;
}
private MolecularDiagnosticReportCoding getMolecularDiagnosticReportCoding(String value, int version) { private MolecularDiagnosticReportCoding getMolecularDiagnosticReportCoding(String value, int version) {
if (value == null || !Arrays.stream(MolecularDiagnosticReportCodingCode.values()).map(MolecularDiagnosticReportCodingCode::toValue).collect(Collectors.toSet()).contains(value)) { if (value == null || !Arrays.stream(MolecularDiagnosticReportCodingCode.values()).map(MolecularDiagnosticReportCodingCode::toValue).collect(Collectors.toSet()).contains(value)) {
return null; return null;

View File

@@ -42,7 +42,7 @@ public class MolekulargenetikToSpecimenDataMapper implements DataMapper<TumorSpe
private final RebiopsieCatalogue rebiopsieCatalogue; private final RebiopsieCatalogue rebiopsieCatalogue;
private final ReevaluationCatalogue reevaluationCatalogue; private final ReevaluationCatalogue reevaluationCatalogue;
private final EinzelempfehlungCatalogue einzelempfehlungCatalogue; private final EinzelempfehlungCatalogue einzelempfehlungCatalogue;
private final PropertyCatalogue propertyCatalogue; private final VorbefundeCatalogue vorbefundeCatalogue;
public MolekulargenetikToSpecimenDataMapper( public MolekulargenetikToSpecimenDataMapper(
final MolekulargenetikCatalogue molekulargenetikCatalogue, final MolekulargenetikCatalogue molekulargenetikCatalogue,
@@ -50,19 +50,19 @@ public class MolekulargenetikToSpecimenDataMapper implements DataMapper<TumorSpe
final RebiopsieCatalogue rebiopsieCatalogue, final RebiopsieCatalogue rebiopsieCatalogue,
final ReevaluationCatalogue reevaluationCatalogue, final ReevaluationCatalogue reevaluationCatalogue,
final EinzelempfehlungCatalogue einzelempfehlungCatalogue, final EinzelempfehlungCatalogue einzelempfehlungCatalogue,
final PropertyCatalogue propertyCatalogue final VorbefundeCatalogue vorbefundeCatalogue
) { ) {
this.molekulargenetikCatalogue = molekulargenetikCatalogue; this.molekulargenetikCatalogue = molekulargenetikCatalogue;
this.therapieplanCatalogue = therapieplanCatalogue; this.therapieplanCatalogue = therapieplanCatalogue;
this.rebiopsieCatalogue = rebiopsieCatalogue; this.rebiopsieCatalogue = rebiopsieCatalogue;
this.reevaluationCatalogue = reevaluationCatalogue; this.reevaluationCatalogue = reevaluationCatalogue;
this.einzelempfehlungCatalogue = einzelempfehlungCatalogue; this.einzelempfehlungCatalogue = einzelempfehlungCatalogue;
this.propertyCatalogue = propertyCatalogue; this.vorbefundeCatalogue = vorbefundeCatalogue;
} }
/** /**
* Loads and maps a specimen using the database id * Loads and maps a specimen using the database id
* The result does not include a diagnosis reference! * Not intended for direct use! The result does not include a diagnosis reference!
* *
* @param id The database id of the procedure data set * @param id The database id of the procedure data set
* @return The loaded Patient data * @return The loaded Patient data
@@ -77,7 +77,7 @@ public class MolekulargenetikToSpecimenDataMapper implements DataMapper<TumorSpe
.patient(data.getPatientReference()) .patient(data.getPatientReference())
.type(getTumorSpecimenCoding(data.getString("materialfixierung"))) .type(getTumorSpecimenCoding(data.getString("materialfixierung")))
.collection(getCollection(data)) .collection(getCollection(data))
// TODO add diagnosis later // diagnosis is added in getAllByKpaId()
; ;
@@ -127,8 +127,18 @@ public class MolekulargenetikToSpecimenDataMapper implements DataMapper<TumorSpe
.collect(Collectors.toSet()) .collect(Collectors.toSet())
); );
// Vorbefunde anhand Einsendenummer
osMolGen.addAll(
vorbefundeCatalogue.getAllByParentId(kpaId).stream()
.map(rs -> rs.getString("befundnummer"))
.map(molekulargenetikCatalogue::getByEinsendenummer)
.map(ResultSet::getId)
.collect(Collectors.toList())
);
return osMolGen.stream() return osMolGen.stream()
.filter(Objects::nonNull) .filter(Objects::nonNull)
.distinct()
.map(this::getById) .map(this::getById)
.peek(it -> it.setDiagnosis(diagnoseReferenz)) .peek(it -> it.setDiagnosis(diagnoseReferenz))
.collect(Collectors.toList()); .collect(Collectors.toList());

View File

@@ -121,12 +121,16 @@ public class MtbDataMapper implements DataMapper<Mtb> {
catalogueFactory.catalogue(RebiopsieCatalogue.class), catalogueFactory.catalogue(RebiopsieCatalogue.class),
catalogueFactory.catalogue(ReevaluationCatalogue.class), catalogueFactory.catalogue(ReevaluationCatalogue.class),
einzelempfehlungCatalogue, einzelempfehlungCatalogue,
propertyCatalogue catalogueFactory.catalogue(VorbefundeCatalogue.class)
); );
var kpaMolekulargenetikDataMapper = new KpaMolekulargenetikDataMapper(molekulargenetikCatalogue, catalogueFactory.catalogue(MolekulargenuntersuchungCatalogue.class), propertyCatalogue); var kpaMolekulargenetikDataMapper = new KpaMolekulargenetikDataMapper(molekulargenetikCatalogue, catalogueFactory.catalogue(MolekulargenuntersuchungCatalogue.class), propertyCatalogue);
var kpaVorbefundeDataMapper = new KpaVorbefundeDataMapper(catalogueFactory.catalogue(VorbefundeCatalogue.class), propertyCatalogue); var kpaVorbefundeDataMapper = new KpaVorbefundeDataMapper(
catalogueFactory.catalogue(VorbefundeCatalogue.class),
molekulargenetikCatalogue,
propertyCatalogue
);
var resultBuilder = Mtb.builder(); var resultBuilder = Mtb.builder();

View File

@@ -26,6 +26,7 @@ import dev.pcvolkmer.mv64e.mtb.PriorDiagnosticReport;
import dev.pcvolkmer.mv64e.mtb.Reference; import dev.pcvolkmer.mv64e.mtb.Reference;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.ResultSet;
import dev.pcvolkmer.onco.datamapper.datacatalogues.MolekulargenetikCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.VorbefundeCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.VorbefundeCatalogue;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -48,6 +49,7 @@ import static org.mockito.Mockito.when;
class KpaVorbefundeDataMapperTest { class KpaVorbefundeDataMapperTest {
VorbefundeCatalogue catalogue; VorbefundeCatalogue catalogue;
MolekulargenetikCatalogue molekulargenetikCatalogue;
PropertyCatalogue propertyCatalogue; PropertyCatalogue propertyCatalogue;
KpaVorbefundeDataMapper dataMapper; KpaVorbefundeDataMapper dataMapper;
@@ -55,11 +57,13 @@ class KpaVorbefundeDataMapperTest {
@BeforeEach @BeforeEach
void setUp( void setUp(
@Mock VorbefundeCatalogue catalogue, @Mock VorbefundeCatalogue catalogue,
@Mock MolekulargenetikCatalogue molekulargenetikCatalogue,
@Mock PropertyCatalogue propertyCatalogue @Mock PropertyCatalogue propertyCatalogue
) { ) {
this.catalogue = catalogue; this.catalogue = catalogue;
this.molekulargenetikCatalogue = molekulargenetikCatalogue;
this.propertyCatalogue = propertyCatalogue; this.propertyCatalogue = propertyCatalogue;
this.dataMapper = new KpaVorbefundeDataMapper(catalogue, propertyCatalogue); this.dataMapper = new KpaVorbefundeDataMapper(catalogue, molekulargenetikCatalogue, propertyCatalogue);
} }
@Test @Test
@@ -93,6 +97,10 @@ class KpaVorbefundeDataMapperTest {
.when(catalogue) .when(catalogue)
.getAllByParentId(anyInt()); .getAllByParentId(anyInt());
doAnswer(invocationOnMock -> ResultSet.from(Map.of("id", 1, "einsendenummer", "X/2025/1234")))
.when(molekulargenetikCatalogue)
.getByEinsendenummer(anyString());
doAnswer(invocationOnMock -> { doAnswer(invocationOnMock -> {
var testPropertyData = Map.of( var testPropertyData = Map.of(
"panel", new PropertyCatalogue.Entry("panel", "Panel", "Panel") "panel", new PropertyCatalogue.Entry("panel", "Panel", "Panel")
@@ -119,7 +127,7 @@ class KpaVorbefundeDataMapperTest {
.isEqualTo(new java.sql.Date(Date.from(Instant.parse("2000-07-06T12:00:00Z")).getTime())); .isEqualTo(new java.sql.Date(Date.from(Instant.parse("2000-07-06T12:00:00Z")).getTime()));
assertThat(actual.getSpecimen()) assertThat(actual.getSpecimen())
.isEqualTo(Reference.builder() .isEqualTo(Reference.builder()
.id("X/2025/1234") .id("1")
.type("Specimen") .type("Specimen")
.build() .build()
); );

View File

@@ -21,7 +21,6 @@
package dev.pcvolkmer.onco.datamapper.mapper; package dev.pcvolkmer.onco.datamapper.mapper;
import dev.pcvolkmer.mv64e.mtb.*; import dev.pcvolkmer.mv64e.mtb.*;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.ResultSet;
import dev.pcvolkmer.onco.datamapper.datacatalogues.*; import dev.pcvolkmer.onco.datamapper.datacatalogues.*;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@@ -50,7 +49,7 @@ class MolekulargenetikToSpecimenDataMapperTest {
RebiopsieCatalogue rebiopsieCatalogue; RebiopsieCatalogue rebiopsieCatalogue;
ReevaluationCatalogue reevaluationCatalogue; ReevaluationCatalogue reevaluationCatalogue;
EinzelempfehlungCatalogue einzelempfehlungCatalogue; EinzelempfehlungCatalogue einzelempfehlungCatalogue;
PropertyCatalogue propertyCatalogue; VorbefundeCatalogue vorbefundeCatalogue;
MolekulargenetikToSpecimenDataMapper mapper; MolekulargenetikToSpecimenDataMapper mapper;
@@ -61,14 +60,14 @@ class MolekulargenetikToSpecimenDataMapperTest {
@Mock RebiopsieCatalogue rebiopsieCatalogue, @Mock RebiopsieCatalogue rebiopsieCatalogue,
@Mock ReevaluationCatalogue reevaluationCatalogue, @Mock ReevaluationCatalogue reevaluationCatalogue,
@Mock EinzelempfehlungCatalogue einzelempfehlungCatalogue, @Mock EinzelempfehlungCatalogue einzelempfehlungCatalogue,
@Mock PropertyCatalogue propertyCatalogue @Mock VorbefundeCatalogue vorbefundeCatalogue
) { ) {
this.molekulargenetikCatalogue = molekulargenetikCatalogue; this.molekulargenetikCatalogue = molekulargenetikCatalogue;
this.therapieplanCatalogue = therapieplanCatalogue; this.therapieplanCatalogue = therapieplanCatalogue;
this.rebiopsieCatalogue = rebiopsieCatalogue; this.rebiopsieCatalogue = rebiopsieCatalogue;
this.reevaluationCatalogue = reevaluationCatalogue; this.reevaluationCatalogue = reevaluationCatalogue;
this.einzelempfehlungCatalogue = einzelempfehlungCatalogue; this.einzelempfehlungCatalogue = einzelempfehlungCatalogue;
this.propertyCatalogue = propertyCatalogue; this.vorbefundeCatalogue = vorbefundeCatalogue;
this.mapper = new MolekulargenetikToSpecimenDataMapper( this.mapper = new MolekulargenetikToSpecimenDataMapper(
molekulargenetikCatalogue, molekulargenetikCatalogue,
@@ -76,7 +75,7 @@ class MolekulargenetikToSpecimenDataMapperTest {
rebiopsieCatalogue, rebiopsieCatalogue,
reevaluationCatalogue, reevaluationCatalogue,
einzelempfehlungCatalogue, einzelempfehlungCatalogue,
propertyCatalogue vorbefundeCatalogue
); );
} }