diff --git a/README.md b/README.md index 09c23d3..eb0a5f8 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,11 @@ VALUES ( ## Mapping MTB zu Therapieplan-Protokollauszug -Das Plugin ermöglicht die Übernahme von Inhalten aus einem MTB in den Protokollauszug des DNPM Therapieplans. Für die beiden Formulare +Das Plugin ermöglicht die Übernahme von Inhalten aus einem MTB in den Protokollauszug des DNPM Therapieplans. Für die Formulare * `OS.Tumorkonferenz` * `OS.Tumorkonferenz.VarianteUKW` +* `MR.MTB_Anmeldung` liegen bereits Implementierungen vor. Um eigene Implementierungen vorzunehmen, die sich an andere Formulare oder Formularvarianten richtet, muss hierzu das Interface `ProcedureToProtocolMapper` implementiert werden. Dazu muss die Methode `apply(Procedure)` derart implementiert werden, @@ -29,7 +30,7 @@ sodass aus einer Prozedur ein entsprechender Abschnitt als Text für den Protoko Als Rückgabewert wird hierbei ein Wert vom Typ `Optional` erwartet, dabei z.B. `Optional.of("Text")`, wenn ein zu verwendender Text oder z.B. `Optional.empty()` wenn kein zu verwendender Text zurückgegeben wird. -Anschließend ist das Mapping im Interface `MtbService` in der Methode `procedureToProtocolMapper(Procedure)` einzutragen, beispielsweise durch +Anschließend ist das Mapping in `DefaultMtbService` in der Methode `procedureToProtocolMapper(Procedure)` einzutragen, beispielsweise durch ``` ... diff --git a/src/main/java/DNPM/config/PluginConfiguration.java b/src/main/java/DNPM/config/PluginConfiguration.java index 7cb8475..88f065b 100644 --- a/src/main/java/DNPM/config/PluginConfiguration.java +++ b/src/main/java/DNPM/config/PluginConfiguration.java @@ -38,8 +38,8 @@ public class PluginConfiguration { } @Bean - public MtbService mtbService() { - return new DefaultMtbService(); + public MtbService mtbService(final IOnkostarApi onkostarApi) { + return new DefaultMtbService(onkostarApi); } @Bean diff --git a/src/main/java/DNPM/services/mtb/DefaultMtbService.java b/src/main/java/DNPM/services/mtb/DefaultMtbService.java index 9926a82..abfbf59 100644 --- a/src/main/java/DNPM/services/mtb/DefaultMtbService.java +++ b/src/main/java/DNPM/services/mtb/DefaultMtbService.java @@ -1,5 +1,6 @@ package DNPM.services.mtb; +import de.itc.onkostar.api.IOnkostarApi; import de.itc.onkostar.api.Procedure; import java.util.Comparator; @@ -14,12 +15,18 @@ import java.util.stream.Collectors; */ public class DefaultMtbService implements MtbService { + private final IOnkostarApi onkostarApi; + + public DefaultMtbService(final IOnkostarApi onkostarApi) { + this.onkostarApi = onkostarApi; + } + @Override public String getProtocol(List procedures) { return procedures.stream() .sorted(Comparator.comparing(Procedure::getStartDate)) .map(procedure -> { - var mapper = MtbService.procedureToProtocolMapper(procedure); + var mapper = procedureToProtocolMapper(procedure); return mapper.apply(procedure); }) .filter(Optional::isPresent) @@ -29,4 +36,18 @@ public class DefaultMtbService implements MtbService { } + @Override + public ProcedureToProtocolMapper procedureToProtocolMapper(Procedure procedure) { + switch (procedure.getFormName()) { + case "OS.Tumorkonferenz": + return new OsTumorkonferenzToProtocolMapper(); + case "OS.Tumorkonferenz.VarianteUKW": + return new OsTumorkonferenzVarianteUkwToProtocolMapper(); + case "MR.MTB_Anmeldung": + return new MrMtbAnmeldungToProtocolMapper(this.onkostarApi); + default: + return p -> Optional.empty(); + } + } + } diff --git a/src/main/java/DNPM/services/mtb/MrMtbAnmeldungToProtocolMapper.java b/src/main/java/DNPM/services/mtb/MrMtbAnmeldungToProtocolMapper.java new file mode 100644 index 0000000..eac1127 --- /dev/null +++ b/src/main/java/DNPM/services/mtb/MrMtbAnmeldungToProtocolMapper.java @@ -0,0 +1,54 @@ +package DNPM.services.mtb; + +import de.itc.onkostar.api.IOnkostarApi; +import de.itc.onkostar.api.Procedure; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Optional; + +public class MrMtbAnmeldungToProtocolMapper implements ProcedureToProtocolMapper { + + private final IOnkostarApi onkostarApi; + + public MrMtbAnmeldungToProtocolMapper(final IOnkostarApi onkostarApi) { + this.onkostarApi = onkostarApi; + } + + @Override + public Optional apply(Procedure procedure) { + assert (procedure.getFormName().equals("MR.MTB_Anmeldung")); + + var resultParts = new ArrayList(); + + var fragestellung = procedure.getValue("Fragestellung"); + if (null != fragestellung && !fragestellung.getString().isBlank()) { + resultParts.add(String.format("Fragestellung:\n%s", fragestellung.getString())); + } + + var refEmpfehlung = procedure.getValue("Empfehlung"); + if (null != refEmpfehlung && refEmpfehlung.getInt() > 0) { + var empfehlungsProzedur = onkostarApi.getProcedure(refEmpfehlung.getInt()); + var refEinzelempfehlungen = onkostarApi.getSubprocedures(empfehlungsProzedur.getId()); + + if (null != refEinzelempfehlungen) { + refEinzelempfehlungen.stream() + .sorted(Comparator.comparingInt(proc -> proc.getValue("Prioritaet").getInt())) + .forEach(proc -> { + if (proc.getFormName().equals("MR.MTB_Einzelempfehlung")) { + var empfehlung = proc.getValue("Empfehlung"); + if (null != empfehlung && !empfehlung.getString().isBlank()) { + resultParts.add(String.format("Empfehlung:\n%s", empfehlung.getString())); + } + } + }); + } + } + + if (resultParts.isEmpty()) { + return Optional.empty(); + } + + return Optional.of(String.join("\n\n", resultParts)); + } +} diff --git a/src/main/java/DNPM/services/mtb/MtbService.java b/src/main/java/DNPM/services/mtb/MtbService.java index fcf55c1..19bbe38 100644 --- a/src/main/java/DNPM/services/mtb/MtbService.java +++ b/src/main/java/DNPM/services/mtb/MtbService.java @@ -3,19 +3,9 @@ package DNPM.services.mtb; import de.itc.onkostar.api.Procedure; import java.util.List; -import java.util.Optional; public interface MtbService { String getProtocol(List procedures); - static ProcedureToProtocolMapper procedureToProtocolMapper(Procedure procedure) { - switch (procedure.getFormName()) { - case "OS.Tumorkonferenz": - return new OsTumorkonferenzToProtocolMapper(); - case "OS.Tumorkonferenz.VarianteUKW": - return new OsTumorkonferenzVarianteUkwToProtocolMapper(); - default: - return p -> Optional.empty(); - } - } + ProcedureToProtocolMapper procedureToProtocolMapper(Procedure procedure); } diff --git a/src/test/java/DNPM/services/mtb/DefaultMtbServiceTest.java b/src/test/java/DNPM/services/mtb/DefaultMtbServiceTest.java index f730c85..f5bc374 100644 --- a/src/test/java/DNPM/services/mtb/DefaultMtbServiceTest.java +++ b/src/test/java/DNPM/services/mtb/DefaultMtbServiceTest.java @@ -6,13 +6,13 @@ import de.itc.onkostar.api.Procedure; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.time.Instant; -import java.util.Arrays; -import java.util.Date; -import java.util.List; +import java.util.*; import static org.assertj.core.api.Assertions.assertThat; @@ -28,7 +28,26 @@ public class DefaultMtbServiceTest { @Mock IOnkostarApi onkostarApi ) { this.onkostarApi = onkostarApi; - this.service = new DefaultMtbService(); + this.service = new DefaultMtbService(onkostarApi); + } + + private static Set>> expectedMappings() { + return Map.ofEntries( + Map.entry("OS.Tumorkonferenz", OsTumorkonferenzToProtocolMapper.class), + Map.entry("OS.Tumorkonferenz.VarianteUKW", OsTumorkonferenzVarianteUkwToProtocolMapper.class), + Map.entry("MR.MTB_Anmeldung", MrMtbAnmeldungToProtocolMapper.class) + ).entrySet(); + } + + @ParameterizedTest + @MethodSource("expectedMappings") + void testShouldMapFormNameToMapper(Map.Entry> expectedMapping) { + var procedure = new Procedure(onkostarApi); + procedure.setFormName(expectedMapping.getKey()); + + var actual = service.procedureToProtocolMapper(procedure); + + assertThat(actual).isExactlyInstanceOf(expectedMapping.getValue()); } @Test diff --git a/src/test/java/DNPM/services/mtb/MrMtbAnmeldungToProtocolMapperTest.java b/src/test/java/DNPM/services/mtb/MrMtbAnmeldungToProtocolMapperTest.java new file mode 100644 index 0000000..479549c --- /dev/null +++ b/src/test/java/DNPM/services/mtb/MrMtbAnmeldungToProtocolMapperTest.java @@ -0,0 +1,87 @@ +package DNPM.services.mtb; + +import de.itc.onkostar.api.IOnkostarApi; +import de.itc.onkostar.api.Item; +import de.itc.onkostar.api.Procedure; +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.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; + +@ExtendWith(MockitoExtension.class) +public class MrMtbAnmeldungToProtocolMapperTest { + + private IOnkostarApi onkostarApi; + + private MrMtbAnmeldungToProtocolMapper mapper; + + @BeforeEach + void setup( + @Mock IOnkostarApi onkostarApi + ) { + this.onkostarApi = onkostarApi; + this.mapper = new MrMtbAnmeldungToProtocolMapper(onkostarApi); + } + + @Test + void testShouldMapCompletedForm() { + var anmeldung = new Procedure(onkostarApi); + anmeldung.setId(1); + anmeldung.setFormName("MR.MTB_Anmeldung"); + anmeldung.setValue("Fragestellung", new Item("Fragestellung", "Frage?")); + anmeldung.setValue("Empfehlung", new Item("Empfehlung", 2)); + + var empfehlung = new Procedure(onkostarApi); + empfehlung.setId(2); + empfehlung.setFormName("MR.MTB_Empfehlung"); + + var einzelempfehlung1 = new Procedure(onkostarApi); + einzelempfehlung1.setId(10); + einzelempfehlung1.setFormName("MR.MTB_Einzelempfehlung"); + einzelempfehlung1.setValue("Prioritaet", new Item("Empfehlungsprio", 1)); + einzelempfehlung1.setValue("Empfehlung", new Item("Empfehlung", "Empfehlung1")); + + var einzelempfehlung2 = new Procedure(onkostarApi); + einzelempfehlung2.setId(20); + einzelempfehlung2.setFormName("MR.MTB_Einzelempfehlung"); + einzelempfehlung2.setValue("Prioritaet", new Item("Empfehlungsprio", 2)); + einzelempfehlung2.setValue("Empfehlung", new Item("Empfehlung", "Empfehlung2")); + + doAnswer(invocationOnMock -> { + var procedureId = invocationOnMock.getArgument(0, Integer.class); + if (2 == procedureId) { + return empfehlung; + } else if (10 == procedureId) { + return einzelempfehlung1; + } else if (20 == procedureId) { + return einzelempfehlung2; + } + return null; + }).when(onkostarApi).getProcedure(anyInt()); + + doAnswer(invocationOnMock -> { + var procedureId = invocationOnMock.getArgument(0, Integer.class); + if (2 == procedureId) { + return Set.of(einzelempfehlung1, einzelempfehlung2); + } + return null; + }).when(onkostarApi).getSubprocedures(anyInt()); + + var actual = this.mapper.apply(anmeldung); + + assertThat(actual).isPresent(); + assertThat(actual.get()).isEqualTo( + "Fragestellung:\nFrage?\n\n" + + "Empfehlung:\nEmpfehlung1\n\n" + + "Empfehlung:\nEmpfehlung2" + ); + } + +} diff --git a/src/test/java/DNPM/services/mtb/MtbServiceTest.java b/src/test/java/DNPM/services/mtb/MtbServiceTest.java deleted file mode 100644 index eca9b1a..0000000 --- a/src/test/java/DNPM/services/mtb/MtbServiceTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package DNPM.services.mtb; - -import de.itc.onkostar.api.IOnkostarApi; -import de.itc.onkostar.api.Procedure; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.Map; -import java.util.Set; - -import static org.assertj.core.api.Assertions.assertThat; - -@ExtendWith(MockitoExtension.class) -public class MtbServiceTest { - - private IOnkostarApi onkostarApi; - - @BeforeEach - void setup( - @Mock IOnkostarApi onkostarApi - ) { - this.onkostarApi = onkostarApi; - } - - private static Set>> expectedMappings() { - return Map.ofEntries( - Map.entry("OS.Tumorkonferenz", OsTumorkonferenzToProtocolMapper.class), - Map.entry("OS.Tumorkonferenz.VarianteUKW", OsTumorkonferenzVarianteUkwToProtocolMapper.class) - ).entrySet(); - } - - @ParameterizedTest - @MethodSource("expectedMappings") - void testShouldMapFormNameToMapper(Map.Entry> expectedMapping) { - var procedure = new Procedure(onkostarApi); - procedure.setFormName(expectedMapping.getKey()); - - var actual = MtbService.procedureToProtocolMapper(procedure); - - assertThat(actual).isExactlyInstanceOf(expectedMapping.getValue()); - } - -} diff --git a/src/test/java/DNPM/services/mtb/OsTumorkonferenzToProtocolMapperTest.java b/src/test/java/DNPM/services/mtb/OsTumorkonferenzToProtocolMapperTest.java new file mode 100644 index 0000000..639edac --- /dev/null +++ b/src/test/java/DNPM/services/mtb/OsTumorkonferenzToProtocolMapperTest.java @@ -0,0 +1,46 @@ +package DNPM.services.mtb; + +import de.itc.onkostar.api.IOnkostarApi; +import de.itc.onkostar.api.Item; +import de.itc.onkostar.api.Procedure; +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 static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(MockitoExtension.class) +public class OsTumorkonferenzToProtocolMapperTest { + + private IOnkostarApi onkostarApi; + + private OsTumorkonferenzToProtocolMapper mapper; + + @BeforeEach + void setup( + @Mock IOnkostarApi onkostarApi + ) { + this.onkostarApi = onkostarApi; + this.mapper = new OsTumorkonferenzToProtocolMapper(); + } + + @Test + void testShouldReturnMtbProtocolForDefaultImplementation() { + var procedure = new Procedure(onkostarApi); + procedure.setFormName("OS.Tumorkonferenz"); + procedure.setStartDate(Date.from(Instant.parse("2023-01-01T00:00:00Z"))); + procedure.setValue("Fragestellung", new Item("Fragestellung", "Test ok?")); + procedure.setValue("Empfehlung", new Item("Empfehlung", "Rerun Test if not ok!")); + + var actual = mapper.apply(procedure); + + assertThat(actual).isPresent(); + assertThat(actual.get()).isEqualTo("Fragestellung:\nTest ok?\n\nEmpfehlung:\nRerun Test if not ok!"); + } + +} diff --git a/src/test/java/DNPM/services/mtb/OsTumorkonferenzVarianteUkwToProtocolMapperTest.java b/src/test/java/DNPM/services/mtb/OsTumorkonferenzVarianteUkwToProtocolMapperTest.java new file mode 100644 index 0000000..03f151c --- /dev/null +++ b/src/test/java/DNPM/services/mtb/OsTumorkonferenzVarianteUkwToProtocolMapperTest.java @@ -0,0 +1,46 @@ +package DNPM.services.mtb; + +import de.itc.onkostar.api.IOnkostarApi; +import de.itc.onkostar.api.Item; +import de.itc.onkostar.api.Procedure; +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 static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(MockitoExtension.class) +public class OsTumorkonferenzVarianteUkwToProtocolMapperTest { + + private IOnkostarApi onkostarApi; + + private OsTumorkonferenzVarianteUkwToProtocolMapper mapper; + + @BeforeEach + void setup( + @Mock IOnkostarApi onkostarApi + ) { + this.onkostarApi = onkostarApi; + this.mapper = new OsTumorkonferenzVarianteUkwToProtocolMapper(); + } + + @Test + void testShouldReturnMtbProtocolForDefaultImplementation() { + var procedure = new Procedure(onkostarApi); + procedure.setFormName("OS.Tumorkonferenz.VarianteUKW"); + procedure.setStartDate(Date.from(Instant.parse("2023-01-01T00:00:00Z"))); + procedure.setValue("Fragestellung", new Item("Fragestellung", "Test ok?")); + procedure.setValue("Empfehlung", new Item("Empfehlung", "Rerun Test if not ok!")); + + var actual = mapper.apply(procedure); + + assertThat(actual).isPresent(); + assertThat(actual.get()).isEqualTo("Fragestellung:\nTest ok?\n\nEmpfehlung:\nRerun Test if not ok!"); + } + +}