diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/KpaTherapielinieDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/KpaTherapielinieDataMapper.java new file mode 100644 index 0000000..5d3dc1e --- /dev/null +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/KpaTherapielinieDataMapper.java @@ -0,0 +1,185 @@ +package dev.pcvolkmer.onco.datamapper.mapper; + +import dev.pcvolkmer.mv64e.mtb.*; +import dev.pcvolkmer.onco.datamapper.ResultSet; +import dev.pcvolkmer.onco.datamapper.datacatalogues.TherapielinieCatalogue; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Mapper class to load and map prozedur data from database table 'dk_dnpm_therapielinie' + * + * @author Paul-Christian Volkmer + * @since 0.1 + */ +public class KpaTherapielinieDataMapper implements SubformDataMapper { + + private final TherapielinieCatalogue catalogue; + + public KpaTherapielinieDataMapper(final TherapielinieCatalogue catalogue) { + this.catalogue = catalogue; + } + + /** + * Loads and maps Prozedur related by database id + * + * @param id The database id of the procedure data set + * @return The loaded MtbDiagnosis file + */ + @Override + public MtbSystemicTherapy getById(final int id) { + var data = catalogue.getById(id); + return this.map(data); + } + + @Override + public List getByParentId(final int parentId) { + return catalogue.getAllByParentId(parentId) + .stream() + .map(this::map) + .collect(Collectors.toList()); + } + + private MtbSystemicTherapy map(final ResultSet resultSet) { + var diseases = catalogue.getDiseases(resultSet.getProcedureId()); + + if (diseases.size() != 1) { + throw new IllegalStateException(String.format("No unique disease for procedure %s", resultSet.getProcedureId())); + } + + var builder = MtbSystemicTherapy.builder(); + builder + .id(resultSet.getString("id")) + .patient(Reference.builder().id(resultSet.getString("patient_id")).build()) + .basedOn(Reference.builder().id(diseases.get(0).getDiseaseId().toString()).build()) + .recordedOn(resultSet.getDate("erfassungsdatum")) + .therapyLine(resultSet.getLong("therapielinie")) + .intent(getMtbTherapyIntentCoding(resultSet.getString("intention"))) + .status(getTherapyStatusCoding(resultSet.getString("status"))) + .statusReason(getMtbTherapyStatusReasonCoding(resultSet.getString("statusgrund"))) + .period(PeriodDate.builder().start(resultSet.getDate("beginn")).end(resultSet.getDate("ende")).build()) + /* TODO JSON deserialisation */ + //.medication() + + /* TODO Yet missing form fields */ + //.category(getMtbSystemicTherapyCategoryCoding()) + //.dosage(getMtbSystemicTherapyDosageDensityCoding()) + //.recommendationFulfillmentStatus(getMtbSystemicTherapyRecommendationFulfillmentStatusCoding() + ; + return builder.build(); + } + + private MtbTherapyIntentCoding getMtbTherapyIntentCoding(String value) { + if (value == null || !Arrays.stream(MtbTherapyIntentCodingCode.values()).map(MtbTherapyIntentCodingCode::toValue).collect(Collectors.toSet()).contains(value)) { + return null; + } + + var resultBuilder = MtbTherapyIntentCoding.builder(); + + switch (value) { + case "X": + resultBuilder.code(MtbTherapyIntentCodingCode.X); + break; + case "K": + resultBuilder.code(MtbTherapyIntentCodingCode.K); + break; + case "P": + resultBuilder.code(MtbTherapyIntentCodingCode.P); + break; + case "S": + resultBuilder.code(MtbTherapyIntentCodingCode.S); + break; + } + + return resultBuilder.build(); + } + + private TherapyStatusCoding getTherapyStatusCoding(String value) { + if (value == null || !Arrays.stream(TherapyStatusCodingCode.values()).map(TherapyStatusCodingCode::toValue).collect(Collectors.toSet()).contains(value)) { + return null; + } + + var resultBuilder = TherapyStatusCoding.builder(); + + switch (value) { + case "not-done": + resultBuilder.code(TherapyStatusCodingCode.NOT_DONE); + break; + case "on-going": + resultBuilder.code(TherapyStatusCodingCode.ON_GOING); + break; + case "stopped": + resultBuilder.code(TherapyStatusCodingCode.STOPPED); + break; + case "completed": + resultBuilder.code(TherapyStatusCodingCode.COMPLETED); + break; + } + + return resultBuilder.build(); + } + + private MtbTherapyStatusReasonCoding getMtbTherapyStatusReasonCoding(String value) { + if (value == null || !Arrays.stream(MtbTherapyStatusReasonCodingCode.values()).map(MtbTherapyStatusReasonCodingCode::toValue).collect(Collectors.toSet()).contains(value)) { + return null; + } + + var resultBuilder = MtbTherapyStatusReasonCoding.builder(); + try { + resultBuilder.code(MtbTherapyStatusReasonCodingCode.forValue(value)); + } catch (IOException e) { + return null; + } + + return resultBuilder.build(); + } + + private MtbSystemicTherapyRecommendationFulfillmentStatusCoding getMtbSystemicTherapyRecommendationFulfillmentStatusCoding(String value) { + if (value == null || !Arrays.stream(MtbSystemicTherapyRecommendationFulfillmentStatusCodingCode.values()).map(MtbSystemicTherapyRecommendationFulfillmentStatusCodingCode::toValue).collect(Collectors.toSet()).contains(value)) { + return null; + } + + var resultBuilder = MtbSystemicTherapyRecommendationFulfillmentStatusCoding.builder(); + try { + resultBuilder.code(MtbSystemicTherapyRecommendationFulfillmentStatusCodingCode.forValue(value)); + } catch (IOException e) { + return null; + } + + return resultBuilder.build(); + } + + private MtbSystemicTherapyCategoryCoding getMtbSystemicTherapyCategoryCoding(String value) { + if (value == null || !Arrays.stream(MtbSystemicTherapyCategoryCodingCode.values()).map(MtbSystemicTherapyCategoryCodingCode::toValue).collect(Collectors.toSet()).contains(value)) { + return null; + } + + var resultBuilder = MtbSystemicTherapyCategoryCoding.builder(); + try { + resultBuilder.code(MtbSystemicTherapyCategoryCodingCode.forValue(value)); + } catch (IOException e) { + return null; + } + + return resultBuilder.build(); + } + + private MtbSystemicTherapyDosageDensityCoding getMtbSystemicTherapyDosageDensityCoding(String value) { + if (value == null || !Arrays.stream(MtbSystemicTherapyDosageDensityCodingCode.values()).map(MtbSystemicTherapyDosageDensityCodingCode::toValue).collect(Collectors.toSet()).contains(value)) { + return null; + } + + var resultBuilder = MtbSystemicTherapyDosageDensityCoding.builder(); + try { + resultBuilder.code(MtbSystemicTherapyDosageDensityCodingCode.forValue(value)); + } catch (IOException e) { + return null; + } + + return resultBuilder.build(); + } + +} diff --git a/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/KpaTherapielinieDataMapperTest.java b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/KpaTherapielinieDataMapperTest.java new file mode 100644 index 0000000..ff22e2a --- /dev/null +++ b/src/test/java/dev/pcvolkmer/onco/datamapper/mapper/KpaTherapielinieDataMapperTest.java @@ -0,0 +1,101 @@ +package dev.pcvolkmer.onco.datamapper.mapper; + +import dev.pcvolkmer.mv64e.mtb.*; +import dev.pcvolkmer.onco.datamapper.ResultSet; +import dev.pcvolkmer.onco.datamapper.datacatalogues.TherapielinieCatalogue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class KpaTherapielinieDataMapperTest { + + TherapielinieCatalogue catalogue; + + KpaTherapielinieDataMapper dataMapper; + + @BeforeEach + void setUp(@Mock TherapielinieCatalogue catalogue) { + this.catalogue = catalogue; + this.dataMapper = new KpaTherapielinieDataMapper(catalogue); + } + + @Test + void shouldMapResultSet(@Mock ResultSet resultSet) { + var testData = Map.of( + "erkrankung.id", "1", + "id", "1", + "beginn", new java.sql.Date(Date.from(Instant.parse("2000-01-01T12:00:00Z")).getTime()), + "ende", new java.sql.Date(Date.from(Instant.parse("2024-06-19T12:00:00Z")).getTime()), + "erfassungsdatum", new java.sql.Date(Date.from(Instant.parse("2024-06-19T12:00:00Z")).getTime()), + "intention", "S", + "status", "stopped", + "statusgrund", "patient-death", + "therapielinie", 1L + ); + + doAnswer(invocationOnMock -> { + var columnName = invocationOnMock.getArgument(0, String.class); + return testData.get(columnName); + }).when(resultSet).getString(anyString()); + + doAnswer(invocationOnMock -> { + var columnName = invocationOnMock.getArgument(0, String.class); + return testData.get(columnName); + }).when(resultSet).getLong(anyString()); + + doAnswer(invocationOnMock -> { + var columnName = invocationOnMock.getArgument(0, String.class); + return testData.get(columnName); + }).when(resultSet).getDate(anyString()); + + when(resultSet.getDiseaseId()).thenReturn(1); + when(resultSet.getProcedureId()).thenReturn(1); + + doAnswer(invocationOnMock -> List.of(resultSet)) + .when(catalogue) + .getAllByParentId(anyInt()); + + doAnswer(invocationOnMock -> List.of(resultSet)) + .when(catalogue) + .getDiseases(anyInt()); + + var actualList = this.dataMapper.getByParentId(1); + assertThat(actualList).hasSize(1); + + var actual = actualList.get(0); + assertThat(actual).isInstanceOf(MtbSystemicTherapy.class); + assertThat(actual.getId()).isEqualTo("1"); + assertThat(actual.getPeriod()).isEqualTo( + PeriodDate.builder() + .start(Date.from(Instant.parse("2000-01-01T12:00:00Z"))) + .end(Date.from(Instant.parse("2024-06-19T12:00:00Z"))) + .build() + ); + assertThat(actual.getRecordedOn()).isEqualTo(Date.from(Instant.parse("2024-06-19T12:00:00Z"))); + assertThat(actual.getIntent()).isEqualTo( + MtbTherapyIntentCoding.builder().code(MtbTherapyIntentCodingCode.S).build() + ); + assertThat(actual.getStatus()).isEqualTo( + TherapyStatusCoding.builder().code(TherapyStatusCodingCode.STOPPED).build() + ); + assertThat(actual.getStatusReason()).isEqualTo( + MtbTherapyStatusReasonCoding.builder().code(MtbTherapyStatusReasonCodingCode.PATIENT_DEATH).build() + ); + assertThat(actual.getTherapyLine()).isEqualTo(1); + } + +}