diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/DataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/DataMapper.java index 5db752b..b4e418b 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/DataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/DataMapper.java @@ -1,5 +1,7 @@ package dev.pcvolkmer.onco.datamapper; +import java.util.Date; + /** * General interface for all data mappers * @@ -16,4 +18,16 @@ public interface DataMapper { */ T getById(int id); + /** + * Maps java.sql.Date to java.util.Date + * @param date + * @return + */ + default Date mapDate(java.sql.Date date) { + if (date == null) { + return null; + } + return new Date(date.getTime()); + } + } diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/KpaPatientDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/KpaPatientDataMapper.java new file mode 100644 index 0000000..7c0938f --- /dev/null +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/KpaPatientDataMapper.java @@ -0,0 +1,120 @@ +package dev.pcvolkmer.onco.datamapper; + +import dev.pcvolkmer.mv64e.mtb.*; +import dev.pcvolkmer.onco.datamapper.datacatalogues.KpaCatalogue; +import dev.pcvolkmer.onco.datamapper.exceptions.DataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Mapper class to load and map patient data from database table 'dk_dnpm_kpa' + * + * @author Paul-Christian Volkmer + * @since 0.1 + */ +public class KpaPatientDataMapper implements DataMapper { + + private final JdbcTemplate jdbcTemplate; + + private KpaPatientDataMapper(final JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + /** + * Create instance of the mapper class + * + * @param jdbcTemplate The Spring JdbcTemplate to be used + * @return The initialized mapper + */ + public static KpaPatientDataMapper create(final JdbcTemplate jdbcTemplate) { + return new KpaPatientDataMapper(jdbcTemplate); + } + + /** + * Loads and maps a patient using the kpa procedures database id + * + * @param id The database id of the procedure data set + * @return The loaded Patient data + */ + @Override + public Patient getById(int id) { + var kpaCatalogue = KpaCatalogue.create(this.jdbcTemplate); + var kpaData = kpaCatalogue.getById(id); + + var builder = Patient.builder(); + try { + builder + .id(kpaData.getString("patient_id")) + .gender(getGenderCoding(kpaData)) + .birthDate(mapDate(kpaData.getDate("geburtsdatum"))) + .dateOfDeath(mapDate(kpaData.getDate("sterbedatum"))) + .healthInsurance(getHealthInsurance(kpaData)) + ; + + } catch (SQLException e) { + throw new DataAccessException(e.getMessage()); + } + return builder.build(); + } + + private GenderCoding getGenderCoding(ResultSet data) throws SQLException { + var genderCodingBuilder = GenderCoding.builder(); + String geschlecht = data.getString("geschlecht"); + switch (geschlecht) { + case "m": + genderCodingBuilder.code(GenderCodingCode.MALE); + break; + case "w": + genderCodingBuilder.code(GenderCodingCode.FEMALE); + break; + case "d": + case "x": + genderCodingBuilder.code(GenderCodingCode.OTHER); + break; + default: + genderCodingBuilder.code(GenderCodingCode.UNKNOWN); + } + return genderCodingBuilder.build(); + } + + private HealthInsurance getHealthInsurance(ResultSet data) throws SQLException { + var healthInsuranceCodingBuilder = HealthInsuranceCoding.builder(); + String healthInsuranceType = data.getString("artderkrankenkasse"); + switch (healthInsuranceType) { + case "GKV": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.GKV).build(); + break; + case "PKV": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.PKV).build(); + break; + case "BG": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.BG).build(); + break; + case "SEL": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.SEL).build(); + break; + case "SOZ": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.SOZ).build(); + break; + case "GPV": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.GPV).build(); + break; + case "PPV": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.PPV).build(); + break; + case "BEI": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.BEI).build(); + break; + case "SKT": + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.SKT).build(); + break; + default: + healthInsuranceCodingBuilder.code(HealthInsuranceCodingCode.UNK).build(); + } + + return HealthInsurance.builder().type(healthInsuranceCodingBuilder.build()).build(); + } + +} diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/MtbDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/MtbDataMapper.java index 1c973e7..c88c202 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/MtbDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/MtbDataMapper.java @@ -54,11 +54,19 @@ public class MtbDataMapper implements DataMapper { */ @Override public Mtb getById(int kpaId) { + var patientDataMapper = PatientDataMapper.create(jdbcTemplate); + var kpaPatientDataMapper = KpaPatientDataMapper.create(jdbcTemplate); var diagnosisDataMapper = KpaDiagnosisDataMapper.create(jdbcTemplate); + var resultBuilder = Mtb.builder(); try { + var kpaPatient = kpaPatientDataMapper.getById(kpaId); + var patient = patientDataMapper.getById(Integer.parseInt(kpaPatient.getId())); + kpaPatient.setAddress(patient.getAddress()); + resultBuilder + .patient(kpaPatient) .diagnoses(List.of(diagnosisDataMapper.getById(kpaId))); } catch (DataAccessException e) { logger.error("Error while getting Mtb.", e); diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/PatientDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/PatientDataMapper.java index 95c691c..4d6dd81 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/PatientDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/PatientDataMapper.java @@ -90,11 +90,4 @@ public class PatientDataMapper implements DataMapper { return gkz.substring(0, 5); } - private Date mapDate(java.sql.Date date) { - if (date == null) { - return null; - } - return new Date(date.getTime()); - } - } diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/datacatalogues/KpaCatalogue.java b/src/main/java/dev/pcvolkmer/onco/datamapper/datacatalogues/KpaCatalogue.java index 5f63948..1c257ff 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/datacatalogues/KpaCatalogue.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/datacatalogues/KpaCatalogue.java @@ -30,7 +30,7 @@ public class KpaCatalogue { */ public ResultSet getById(int id) { var result = this.jdbcTemplate.query( - "SELECT * FROM dk_dnpm_kpa id = ?", + "SELECT * FROM dk_dnpm_kpa JOIN prozedur ON (prozedur.id = dk_dnpm_kpa.id) WHERE id = ?", (resultSet, i) -> resultSet, id); diff --git a/src/test/java/dev/pcvolkmer/onco/datamapper/KpaPatientDataMapperTest.java b/src/test/java/dev/pcvolkmer/onco/datamapper/KpaPatientDataMapperTest.java new file mode 100644 index 0000000..09ea679 --- /dev/null +++ b/src/test/java/dev/pcvolkmer/onco/datamapper/KpaPatientDataMapperTest.java @@ -0,0 +1,111 @@ +package dev.pcvolkmer.onco.datamapper; + +import dev.pcvolkmer.mv64e.mtb.*; +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 org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import javax.sql.DataSource; +import java.sql.ResultSet; +import java.sql.SQLException; +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.*; +import static org.mockito.Mockito.doAnswer; + +@ExtendWith(MockitoExtension.class) +class KpaPatientDataMapperTest { + + JdbcTemplate jdbcTemplate; + + KpaPatientDataMapper dataMapper; + + @BeforeEach + void setUp(@Mock JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + this.dataMapper = KpaPatientDataMapper.create(jdbcTemplate); + } + + @Test + void shouldCreateDataMapper(@Mock DataSource dataSource) { + assertThat(MtbDataMapper.create(dataSource)).isNotNull(); + } + + @Test + void shouldCreatePatientAlive(@Mock ResultSet resultSet) throws SQLException { + var testData = Map.of( + "patient_id", "1", + "geschlecht", "m", + "geburtsdatum", new java.sql.Date(Date.from(Instant.parse("2000-01-01T12:00:00Z")).getTime()), + "sterbedatum", new java.sql.Date(Date.from(Instant.parse("2024-06-19T12:00:00Z")).getTime()), + "artderkrankenkasse", "GKV" + ); + + 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).getDate(anyString()); + + doAnswer(invocationOnMock -> List.of(resultSet)) + .when(jdbcTemplate) + .query(anyString(), any(RowMapper.class), anyInt()); + + var actual = this.dataMapper.getById(1); + assertThat(actual).isInstanceOf(Patient.class); + assertThat(actual.getId()).isEqualTo("1"); + assertThat(actual.getGender().getCode()).isEqualTo(GenderCodingCode.MALE); + assertThat(actual.getBirthDate()).isEqualTo(Date.from(Instant.parse("2000-01-01T12:00:00Z"))); + assertThat(actual.getDateOfDeath()).isEqualTo(Date.from(Instant.parse("2024-06-19T12:00:00Z"))); + assertThat(actual.getHealthInsurance()).isEqualTo( + HealthInsurance.builder().type(HealthInsuranceCoding.builder().code(HealthInsuranceCodingCode.GKV).build()).build() + ); + } + + @Test + void shouldCreatePatientDead(@Mock ResultSet resultSet) throws SQLException { + var testData = Map.of( + "patient_id", "1", + "geschlecht", "w", + "geburtsdatum", new java.sql.Date(Date.from(Instant.parse("2000-01-01T12:00:00Z")).getTime()), + "artderkrankenkasse", "PKV" + ); + + 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).getDate(anyString()); + + doAnswer(invocationOnMock -> List.of(resultSet)) + .when(jdbcTemplate) + .query(anyString(), any(RowMapper.class), anyInt()); + + var actual = this.dataMapper.getById(1); + assertThat(actual).isInstanceOf(Patient.class); + assertThat(actual.getId()).isEqualTo("1"); + assertThat(actual.getGender().getCode()).isEqualTo(GenderCodingCode.FEMALE); + assertThat(actual.getBirthDate()).isEqualTo(Date.from(Instant.parse("2000-01-01T12:00:00Z"))); + assertThat(actual.getDateOfDeath()).isNull(); + assertThat(actual.getHealthInsurance()).isEqualTo( + HealthInsurance.builder().type(HealthInsuranceCoding.builder().code(HealthInsuranceCodingCode.PKV).build()).build() + ); + } + +}