diff --git a/src/main/java/DNPM/services/strahlentherapie/DefaultStrahlentherapieService.java b/src/main/java/DNPM/services/strahlentherapie/DefaultStrahlentherapieService.java new file mode 100644 index 0000000..b899d56 --- /dev/null +++ b/src/main/java/DNPM/services/strahlentherapie/DefaultStrahlentherapieService.java @@ -0,0 +1,73 @@ +package DNPM.services.strahlentherapie; + +import DNPM.services.SettingsService; +import de.itc.onkostar.api.IOnkostarApi; +import de.itc.onkostar.api.Patient; +import de.itc.onkostar.api.Procedure; + +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Standardimplementierung des StrahlentherapieServices + * + * @since 0.6.0 + */ +public class DefaultStrahlentherapieService implements StrahlentherapieService { + + private static final String ECOG_FIELD = "ECOGvorTherapie"; + + private final IOnkostarApi onkostarApi; + + private final SettingsService settingsService; + + public DefaultStrahlentherapieService(final IOnkostarApi onkostarApi, final SettingsService settingsService) { + this.onkostarApi = onkostarApi; + this.settingsService = settingsService; + } + + /** + * Ermittelt den letzten bekannten ECOG-Status aus allen Systemtherapieformularen des Patienten + * + * @param patient Der zu verwendende Patient + * @return Der ECOG-Status als String oder leeres Optional + */ + @Override + public Optional latestEcogStatus(Patient patient) { + return ecogStatus(patient).stream() + .max(Comparator.comparing(EcogStatusWithDate::getDate)) + .map(EcogStatusWithDate::getStatus); + } + + /** + * Ermittelt jeden bekannten ECOG-Status aus allen Systemtherapieformularen des Patienten + * + * @param patient Der zu verwendende Patient + * @return Eine Liste mit Datum und ECOG-Status als String + */ + @Override + public List ecogStatus(Patient patient) { + return patient.getDiseases().stream() + .flatMap(disease -> onkostarApi.getProceduresForDiseaseByForm(disease.getId(), getFormName()).stream()) + .filter(procedure -> null != procedure.getStartDate()) + .sorted(Comparator.comparing(Procedure::getStartDate)) + .map(procedure -> { + try { + return new EcogStatusWithDate(procedure.getStartDate(), procedure.getValue(ECOG_FIELD).getString()); + } catch (IllegalArgumentException e) { + return null; + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + private String getFormName() { + return settingsService + .getSetting("strahlentherapieform") + .orElse("OS.Strahlentherapie"); + } +} diff --git a/src/main/java/DNPM/services/strahlentherapie/StrahlentherapieService.java b/src/main/java/DNPM/services/strahlentherapie/StrahlentherapieService.java new file mode 100644 index 0000000..f5cef46 --- /dev/null +++ b/src/main/java/DNPM/services/strahlentherapie/StrahlentherapieService.java @@ -0,0 +1,70 @@ +package DNPM.services.strahlentherapie; + +import de.itc.onkostar.api.Patient; +import org.springframework.util.Assert; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +/** + * Service für Systemtherapieformulare + * + * @since 0.6.0 + */ +public interface StrahlentherapieService { + + /** + * Ermittelt den letzten bekannten ECOG-Status aus allen Systemtherapieformularen des Patienten + * @param patient Der zu verwendende Patient + * @return Der ECOG-Status als String oder leeres Optional + */ + Optional latestEcogStatus(Patient patient); + + /** + * Ermittelt jeden bekannten ECOG-Status aus allen Strahlentherapieformularen des Patienten + * @param patient Der zu verwendende Patient + * @return Eine Liste mit Datum und ECOG-Status als String + */ + List ecogStatus(Patient patient); + + /** + * Datenklasse zum Abbilden des ECOG-Status und Datum + */ + class EcogStatusWithDate { + private Date date; + private String status; + + public EcogStatusWithDate(Date date, String status) { + Assert.notNull(date, "Date cannot be null"); + Assert.hasText(status, "Status cannot be empty String"); + Assert.isTrue(isValidEcogCode(status), "Not a valid ADT.LeistungszustandECOG code"); + this.date = date; + this.status = status; + } + + private boolean isValidEcogCode(String status) { + switch (status) { + case "0": + case "1": + case "2": + case "3": + case "4": + case "5": + case "U": + return true; + default: + return false; + } + } + + public Date getDate() { + return date; + } + + public String getStatus() { + return status; + } + } + +} diff --git a/src/test/java/DNPM/services/strahlentherapie/DefaultStrahlentherapieServiceTest.java b/src/test/java/DNPM/services/strahlentherapie/DefaultStrahlentherapieServiceTest.java new file mode 100644 index 0000000..652aa16 --- /dev/null +++ b/src/test/java/DNPM/services/strahlentherapie/DefaultStrahlentherapieServiceTest.java @@ -0,0 +1,106 @@ +package DNPM.services.strahlentherapie; + +import DNPM.services.SettingsService; +import de.itc.onkostar.api.*; +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +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.*; + +@ExtendWith(MockitoExtension.class) +class DefaultStrahlentherapieServiceTest { + + private IOnkostarApi onkostarApi; + + private SettingsService settingsService; + + private DefaultStrahlentherapieService service; + + @BeforeEach + void setup(@Mock IOnkostarApi onkostarApi, @Mock SettingsService settingsService) { + this.onkostarApi = onkostarApi; + this.settingsService = settingsService; + this.service = new DefaultStrahlentherapieService(onkostarApi, settingsService); + } + + @Test + void testShouldRequestProceduresWithDefaultFormName() { + when(this.settingsService.getSetting(anyString())).thenReturn(Optional.empty()); + + doAnswer(invocationOnMock -> { + var procedure = new Procedure(onkostarApi); + procedure.setId(1); + procedure.setFormName("OS.Strahlentherapie"); + procedure.setStartDate(Date.from(Instant.parse("2023-07-01T06:00:00Z"))); + procedure.setEditState(ProcedureEditStateType.COMPLETED); + procedure.setValue("ECOGvorTherapie", new Item("ECOGvorTherapie", 1)); + return Lists.list(procedure); + }).when(this.onkostarApi).getProceduresForDiseaseByForm(anyInt(), anyString()); + + doAnswer(invocationOnMock -> { + var disease = new Disease(onkostarApi); + disease.setId(1); + disease.setPatientId(123); + return Lists.list(disease); + }).when(this.onkostarApi).getDiseasesByPatientId(anyInt()); + + var patient = new Patient(onkostarApi); + patient.setId(123); + + service.ecogStatus(patient); + + var argumentCaptor = ArgumentCaptor.forClass(String.class); + verify(onkostarApi, times(1)).getProceduresForDiseaseByForm(anyInt(), argumentCaptor.capture()); + assertThat(argumentCaptor.getValue()).isEqualTo("OS.Strahlentherapie"); + } + + @Test + void testShouldReturnListOfEcogStatusWithDate() { + doAnswer(invocationOnMock -> { + var disease = new Disease(onkostarApi); + disease.setId(1); + return List.of(disease); + }).when(this.onkostarApi).getDiseasesByPatientId(anyInt()); + + doAnswer(invocationOnMock -> { + var procedure1 = new Procedure(onkostarApi); + procedure1.setId(1); + procedure1.setFormName("OS.Strahlentherapie"); + procedure1.setStartDate(Date.from(Instant.parse("2023-07-01T06:00:00Z"))); + procedure1.setEditState(ProcedureEditStateType.COMPLETED); + procedure1.setValue("ECOGvorTherapie", new Item("ECOGvorTherapie", 1)); + + var procedure2 = new Procedure(onkostarApi); + procedure2.setId(2); + procedure2.setFormName("OS.Strahlentherapie"); + procedure2.setStartDate(Date.from(Instant.parse("2023-07-12T06:00:00Z"))); + procedure2.setEditState(ProcedureEditStateType.COMPLETED); + procedure2.setValue("ECOGvorTherapie", new Item("ECOGvorTherapie", 2)); + return List.of(procedure1, procedure2); + }).when(this.onkostarApi).getProceduresForDiseaseByForm(anyInt(), anyString()); + + var patient = new Patient(onkostarApi); + patient.setId(1); + + var actual = service.ecogStatus(patient); + + assertThat(actual) + .isNotNull() + .isExactlyInstanceOf(ArrayList.class) + .hasSize(2); + } +}