summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md18
-rw-r--r--pom.xml166
-rw-r--r--src/main/java/DNPM/exceptions/FormException.java9
-rw-r--r--src/main/java/DNPM/forms/TherapieplanAnalyzer.java180
-rw-r--r--src/main/java/DNPM/services/DefaultFormService.java34
-rw-r--r--src/main/java/DNPM/services/FormService.java29
-rw-r--r--src/main/resources/de/itc/onkostar/library/moduleContext.xml1
-rw-r--r--src/test/java/DNPM/forms/TherapieplanAnalyzerTest.java70
8 files changed, 450 insertions, 57 deletions
diff --git a/README.md b/README.md
index eae0bcb..7a0c854 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,19 @@
-= Onkostar-Plugin zur Verwendung mit der DNPM-Formularsammlung
+# Onkostar-Plugin zur Verwendung mit der DNPM-Formularsammlung
+
+## Therapieplan
+
+Soll das automatische Befüllen der Unterformulare *Einzelempfehlung* und *Rebiopsie* nicht durchgeführt werden, weil es mehrere MTBs je MTB-Episode gibt, so muss die Einstellung `mehrere_mtb_in_mtbepisode` vorhanden sein und auf den Wert `true` gesetzt sein.
+
+```
+INSERT INTO einstellung (name, wert, kategorie, optionen, beschreibung)
+VALUES (
+ 'mehrere_mtb_in_mtbepisode',
+ 'true',
+ 'Dokumentation',
+ '[{"key": "true", "value": "Ja"},{"key": "false", "value": "Nein"}]',
+ 'Angabe, ob mehrere MTBs je MTB-Episode verwendet werden.'
+);
+```
+
diff --git a/pom.xml b/pom.xml
index 512f699..c5bec8e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,64 +1,64 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>DNPMHelper</groupId>
- <artifactId>DNPMHelper</artifactId>
- <version>0.0.2</version>
- <name>DNPMHelper</name>
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>DNPMHelper</groupId>
+ <artifactId>DNPMHelper</artifactId>
+ <version>0.0.2</version>
+ <name>DNPMHelper</name>
- <properties>
- <maven.compiler.source>11</maven.compiler.source>
- <maven.compiler.target>11</maven.compiler.target>
- <java.version>11</java.version>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <properties>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <java.version>11</java.version>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring-version>4.3.8.RELEASE</spring-version>
- </properties>
+ <spring-version>4.3.8.RELEASE</spring-version>
+ </properties>
- <dependencies>
- <!-- This is the onkostar-api -->
- <dependency>
- <groupId>de.itc</groupId>
- <artifactId>onkostar-parent</artifactId>
- <version>2.11.1.1</version>
- <scope>system</scope>
- <systemPath>${project.basedir}/libs/onkostar-api-2.11.1.1.jar</systemPath>
- </dependency>
+ <dependencies>
+ <!-- This is the onkostar-api -->
+ <dependency>
+ <groupId>de.itc</groupId>
+ <artifactId>onkostar-parent</artifactId>
+ <version>2.11.1.1</version>
+ <scope>system</scope>
+ <systemPath>${project.basedir}/libs/onkostar-api-2.11.1.1.jar</systemPath>
+ </dependency>
- <!-- Hibernate -->
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-core</artifactId>
- <version>4.3.11.Final</version>
- <scope>provided</scope>
- </dependency>
+ <!-- Hibernate -->
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-core</artifactId>
+ <version>4.3.11.Final</version>
+ <scope>provided</scope>
+ </dependency>
- <!-- zusätzliche Erweiterungen. -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>${spring-version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${spring-version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.12.2</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.2</version>
- <scope>provided</scope>
- </dependency>
+ <!-- zusätzliche Erweiterungen. -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ <version>${spring-version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${spring-version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>2.12.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.2</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
@@ -77,6 +77,60 @@
<version>2.6</version>
<scope>provided</scope>
</dependency>
- </dependencies>
+
+ <!-- Test dependencies -->
+ <!-- Wird nur für Unit-tests benoetigt -->
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>5.9.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>3.24.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>4.11.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <version>4.11.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ca.uhn.hapi</groupId>
+ <artifactId>hapi-base</artifactId>
+ <version>2.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ca.uhn.hapi</groupId>
+ <artifactId>hapi-structures-v26</artifactId>
+ <version>2.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.22.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>2.22.2</version>
+ </plugin>
+ </plugins>
+ </build>
</project> \ No newline at end of file
diff --git a/src/main/java/DNPM/exceptions/FormException.java b/src/main/java/DNPM/exceptions/FormException.java
new file mode 100644
index 0000000..4d0d6dd
--- /dev/null
+++ b/src/main/java/DNPM/exceptions/FormException.java
@@ -0,0 +1,9 @@
+package DNPM.exceptions;
+
+public class FormException extends RuntimeException {
+
+ public FormException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/DNPM/forms/TherapieplanAnalyzer.java b/src/main/java/DNPM/forms/TherapieplanAnalyzer.java
new file mode 100644
index 0000000..9fd53cc
--- /dev/null
+++ b/src/main/java/DNPM/forms/TherapieplanAnalyzer.java
@@ -0,0 +1,180 @@
+package DNPM.forms;
+
+import DNPM.services.FormService;
+import de.itc.onkostar.api.Disease;
+import de.itc.onkostar.api.IOnkostarApi;
+import de.itc.onkostar.api.Item;
+import de.itc.onkostar.api.Procedure;
+import de.itc.onkostar.api.analysis.AnalyseTriggerEvent;
+import de.itc.onkostar.api.analysis.AnalyzerRequirement;
+import de.itc.onkostar.api.analysis.IProcedureAnalyzer;
+import de.itc.onkostar.api.analysis.OnkostarPluginType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Diese Klasse implementiert ein Plugin, welches Aktionen nach Bearbeitung eines Therapieplans durchführt.
+ *
+ * @since 0.0.2
+ */
+@Component
+public class TherapieplanAnalyzer implements IProcedureAnalyzer {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final IOnkostarApi onkostarApi;
+
+ private final FormService formService;
+
+ public TherapieplanAnalyzer(final IOnkostarApi onkostarApi, final FormService formService) {
+ this.onkostarApi = onkostarApi;
+ this.formService = formService;
+ }
+
+ @Override
+ public OnkostarPluginType getType() {
+ return OnkostarPluginType.ANALYZER;
+ }
+
+ @Override
+ public String getVersion() {
+ return "0.1.0";
+ }
+
+ @Override
+ public String getName() {
+ return "DNPM Therapieplan Analyzer";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Aktualisiert Unterformulare nach Änderungen im Therapieplan-Formular";
+ }
+
+ /**
+ * @deprecated
+ */
+ @Override
+ public boolean isRelevantForDeletedProcedure() {
+ return false;
+ }
+
+ @Override
+ public boolean isRelevantForAnalyzer(Procedure procedure, Disease disease) {
+ return null != procedure && procedure.getFormName().equals("DNPM Therapieplan");
+ }
+
+ @Override
+ public boolean isSynchronous() {
+ return false;
+ }
+
+ @Override
+ public AnalyzerRequirement getRequirement() {
+ return AnalyzerRequirement.PROCEDURE;
+ }
+
+ @Override
+ public Set<AnalyseTriggerEvent> getTriggerEvents() {
+ return Set.of(
+ AnalyseTriggerEvent.EDIT_SAVE,
+ AnalyseTriggerEvent.EDIT_LOCK,
+ AnalyseTriggerEvent.REORG
+ );
+ }
+
+ @Override
+ public void analyze(Procedure procedure, Disease disease) {
+ updateMtbInSections(procedure);
+ updateMtbInSubforms(procedure);
+ }
+
+ /**
+ * Verlinke MTB und Übernahme Datum aus Hauptformular in weiteren Bereichen
+ * "Humangenetische Beratung" und "Reevaluation", wenn erforderlich.
+ *
+ * @param procedure Die Prozedur mit Hauptformular
+ */
+ private void updateMtbInSections(Procedure procedure) {
+ if (
+ null != onkostarApi.getGlobalSetting("mehrere_mtb_in_mtbepisode")
+ && onkostarApi.getGlobalSetting("mehrere_mtb_in_mtbepisode").equals("true")
+ ||
+ !procedure.getValue("humangenberatung").getString().equals("1")
+ && !procedure.getValue("reevaluation").getString().equals("1")
+ ) {
+ return;
+ }
+
+ var mtbReference = procedure.getValue("referstemtb").getInt();
+ var mtbDate = procedure.getValue("datum").getDate();
+
+ if (mtbReference != procedure.getValue("reftkhumangenber").getInt() && !mtbDate.equals(procedure.getValue("datumtkhumangenber").getDate())) {
+ procedure.setValue("reftkhumangenber", new Item("ref_tk_humangenber", mtbReference));
+ procedure.setValue("datumtkhumangenber", new Item("datum_tk_humangenber", mtbDate));
+ }
+
+ if (mtbReference != procedure.getValue("reftkreevaluation").getInt() && !mtbDate.equals(procedure.getValue("datumtkreevaluation").getDate())) {
+ procedure.setValue("reftkreevaluation", new Item("ref_tk_reevaluation", mtbReference));
+ procedure.setValue("datumtkreevaluation", new Item("datum_tk_reevaluation", mtbDate));
+ }
+
+ try {
+ onkostarApi.saveProcedure(procedure, false);
+ } catch (Exception e) {
+ logger.error("Formular 'DNPM Therapieplan' konnte nicht aktualisiert werden", e);
+ }
+ }
+
+ /**
+ * Verlinke MTB und Übernahme Datum aus Hauptformular in Unterformularen
+ *
+ * @param procedure Die Prozedur mit Hauptformular
+ */
+ private void updateMtbInSubforms(Procedure procedure) {
+ if (
+ null != onkostarApi.getGlobalSetting("mehrere_mtb_in_mtbepisode")
+ && onkostarApi.getGlobalSetting("mehrere_mtb_in_mtbepisode").equals("true")
+ ) {
+ return;
+ }
+
+ var mtbReference = procedure.getValue("referstemtb").getInt();
+ var mtbDate = procedure.getValue("datum").getDate();
+
+ formService.getSubFormProcedureIds(procedure.getId()).stream()
+ .map(onkostarApi::getProcedure)
+ .filter(Objects::nonNull)
+ .forEach(subform -> {
+ if (subform.getFormName().equals("DNPM UF Einzelempfehlung")) {
+ if (mtbReference != subform.getValue("mtb").getInt() && !mtbDate.equals(subform.getValue("ufeedatum").getDate())) {
+ subform.setValue("mtb", new Item("ref_tumorkonferenz", mtbReference));
+ subform.setValue("ufeedatum", new Item("datum", mtbDate));
+
+ try {
+ onkostarApi.saveProcedure(subform, false);
+ } catch (Exception e) {
+ logger.error("Formular 'DNPM UF Einzelempfehlung' konnte nicht aktualisiert werden", e);
+ }
+ }
+ }
+
+ if (subform.getFormName().equals("DNPM UF Rebiopsie")) {
+ if (mtbReference != subform.getValue("reftumorkonferenz").getInt() && !mtbDate.equals(subform.getValue("ufrbdatum").getDate())) {
+ subform.setValue("reftumorkonferenz", new Item("ref_tumorkonferenz", mtbReference));
+ subform.setValue("ufrbdatum", new Item("datum", mtbDate));
+
+ try {
+ onkostarApi.saveProcedure(subform, false);
+ } catch (Exception e) {
+ logger.error("Formular 'DNPM UF Rebiopsie' konnte nicht aktualisiert werden", e);
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/src/main/java/DNPM/services/DefaultFormService.java b/src/main/java/DNPM/services/DefaultFormService.java
new file mode 100644
index 0000000..c7fb042
--- /dev/null
+++ b/src/main/java/DNPM/services/DefaultFormService.java
@@ -0,0 +1,34 @@
+package DNPM.services;
+
+import DNPM.exceptions.FormException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.sql.DataSource;
+import java.util.List;
+
+@Service
+public class DefaultFormService implements FormService {
+
+ private final JdbcTemplate jdbcTemplate;
+
+ public DefaultFormService(final DataSource dataSource) {
+ this.jdbcTemplate = new JdbcTemplate(dataSource);
+ }
+
+ @Override
+ public int getMainFormProcedureId(int procedureId) throws FormException {
+ var sql = "SELECT hauptprozedur_id FROM prozedur WHERE id = ?";
+ try {
+ return jdbcTemplate.queryForObject(sql, (resultSet, i) -> resultSet.getInt("hauptprozedur_id"), procedureId);
+ } catch (Exception e) {
+ throw new FormException(String.format("No main form found for subform with ID '%d'", procedureId));
+ }
+ }
+
+ @Override
+ public List<Integer> getSubFormProcedureIds(int procedureId) {
+ var sql = "SELECT id FROM prozedur WHERE hauptprozedur_id = ?";
+ return jdbcTemplate.queryForList(sql, Integer.class, procedureId);
+ }
+}
diff --git a/src/main/java/DNPM/services/FormService.java b/src/main/java/DNPM/services/FormService.java
new file mode 100644
index 0000000..824d350
--- /dev/null
+++ b/src/main/java/DNPM/services/FormService.java
@@ -0,0 +1,29 @@
+package DNPM.services;
+
+import DNPM.exceptions.FormException;
+
+import java.util.List;
+
+public interface FormService {
+
+ /**
+ * Diese Methode übergibt die Prozedur-ID des zugehörigen Hauptformulars zu einem Unterformular
+ * Siehe auch: <a href="https://github.com/CCC-MF/onkostar-plugin-forminfo/blob/master/src/main/java/de/ukw/ccc/onkostar/forminfo/services/FormInfoService.java">FormInfoService.java</a>
+ *
+ * @param procedureId Die Prozedur-ID des Unterformulars
+ * @return Die Prozedur-ID des zugehörigen Hauptformulars
+ * @throws FormException
+ */
+ int getMainFormProcedureId(int procedureId) throws FormException;
+
+ /**
+ * Diese Methode übergibt die Prozedur-IDs von Unterformularen zu einem Formular
+ * Siehe auch: <a href="https://github.com/CCC-MF/onkostar-plugin-forminfo/blob/master/src/main/java/de/ukw/ccc/onkostar/forminfo/services/FormInfoService.java">FormInfoService.java</a>
+ *
+ * @param procedureId Die Prozedur-ID des Formulars
+ * @return Eine Liste mit Prozedur-IDs der Unterformulare
+ * @throws FormException
+ */
+ List<Integer> getSubFormProcedureIds(int procedureId);
+
+}
diff --git a/src/main/resources/de/itc/onkostar/library/moduleContext.xml b/src/main/resources/de/itc/onkostar/library/moduleContext.xml
index 51844e1..8bd2c82 100644
--- a/src/main/resources/de/itc/onkostar/library/moduleContext.xml
+++ b/src/main/resources/de/itc/onkostar/library/moduleContext.xml
@@ -16,6 +16,7 @@
<context:component-scan base-package="ATCCodes" />
<context:component-scan base-package="DNPM.forms" />
+ <context:component-scan base-package="DNPM.services" />
<mvc:resources mapping="/app/lib/umr/**" location="classpath:/app/lib/umr/" />
</beans> \ No newline at end of file
diff --git a/src/test/java/DNPM/forms/TherapieplanAnalyzerTest.java b/src/test/java/DNPM/forms/TherapieplanAnalyzerTest.java
new file mode 100644
index 0000000..38bc76c
--- /dev/null
+++ b/src/test/java/DNPM/forms/TherapieplanAnalyzerTest.java
@@ -0,0 +1,70 @@
+package DNPM.forms;
+
+import DNPM.services.FormService;
+import de.itc.onkostar.api.IOnkostarApi;
+import de.itc.onkostar.api.Item;
+import de.itc.onkostar.api.Procedure;
+import de.itc.onkostar.api.constants.JaNeinUnbekannt;
+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.Date;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+public class TherapieplanAnalyzerTest {
+
+ @Mock
+ private IOnkostarApi onkostarApi;
+
+ @Mock
+ private FormService formService;
+
+ private TherapieplanAnalyzer therapieplanAnalyzer;
+
+ @BeforeEach
+ void setUp() {
+ this.therapieplanAnalyzer = new TherapieplanAnalyzer(onkostarApi, formService);
+ }
+
+ @Test
+ void shouldNotUpdateSubformsOrSectionsIfMultipleMtbConfiguration() throws Exception {
+ doAnswer(invocationOnMock -> {
+ var settingName = invocationOnMock.getArgument(0, String.class);
+ if (settingName.equals("mehrere_mtb_in_mtbepisode")) {
+ return "true";
+ }
+ return null;
+ }).when(onkostarApi).getGlobalSetting(anyString());
+
+ this.therapieplanAnalyzer.analyze(new Procedure(onkostarApi), null);
+
+ verify(onkostarApi, never()).saveProcedure(any(Procedure.class), anyBoolean());
+ }
+
+ @Test
+ void shouldNotUpdateSectionsIfSectionsNotEnabled() throws Exception {
+ when(onkostarApi.getGlobalSetting(anyString())).thenReturn(null);
+
+ var testProcedure = new Procedure(onkostarApi);
+ testProcedure.setId(1000);
+
+ // Setzen MTB Referenz und Datum MTB
+ testProcedure.setValue("referstemtb", new Item("ref_tumorkonferenz", 1234));
+ testProcedure.setValue("datum", new Item("datum", new Date()));
+
+ // Keine humangenetische Beratung und keine Reevaluation empfohlen
+ testProcedure.setValue("humangenberatung", new Item("humangen_beratung", JaNeinUnbekannt.NEIN));
+ testProcedure.setValue("reevaluation", new Item("reevaluation", JaNeinUnbekannt.NEIN));
+
+ this.therapieplanAnalyzer.analyze(testProcedure, null);
+
+ verify(onkostarApi, never()).saveProcedure(any(Procedure.class), anyBoolean());
+ }
+
+}