diff options
| author | Paul-Christian Volkmer | 2023-03-14 11:09:06 +0100 |
|---|---|---|
| committer | GitHub | 2023-03-14 11:09:06 +0100 |
| commit | dfd0bcead45259e8fe317d54e7eeaa8d1f3b79fe (patch) | |
| tree | 9ec3dcc3f69b3510bc4f76996a36ef2e1079a53a | |
| parent | e89b31532b67cf2026f1b2b975176c950bfeaaa7 (diff) | |
| parent | c3e96d18fcd477519f09465ed27f55b1d8c64517 (diff) | |
Merge pull request #8 from CCC-MF/issue_7
Übernahme MTB mit Datum in Einzelempfehlung und Rebiopsie
| -rw-r--r-- | README.md | 18 | ||||
| -rw-r--r-- | pom.xml | 166 | ||||
| -rw-r--r-- | src/main/java/DNPM/exceptions/FormException.java | 9 | ||||
| -rw-r--r-- | src/main/java/DNPM/forms/TherapieplanAnalyzer.java | 180 | ||||
| -rw-r--r-- | src/main/java/DNPM/services/DefaultFormService.java | 34 | ||||
| -rw-r--r-- | src/main/java/DNPM/services/FormService.java | 29 | ||||
| -rw-r--r-- | src/main/resources/de/itc/onkostar/library/moduleContext.xml | 1 | ||||
| -rw-r--r-- | src/test/java/DNPM/forms/TherapieplanAnalyzerTest.java | 70 |
8 files changed, 450 insertions, 57 deletions
@@ -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.' +); +``` + @@ -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()); + } + +} |
