Skip to content

Commit

Permalink
fix: iterate over all export meldungen, avoiding prioritising for now
Browse files Browse the repository at this point in the history
  • Loading branch information
chgl committed May 12, 2024
1 parent bd9f7a8 commit e815fc1
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 54 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
!src
!*.gradle
!gradle.properties
!lombok.config
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@ public ObdsPatientMapper(FhirProperties fhirProperties) {
public Bundle mapOnkoResourcesToPatient(List<MeldungExport> meldungExportList) {

if (meldungExportList.isEmpty()) {
LOG.warn("Cannot map empty list of MeldungExport to {}", ResourceType.Patient);
return null;
}

// get first element of meldungExportList
var meldungExport = meldungExportList.get(0);

LOG.debug(
"Mapping Meldung {} to {}", getReportingIdFromAdt(meldungExport), ResourceType.Patient);
"Mapping Meldung {} (one of total {} in export list) to {}",
getReportingIdFromAdt(meldungExport),
meldungExportList.size(),
ResourceType.Patient);

var patient = new Patient();

Expand Down Expand Up @@ -82,15 +86,12 @@ public Bundle mapOnkoResourcesToPatient(List<MeldungExport> meldungExportList) {
meldungExport.getXml_daten().getMenge_Patient().getPatient().getPatienten_Stammdaten();

// gender
var genderMap =
new HashMap<String, Enumerations.AdministrativeGender>() {
{
put("W", Enumerations.AdministrativeGender.FEMALE);
put("M", Enumerations.AdministrativeGender.MALE);
put("D", Enumerations.AdministrativeGender.OTHER); // TODO set genderExtension
put("U", Enumerations.AdministrativeGender.UNKNOWN);
}
};
// TODO set genderExtension if AdministrativeGender.OTHER
var genderMap = new HashMap<String, Enumerations.AdministrativeGender>();
genderMap.put("W", Enumerations.AdministrativeGender.FEMALE);
genderMap.put("M", Enumerations.AdministrativeGender.MALE);
genderMap.put("D", Enumerations.AdministrativeGender.OTHER);
genderMap.put("U", Enumerations.AdministrativeGender.UNKNOWN);

patient.setGender(genderMap.getOrDefault(patData.getPatienten_Geschlecht(), null));

Expand All @@ -99,33 +100,66 @@ public Bundle mapOnkoResourcesToPatient(List<MeldungExport> meldungExportList) {
new DateType(getBirthDateYearMonthString(patData.getPatienten_Geburtsdatum())));
}

var reportingReason =
meldungExport
.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
.getMeldeanlass();
// check if any one of the meldungen reported the death
var deathReports =
meldungExportList.stream()
.filter(m -> getReportingReasonFromAdt(m) == Meldeanlass.TOD)
.toList();

// deceased
if (reportingReason == Meldeanlass.TOD) {
var mengeVerlauf =
meldungExport
.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
.getMenge_Verlauf();

if (mengeVerlauf != null && mengeVerlauf.getVerlauf() != null) {

var death = mengeVerlauf.getVerlauf().getTod();

if (death.getSterbedatum() != null) {
patient.setDeceased(convertObdsDateToDateTimeType(death.getSterbedatum()));
}
if (!deathReports.isEmpty()) {
// start by setting deceased to true. If a more detailed death date is
// available in the data, override it further down this code path.
patient.setDeceased(new BooleanType(true));

// get the first entry with the largest version number where the death date is set
var reportWithSterbeDatum =
deathReports.stream()
.sorted(Comparator.comparingInt(MeldungExport::getVersionsnummer).reversed())
.filter(
m -> {
var mengeVerlauf =
m.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
.getMenge_Verlauf();

if (mengeVerlauf == null) {
return false;
}

if (mengeVerlauf.getVerlauf() == null) {
return false;
}

if (mengeVerlauf.getVerlauf().getTod() == null) {
return false;
}

return StringUtils.hasLength(
mengeVerlauf.getVerlauf().getTod().getSterbedatum());
})
.findFirst();

if (reportWithSterbeDatum.isPresent()) {
var deathDate =
reportWithSterbeDatum
.get()
.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
.getMenge_Verlauf()
.getVerlauf()
.getTod()
.getSterbedatum();

patient.setDeceased(convertObdsDateToDateTimeType(deathDate));
} else {
LOG.warn("Sterbedatum not set on any of the Tod Meldungen.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,6 @@ public static List<MeldungExport> prioritiseLatestMeldungExports(
return index == -1 ? Integer.MAX_VALUE : index;
});

// TODO: do this in-place sort instead:
// meldungExportList.sort(meldungComparator);

return meldungExportList.stream().sorted(meldungComparator).collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,19 +166,8 @@ public ValueMapper<MeldungExportList, Bundle> getOnkoToObservationBundleMapper()
}

public ValueMapper<MeldungExportList, Bundle> getOnkoToPatientBundleMapper() {
return meldungExporte -> {
List<MeldungExport> meldungExportList =
prioritiseLatestMeldungExports(
meldungExporte,
Arrays.asList(
Meldeanlass.TOD,
Meldeanlass.BEHANDLUNGSENDE,
Meldeanlass.STATUSAENDERUNG,
Meldeanlass.DIAGNOSE),
null);

return onkoPatientMapper.mapOnkoResourcesToPatient(meldungExportList);
};
return meldungExporte ->
onkoPatientMapper.mapOnkoResourcesToPatient(meldungExporte.getElements());
}

public ValueMapper<Pair<MeldungExportList, Bundle>, Bundle> getOnkoToConditionBundleMapper() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,15 @@ void extractDateTimeFromADTDate_withGivenObdsDate_shouldConvertToExpectedFhirDat
@Test
void
prioritiseLatestMeldungExports_withSamePrioriyOrderUsedForMappingThePatientResource_shouldHandleMultipleDeathReports() {
var expectedFirstDeathMeldung = createMeldungExport("3", 5, Meldeanlass.TOD);

var meldungExports = new MeldungExportList();
meldungExports.addElement(createMeldungExport("0", 1, Meldeanlass.DIAGNOSE));
meldungExports.addElement(createMeldungExport("1", 1, Meldeanlass.BEHANDLUNGSBEGINN));
meldungExports.addElement(createMeldungExport("2", 1, Meldeanlass.BEHANDLUNGSENDE));
meldungExports.addElement(createMeldungExport("3", 1, Meldeanlass.TOD));
meldungExports.addElement(createMeldungExport("4", 3, Meldeanlass.BEHANDLUNGSBEGINN));
meldungExports.addElement(createMeldungExport("3", 5, Meldeanlass.TOD));
meldungExports.addElement(expectedFirstDeathMeldung);
meldungExports.addElement(createMeldungExport("6", 7, Meldeanlass.BEHANDLUNGSENDE));
meldungExports.addElement(createMeldungExport("0", 2, Meldeanlass.DIAGNOSE));
meldungExports.addElement(createMeldungExport("3", 3, Meldeanlass.TOD));
Expand All @@ -80,6 +82,6 @@ void extractDateTimeFromADTDate_withGivenObdsDate_shouldConvertToExpectedFhirDat
Meldeanlass.DIAGNOSE),
null);

assertThat(prioritised).isNotEmpty();
assertThat(prioritised).first().isEqualTo(expectedFirstDeathMeldung);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
import java.util.stream.Stream;
import org.approvaltests.Approvals;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.miracum.streams.ume.obdstofhir.mapper.*;
import org.miracum.streams.ume.obdstofhir.model.ADT_GEKID;
import org.miracum.streams.ume.obdstofhir.model.Meldeanlass;
import org.miracum.streams.ume.obdstofhir.model.MeldungExport;
import org.miracum.streams.ume.obdstofhir.model.MeldungExportList;
import org.miracum.streams.ume.obdstofhir.model.Tupel;
Expand All @@ -28,7 +30,7 @@ public ObdsPatientMapperTest(ObdsPatientMapper onkoPatientMapper) {
this.onkoPatientMapper = onkoPatientMapper;
}

private static MeldungExportList createMeldungExportListFromPLZ(String plz) {
private static MeldungExport createMeldungExportFromPLZ(String plz) {
// TODO: we might want to introduce more concise builder patterns
var meldung = new ADT_GEKID.Menge_Patient.Patient.Menge_Meldung.Meldung();
meldung.setMeldung_ID("id-" + plz);
Expand Down Expand Up @@ -62,6 +64,17 @@ private static MeldungExportList createMeldungExportListFromPLZ(String plz) {
var meldungExport = new MeldungExport();
meldungExport.setXml_daten(obdsData);

return meldungExport;
}

private static MeldungExportList createMeldungExportListFromPLZ(String plz) {
var meldungExport = createMeldungExportFromPLZ(plz);

return createMeldungExportListFromMeldungExport(meldungExport);
}

private static MeldungExportList createMeldungExportListFromMeldungExport(
MeldungExport meldungExport) {
var meldungExportList = new MeldungExportList();
meldungExportList.addElement(meldungExport);

Expand Down Expand Up @@ -126,4 +139,86 @@ void mapOnkoResourcesToPatient_withMeldungExportWithInvalidPLZ_shouldCreateNotFi

assertThat(patient.getAddress()).isEmpty();
}

@Test
void
mapOnkoResourcesToPatient_withMeldungExportListWithMultipleDeathReports_shouldSetDeathDateFromMostRecentReport()
throws IOException {
var meldungExportList = new MeldungExportList();
for (int i = 1; i < 6; i++) {
var tod =
new ADT_GEKID.Menge_Patient.Patient.Menge_Meldung.Meldung.Menge_Verlauf.Verlauf.Tod();
tod.setSterbedatum(String.format("%02d.%02d.2%03d", i, i, i));
var verlauf =
new ADT_GEKID.Menge_Patient.Patient.Menge_Meldung.Meldung.Menge_Verlauf.Verlauf();
verlauf.setTod(tod);
var mengeVerlauf = new ADT_GEKID.Menge_Patient.Patient.Menge_Meldung.Meldung.Menge_Verlauf();
mengeVerlauf.setVerlauf(verlauf);
var meldungExport = createMeldungExportFromPLZ("" + i);
meldungExport.setVersionsnummer(i);
meldungExport
.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
// set death only for even "i"s for more realistic testing.
.setMeldeanlass(i % 2 == 0 ? Meldeanlass.TOD : Meldeanlass.DIAGNOSE);
meldungExport
.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
.setMenge_Verlauf(mengeVerlauf);

meldungExportList.addElement(meldungExport);
}

var resultBundle = onkoPatientMapper.mapOnkoResourcesToPatient(meldungExportList.getElements());

assertThat(resultBundle.getEntry()).hasSize(1);

var patient = (Patient) resultBundle.getEntry().get(0).getResource();

assertThat(patient.getDeceasedDateTimeType().asStringValue()).isEqualTo("2004-04-04");
}

@Test
void mapOnkoResourcesToPatient_withMeldungExportListWithoutDeathDate_shouldSetDeathBooleanToTrue()
throws IOException {
var tod = new ADT_GEKID.Menge_Patient.Patient.Menge_Meldung.Meldung.Menge_Verlauf.Verlauf.Tod();
var verlauf = new ADT_GEKID.Menge_Patient.Patient.Menge_Meldung.Meldung.Menge_Verlauf.Verlauf();
verlauf.setTod(tod);
var mengeVerlauf = new ADT_GEKID.Menge_Patient.Patient.Menge_Meldung.Meldung.Menge_Verlauf();
mengeVerlauf.setVerlauf(verlauf);
var meldungExport = createMeldungExportFromPLZ("" + 0);
meldungExport.setVersionsnummer(0);
meldungExport
.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
// set death only for even "i"s for more realistic testing.
.setMeldeanlass(Meldeanlass.TOD);
meldungExport
.getXml_daten()
.getMenge_Patient()
.getPatient()
.getMenge_Meldung()
.getMeldung()
.setMenge_Verlauf(mengeVerlauf);

var meldungExportList = new MeldungExportList();
meldungExportList.addElement(meldungExport);

var resultBundle = onkoPatientMapper.mapOnkoResourcesToPatient(meldungExportList.getElements());

assertThat(resultBundle.getEntry()).hasSize(1);

var patient = (Patient) resultBundle.getEntry().get(0).getResource();

assertThat(patient.getDeceasedBooleanType().getValue()).isTrue();
}
}

0 comments on commit e815fc1

Please sign in to comment.