From a97d76e5bbe42cde2a5729efedcdcdcd7c26bbe9 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Mon, 3 Apr 2023 14:34:32 +0200 Subject: [PATCH] =?UTF-8?q?Issue=20#20:=20Detailimplementierungen=20f?= =?UTF-8?q?=C3=BCr=20Consent=20Management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/DNPM/ConsentManager.java | 98 ++------------ .../java/DNPM/config/PluginConfiguration.java | 6 + .../consent/ConsentManagerService.java | 18 +++ .../consent/ConsentManagerServiceFactory.java | 25 ++++ .../consent/MrConsentManagerService.java | 121 ++++++++++++++++++ .../de/itc/onkostar/library/moduleContext.xml | 1 + src/test/java/DNPM/ConsentManagerTest.java | 42 ++---- .../ConsentManagerServiceFactoryTest.java | 51 ++++++++ .../DNPM/config/PluginConfigurationTest.java | 7 + .../consent/MrConsentManagerServiceTest.java | 61 +++++++++ 10 files changed, 313 insertions(+), 117 deletions(-) create mode 100644 src/main/java/DNPM/services/consent/ConsentManagerService.java create mode 100644 src/main/java/DNPM/services/consent/ConsentManagerServiceFactory.java create mode 100644 src/main/java/DNPM/services/consent/MrConsentManagerService.java create mode 100644 src/test/java/DNPM/config/ConsentManagerServiceFactoryTest.java create mode 100644 src/test/java/DNPM/services/consent/MrConsentManagerServiceTest.java diff --git a/src/main/java/DNPM/ConsentManager.java b/src/main/java/DNPM/ConsentManager.java index 4d630b7..3eca56b 100644 --- a/src/main/java/DNPM/ConsentManager.java +++ b/src/main/java/DNPM/ConsentManager.java @@ -1,31 +1,29 @@ package DNPM; +import DNPM.services.consent.ConsentManagerServiceFactory; 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.AnalyzerRequirement; import de.itc.onkostar.api.analysis.IProcedureAnalyzer; import de.itc.onkostar.api.analysis.OnkostarPluginType; -import org.hibernate.SQLQuery; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.transform.Transformers; -import org.hibernate.type.StandardBasicTypes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; -import java.util.Map; - public class ConsentManager implements IProcedureAnalyzer { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final IOnkostarApi onkostarApi; - public ConsentManager(final IOnkostarApi onkostarApi) { + private final ConsentManagerServiceFactory consentManagerServiceFactory; + + public ConsentManager( + final IOnkostarApi onkostarApi, + final ConsentManagerServiceFactory consentManagerServiceFactory + ) { this.onkostarApi = onkostarApi; + this.consentManagerServiceFactory = consentManagerServiceFactory; } @Override @@ -71,85 +69,7 @@ public class ConsentManager implements IProcedureAnalyzer { @Override public void analyze(Procedure prozedur, Disease erkrankung) { - int value = 0; - try { - SessionFactory sessionFactory = onkostarApi.getSessionFactory(); - Session session = sessionFactory.getCurrentSession(); - // geänderte Werte checken - String sql1 = "select id, max(timestamp) AS datum from aenderungsprotokoll where entity_id = '" + prozedur.getId() + "'"; - SQLQuery query1 = session.createSQLQuery(sql1) - .addScalar("id", StandardBasicTypes.INTEGER) - .addScalar("datum", StandardBasicTypes.TIMESTAMP); - logger.info("Wert-Check: {}", query1.uniqueResult()); - - String sql = "SELECT prozedur.id AS procedure_id, prozedur.data_form_id, data_catalogue.name AS data_catalogue, data_catalogue_entry.name AS data_catalogue_entry, data_form.description AS formname, prozedur.beginndatum AS datum " + - "FROM prozedur " + - "LEFT JOIN data_form_data_catalogue ON data_form_data_catalogue.data_form_id = prozedur.data_form_id " + - "LEFT JOIN data_catalogue_entry ON data_catalogue_entry.data_catalogue_id = data_form_data_catalogue.data_catalogue_id " + - "LEFT JOIN data_catalogue ON data_catalogue.id = data_catalogue_entry.data_catalogue_id " + - "LEFT JOIN data_form ON data_form.id = prozedur.data_form_id " + - "WHERE patient_id = " + prozedur.getPatientId() + " " + - "AND geloescht = 0 " + - "AND data_catalogue_entry.type = 'formReference' " + - "GROUP BY prozedur.id, prozedur.data_form_id, data_catalogue.name, data_catalogue_entry.name"; - - SQLQuery query = session.createSQLQuery(sql) - .addScalar("procedure_id", StandardBasicTypes.INTEGER) - .addScalar("data_form_id", StandardBasicTypes.INTEGER) - .addScalar("data_catalogue", StandardBasicTypes.STRING) - .addScalar("data_catalogue_entry", StandardBasicTypes.STRING) - .addScalar("formname", StandardBasicTypes.STRING) - .addScalar("datum", StandardBasicTypes.DATE); - - query.setResultTransformer(Transformers.aliasToBean(VerweisVon.class)); - - @SuppressWarnings("unchecked") - List result = query.list(); - - for (VerweisVon verweisVon : result) { - sql = verweisVon.getSQL(); - query = session.createSQLQuery(sql) - .addScalar("value", StandardBasicTypes.INTEGER); - if (query.uniqueResult() != null) { - value = (Integer) query.uniqueResult(); - } - if (value == prozedur.getId()) { - saveReferencedProcedure(prozedur, verweisVon); - value = 0; - } - } - } catch (RuntimeException e) { - logger.error("Sonstiger Fehler bei der Ausführung von analyze()", e); - } - } - - private void saveReferencedProcedure(Procedure prozedur, VerweisVon verweisVon) { - Procedure andereprozedur = onkostarApi.getProcedure(verweisVon.getProcedure_id()); - try { - Map felder = prozedur.getAllValues(); - for (Map.Entry feld : felder.entrySet()) { - if (feld.getKey().startsWith("Consent")) { - if (feld.getKey().equals("ConsentStatusEinwilligungDNPM")) { - switch (feld.getValue().getValue().toString()) { - case "z": - andereprozedur.setValue(feld.getKey(), new Item(feld.getKey(), "active")); - break; - case "a": - case "w": - andereprozedur.setValue(feld.getKey(), new Item(feld.getKey(), "rejected")); - break; - default: - break; - } - } else { - andereprozedur.setValue(feld.getKey(), prozedur.getValue(feld.getKey())); - } - } - } - onkostarApi.saveProcedure(andereprozedur); - } catch (Exception e) { - logger.error("Kann Prozedur nicht speichern", e); - } + consentManagerServiceFactory.currentUsableInstance().applyConsent(prozedur); } } diff --git a/src/main/java/DNPM/config/PluginConfiguration.java b/src/main/java/DNPM/config/PluginConfiguration.java index 09a5c50..30d8fb3 100644 --- a/src/main/java/DNPM/config/PluginConfiguration.java +++ b/src/main/java/DNPM/config/PluginConfiguration.java @@ -2,6 +2,7 @@ package DNPM.config; import DNPM.database.SettingsRepository; import DNPM.services.*; +import DNPM.services.consent.ConsentManagerServiceFactory; import DNPM.services.mtb.DefaultMtbService; import DNPM.services.mtb.MtbService; import DNPM.services.systemtherapie.DefaultSystemtherapieService; @@ -52,6 +53,11 @@ public class PluginConfiguration { return new DefaultSystemtherapieService(onkostarApi, settingsService); } + @Bean + public ConsentManagerServiceFactory consentManagerServiceFactory(final IOnkostarApi onkostarApi) { + return new ConsentManagerServiceFactory(onkostarApi); + } + @Bean public TherapieplanServiceFactory therapieplanServiceFactory( final IOnkostarApi onkostarApi, diff --git a/src/main/java/DNPM/services/consent/ConsentManagerService.java b/src/main/java/DNPM/services/consent/ConsentManagerService.java new file mode 100644 index 0000000..9e2d0fa --- /dev/null +++ b/src/main/java/DNPM/services/consent/ConsentManagerService.java @@ -0,0 +1,18 @@ +package DNPM.services.consent; + +import de.itc.onkostar.api.Procedure; + +/** + * Schnittstelle für die Anwendung von Consent-Änderungen + * + * @since 0.2.0 + */ +public interface ConsentManagerService { + + /** + * Wende Consent an, wenn dieses Consent-Formular gespeichert wird + * @param procedure Prozedur des Consent-Formulars + */ + void applyConsent(Procedure procedure); + +} diff --git a/src/main/java/DNPM/services/consent/ConsentManagerServiceFactory.java b/src/main/java/DNPM/services/consent/ConsentManagerServiceFactory.java new file mode 100644 index 0000000..eb6c8ce --- /dev/null +++ b/src/main/java/DNPM/services/consent/ConsentManagerServiceFactory.java @@ -0,0 +1,25 @@ +package DNPM.services.consent; + +import de.itc.onkostar.api.IOnkostarApi; + +public class ConsentManagerServiceFactory { + + private final IOnkostarApi onkostarApi; + + public ConsentManagerServiceFactory( + final IOnkostarApi onkostarApi + ) { + this.onkostarApi = onkostarApi; + } + + public ConsentManagerService currentUsableInstance() { + var consentFormName = onkostarApi.getGlobalSetting("consentform"); + + switch (consentFormName) { + case "MR.Consent": + default: + return new MrConsentManagerService(this.onkostarApi); + } + } + +} diff --git a/src/main/java/DNPM/services/consent/MrConsentManagerService.java b/src/main/java/DNPM/services/consent/MrConsentManagerService.java new file mode 100644 index 0000000..bf054b4 --- /dev/null +++ b/src/main/java/DNPM/services/consent/MrConsentManagerService.java @@ -0,0 +1,121 @@ +package DNPM.services.consent; + +import DNPM.VerweisVon; +import de.itc.onkostar.api.IOnkostarApi; +import de.itc.onkostar.api.Item; +import de.itc.onkostar.api.Procedure; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.transform.Transformers; +import org.hibernate.type.StandardBasicTypes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Map; + +/** + * Detailimplementierung für das Formular `MR.Consent` + * + * @since 0.2.0 + */ +public class MrConsentManagerService implements ConsentManagerService { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final IOnkostarApi onkostarApi; + + public MrConsentManagerService(final IOnkostarApi onkostarApi) { + this.onkostarApi = onkostarApi; + } + + /** + * Wende Consent an, wenn dieses Consent-Formular gespeichert wird + * + * @param procedure Prozedur des Consent-Formulars + */ + @Override + public void applyConsent(Procedure procedure) { + int value = 0; + try { + SessionFactory sessionFactory = onkostarApi.getSessionFactory(); + Session session = sessionFactory.getCurrentSession(); + // geänderte Werte checken + String sql1 = "select id, max(timestamp) AS datum from aenderungsprotokoll where entity_id = '" + procedure.getId() + "'"; + SQLQuery query1 = session.createSQLQuery(sql1) + .addScalar("id", StandardBasicTypes.INTEGER) + .addScalar("datum", StandardBasicTypes.TIMESTAMP); + logger.info("Wert-Check: {}", query1.uniqueResult()); + + String sql = "SELECT prozedur.id AS procedure_id, prozedur.data_form_id, data_catalogue.name AS data_catalogue, data_catalogue_entry.name AS data_catalogue_entry, data_form.description AS formname, prozedur.beginndatum AS datum " + + "FROM prozedur " + + "LEFT JOIN data_form_data_catalogue ON data_form_data_catalogue.data_form_id = prozedur.data_form_id " + + "LEFT JOIN data_catalogue_entry ON data_catalogue_entry.data_catalogue_id = data_form_data_catalogue.data_catalogue_id " + + "LEFT JOIN data_catalogue ON data_catalogue.id = data_catalogue_entry.data_catalogue_id " + + "LEFT JOIN data_form ON data_form.id = prozedur.data_form_id " + + "WHERE patient_id = " + procedure.getPatientId() + " " + + "AND geloescht = 0 " + + "AND data_catalogue_entry.type = 'formReference' " + + "GROUP BY prozedur.id, prozedur.data_form_id, data_catalogue.name, data_catalogue_entry.name"; + + SQLQuery query = session.createSQLQuery(sql) + .addScalar("procedure_id", StandardBasicTypes.INTEGER) + .addScalar("data_form_id", StandardBasicTypes.INTEGER) + .addScalar("data_catalogue", StandardBasicTypes.STRING) + .addScalar("data_catalogue_entry", StandardBasicTypes.STRING) + .addScalar("formname", StandardBasicTypes.STRING) + .addScalar("datum", StandardBasicTypes.DATE); + + query.setResultTransformer(Transformers.aliasToBean(VerweisVon.class)); + + @SuppressWarnings("unchecked") + List result = query.list(); + + for (VerweisVon verweisVon : result) { + sql = verweisVon.getSQL(); + query = session.createSQLQuery(sql) + .addScalar("value", StandardBasicTypes.INTEGER); + if (query.uniqueResult() != null) { + value = (Integer) query.uniqueResult(); + } + if (value == procedure.getId()) { + saveReferencedProcedure(procedure, verweisVon); + value = 0; + } + } + } catch (RuntimeException e) { + logger.error("Sonstiger Fehler bei der Ausführung von analyze()", e); + } + } + + private void saveReferencedProcedure(Procedure prozedur, VerweisVon verweisVon) { + Procedure andereprozedur = onkostarApi.getProcedure(verweisVon.getProcedure_id()); + try { + Map felder = prozedur.getAllValues(); + for (Map.Entry feld : felder.entrySet()) { + if (feld.getKey().startsWith("Consent")) { + if (feld.getKey().equals("ConsentStatusEinwilligungDNPM")) { + switch (feld.getValue().getValue().toString()) { + case "z": + andereprozedur.setValue(feld.getKey(), new Item(feld.getKey(), "active")); + break; + case "a": + case "w": + andereprozedur.setValue(feld.getKey(), new Item(feld.getKey(), "rejected")); + break; + default: + break; + } + } else { + andereprozedur.setValue(feld.getKey(), prozedur.getValue(feld.getKey())); + } + } + } + onkostarApi.saveProcedure(andereprozedur); + } catch (Exception e) { + logger.error("Kann Prozedur nicht speichern", e); + } + } + +} diff --git a/src/main/resources/de/itc/onkostar/library/moduleContext.xml b/src/main/resources/de/itc/onkostar/library/moduleContext.xml index 880025d..b943b5f 100644 --- a/src/main/resources/de/itc/onkostar/library/moduleContext.xml +++ b/src/main/resources/de/itc/onkostar/library/moduleContext.xml @@ -19,6 +19,7 @@ + diff --git a/src/test/java/DNPM/ConsentManagerTest.java b/src/test/java/DNPM/ConsentManagerTest.java index 6755ed6..41c9a02 100644 --- a/src/test/java/DNPM/ConsentManagerTest.java +++ b/src/test/java/DNPM/ConsentManagerTest.java @@ -1,20 +1,15 @@ package DNPM; +import DNPM.services.consent.ConsentManagerServiceFactory; +import DNPM.services.consent.MrConsentManagerService; import de.itc.onkostar.api.IOnkostarApi; import de.itc.onkostar.api.Procedure; -import org.hibernate.SQLQuery; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.type.Type; 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 static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @@ -22,39 +17,30 @@ class ConsentManagerTest { private IOnkostarApi onkostarApi; + private ConsentManagerServiceFactory consentManagerServiceFactory; + private ConsentManager consentManager; @BeforeEach void setup( - @Mock IOnkostarApi onkostarApi + @Mock IOnkostarApi onkostarApi, + @Mock ConsentManagerServiceFactory consentManagerServiceFactory ) { this.onkostarApi = onkostarApi; - this.consentManager = new ConsentManager(onkostarApi); + this.consentManagerServiceFactory = consentManagerServiceFactory; + this.consentManager = new ConsentManager(onkostarApi, consentManagerServiceFactory); } @Test - void testShouldCreateSqlQueriesWithRelatedEntityIds() { - var sessionFactory = mock(SessionFactory.class); - var session = mock(Session.class); - var query = mock(SQLQuery.class); + void shouldRunServiceMethodsOnAnalyzeCalled() { + var consentManagerServiceMock = mock(MrConsentManagerService.class); - when(onkostarApi.getSessionFactory()).thenReturn(sessionFactory); - when(sessionFactory.getCurrentSession()).thenReturn(session); - when(session.createSQLQuery(anyString())).thenReturn(query); - when(query.addScalar(anyString(), any(Type.class))).thenReturn(query); - when(query.uniqueResult()).thenReturn(""); + when(this.consentManagerServiceFactory.currentUsableInstance()) + .thenReturn(consentManagerServiceMock); - var dummyProzedur = new Procedure(this.onkostarApi); - dummyProzedur.setId(111); - dummyProzedur.setPatientId(123); + this.consentManager.analyze(new Procedure(onkostarApi), null); - consentManager.analyze(dummyProzedur, null); - - var argumentCaptor = ArgumentCaptor.forClass(String.class); - verify(session, times(2)).createSQLQuery(argumentCaptor.capture()); - assertThat(argumentCaptor.getAllValues()).hasSize(2); - assertThat(argumentCaptor.getAllValues().get(0)).contains("where entity_id = '111'"); - assertThat(argumentCaptor.getAllValues().get(1)).contains("WHERE patient_id = 123 AND geloescht = 0"); + verify(consentManagerServiceMock, times(1)).applyConsent(any(Procedure.class)); } } diff --git a/src/test/java/DNPM/config/ConsentManagerServiceFactoryTest.java b/src/test/java/DNPM/config/ConsentManagerServiceFactoryTest.java new file mode 100644 index 0000000..affbee1 --- /dev/null +++ b/src/test/java/DNPM/config/ConsentManagerServiceFactoryTest.java @@ -0,0 +1,51 @@ +package DNPM.config; + +import DNPM.services.consent.ConsentManagerServiceFactory; +import DNPM.services.consent.MrConsentManagerService; +import de.itc.onkostar.api.IOnkostarApi; +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; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ConsentManagerServiceFactoryTest { + + private IOnkostarApi onkostarApi; + + private ConsentManagerServiceFactory consentManagerServiceFactory; + + @BeforeEach + void setup( + @Mock IOnkostarApi onkostarApi + ) { + this.onkostarApi = onkostarApi; + this.consentManagerServiceFactory = new ConsentManagerServiceFactory(onkostarApi); + } + + private static Set>> expectedMappings() { + return Map.ofEntries( + Map.entry("MR.Consent", MrConsentManagerService.class) + ).entrySet(); + } + + @ParameterizedTest + @MethodSource("expectedMappings") + void testShouldMapFormNameToService(Map.Entry> expectedMapping) { + when(onkostarApi.getGlobalSetting(anyString())).thenReturn(expectedMapping.getKey()); + + var actual = consentManagerServiceFactory.currentUsableInstance(); + + assertThat(actual).isExactlyInstanceOf(expectedMapping.getValue()); + } + +} diff --git a/src/test/java/DNPM/config/PluginConfigurationTest.java b/src/test/java/DNPM/config/PluginConfigurationTest.java index 32ac53b..606817b 100644 --- a/src/test/java/DNPM/config/PluginConfigurationTest.java +++ b/src/test/java/DNPM/config/PluginConfigurationTest.java @@ -3,6 +3,7 @@ package DNPM.config; import DNPM.services.FormService; import DNPM.services.SettingsService; import DNPM.services.TherapieplanServiceFactory; +import DNPM.services.consent.ConsentManagerServiceFactory; import de.itc.onkostar.api.IOnkostarApi; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,6 +32,12 @@ class PluginConfigurationTest { this.configuration = new PluginConfiguration(); } + @Test + void testShouldReturnConsentManagerServiceFactory() { + var actual = this.configuration.consentManagerServiceFactory(onkostarApi); + assertThat(actual).isInstanceOf(ConsentManagerServiceFactory.class); + } + @Test void testShouldReturnTherapieplanServiceFactory() { var actual = this.configuration.therapieplanServiceFactory(onkostarApi, settingsService, formService); diff --git a/src/test/java/DNPM/services/consent/MrConsentManagerServiceTest.java b/src/test/java/DNPM/services/consent/MrConsentManagerServiceTest.java new file mode 100644 index 0000000..2c8448e --- /dev/null +++ b/src/test/java/DNPM/services/consent/MrConsentManagerServiceTest.java @@ -0,0 +1,61 @@ +package DNPM.services.consent; + +import de.itc.onkostar.api.IOnkostarApi; +import de.itc.onkostar.api.Procedure; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.type.Type; +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 static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class MrConsentManagerServiceTest { + + private IOnkostarApi onkostarApi; + + private MrConsentManagerService service; + + @BeforeEach + void setup( + @Mock IOnkostarApi onkostarApi + ) { + this.onkostarApi = onkostarApi; + this.service = new MrConsentManagerService(onkostarApi); + } + + @Test + void testShouldCreateSqlQueriesWithRelatedEntityIds() { + var sessionFactory = mock(SessionFactory.class); + var session = mock(Session.class); + var query = mock(SQLQuery.class); + + when(onkostarApi.getSessionFactory()).thenReturn(sessionFactory); + when(sessionFactory.getCurrentSession()).thenReturn(session); + when(session.createSQLQuery(anyString())).thenReturn(query); + when(query.addScalar(anyString(), any(Type.class))).thenReturn(query); + when(query.uniqueResult()).thenReturn(""); + + var dummyProzedur = new Procedure(this.onkostarApi); + dummyProzedur.setId(111); + dummyProzedur.setPatientId(123); + + this.service.applyConsent(dummyProzedur); + + var argumentCaptor = ArgumentCaptor.forClass(String.class); + verify(session, times(2)).createSQLQuery(argumentCaptor.capture()); + assertThat(argumentCaptor.getAllValues()).hasSize(2); + assertThat(argumentCaptor.getAllValues().get(0)).contains("where entity_id = '111'"); + assertThat(argumentCaptor.getAllValues().get(1)).contains("WHERE patient_id = 123 AND geloescht = 0"); + } + +}